roboforum.ru

Технический форум по робототехнике.


Подскажите с кодом

Как собрать и запрограммировать робота на Arduino(Freeduino, Roboduino, Seeduino ...). Используем Wiring и Processing.

Re: Подскажите с кодом

Сообщение SSnick » 11 июл 2014, 01:33

Спасибо, именно так все и происходит, согласен с вашими обьяснениями логики кода - все так и должно быть, кроме того момента, что бы возможно было "на ходу" ( когда выполянется какой либо цикл ) менять переменную val из сериал - вы можете подсказать как это можно реализовать?
SSnick
 
Сообщения: 8
Зарегистрирован: 10 июл 2014, 19:00

Re: Подскажите с кодом

Сообщение Angel71 » 11 июл 2014, 02:16

ответ на предыдущей странице. на ней же чуть ранее вариант, как изучать язык + берёте один или несколько нормальных самоучителей и начинаете с самых азов. тапы данных, чем отличается число от символа и так далее.
Аватара пользователя
Angel71
 
Сообщения: 10668
Зарегистрирован: 18 апр 2009, 22:18
Предупреждения: -1

Re: Подскажите с кодом

Сообщение SSnick » 11 июл 2014, 02:40

Я написал этот код сам, как Вы считаете, у меня проблема в символах или типе данных? я знаю азы
ответ в сказке про ежика? я понимаю всю логику работы - вы мне можете написать в коде как реализовать мою идею?
SSnick
 
Сообщения: 8
Зарегистрирован: 10 июл 2014, 19:00

Re: Подскажите с кодом

Сообщение Angel71 » 11 июл 2014, 10:07

мдя
Код: Выделить всёРазвернуть
int pin13 =13;
int pin12 =12;
int pin11 =11;
int pin10 =10;
byte massive1[] ={13,12,11,10};
byte massive2[] ={10,11,12,13};

void setup()
{
    pinMode(pin13, OUTPUT);
    pinMode(pin12, OUTPUT);
    pinMode(pin11, OUTPUT);
    pinMode(pin10, OUTPUT);
    Serial.begin(9600);
}

void loop()
{
    while(Serial.available()==0);
    switch(char val = Serial.read())
    {
      case '1':
        for(int i =0; i<4; i++)
        {
          Serial.println("Massive 1 is working ");
          Serial.println(massive1[i]);
          Serial.println(val);
          digitalWrite(massive1[i],HIGH);
          delay(5);
          digitalWrite(massive1[i],LOW);
         };
      case '2':
        for(int i =0; i<4; i++)
        {
              Serial.println("Massive 2 is working ");
              Serial.println(massive2[i]);
              Serial.println(val);
              digitalWrite(massive2[i],HIGH);
              delay(5);
              digitalWrite(massive2[i],LOW);
         }   
    }
    delay(400);
}

раз азы знаете и понимаете чуть больше, чем на уровне заучивания английской абры-кадабры, значит сможете сделать тоже самое хотя бы 2-3 вариантами. заменить на двумерный массив, сделать 1 case вместо 2х, заменить swicth на if и т.д.
Аватара пользователя
Angel71
 
Сообщения: 10668
Зарегистрирован: 18 апр 2009, 22:18
Предупреждения: -1

Re: Подскажите с кодом

Сообщение SSnick » 11 июл 2014, 11:24

спасибо
SSnick
 
Сообщения: 8
Зарегистрирован: 10 июл 2014, 19:00

Re: Подскажите с кодом

Сообщение RootAdmin » 11 июл 2014, 12:02

Ну вот код, первый который попался под руку из тех что работают с компьютером.

Код: Выделить всёРазвернуть
/*
Управление лазером и шаговиком для дальномера.
*/
#define StepFreq 310 //Частота шагов зеркала в герцах
#define motor_X_pin_1 8
#define motor_X_pin_2 9
#define motor_X_pin_3 10
#define motor_X_pin_4 11
#define laserpin 7
#define PosSensor 6
#define PosVCC 5 //Питание для светодиода сенсора
#define PosGND 4 //Земля для светодиода сенсора

int led = 13;
int ii=0;
int id=0;
int inByte[]={0,0,0,0,0,0,0,0};         // Для принятых байтов
volatile int CountByte = 0;         // Счетчик принятых
int countwrong=0; //Счетчик неверных длин команд

int MotorPins[] = {motor_X_pin_1, motor_X_pin_2, motor_X_pin_3, motor_X_pin_4};


volatile byte curstep=0; //Текущий "шаг" включения обмоток
volatile byte MOTstep=0; //Текущий шаг мотора
volatile byte USTstep=0; //Заданный шаг мотора
unsigned char timerLoadValue; //Количестов "начальных" тиков таймера

void setup() {               
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);

  pinMode(motor_X_pin_1, OUTPUT);
  pinMode(motor_X_pin_2, OUTPUT);
  pinMode(motor_X_pin_3, OUTPUT);
  pinMode(motor_X_pin_4, OUTPUT);
  pinMode(laserpin, OUTPUT);
  pinMode(PosSensor, INPUT);
  digitalWrite(PosSensor, HIGH); //Подтянем вход датчика вверх

  pinMode(PosGND, OUTPUT);
  digitalWrite(PosGND, LOW); //поставим ноль питанию датчика
  pinMode(PosVCC, OUTPUT);
  digitalWrite(PosVCC, HIGH); //поставим единицу (запитаем датчик)
 
    Serial.begin(9600);
   
  //Запускает таймер и получает загружаемое значение таймера.
timerLoadValue=SetupTimer2(StepFreq); //Параметр - частота, Шагов в секунду. Двигатель и больше может...
//Выводит загружаемое значение таймера
  Serial.print("Timer2 Load:");
  Serial.println(timerLoadValue,HEX);

}

// the loop routine runs over and over again forever:
void loop()
{
 
if  (digitalRead(PosSensor)) {digitalWrite(led, HIGH);}
else {digitalWrite(led, LOW);}
  for (int i=0; i<20; i++)
  {
  //  Serial.println (i);
  //  Serial.println (CountByte);
  //  delay(100);               // wait for a second
    if (i==1) //Секция отладки
    {
      id++;
      if (id>31000)
      {
        id=0;
      digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
      Serial.print ("A_");
      Serial.print (ii);
      Serial.println ("      ");
   //     Serial.print ("CB=");
   //     Serial.println (CountByte);
       /* Serial.print ("InByte=");
        Serial.write (inByte[0]);
        Serial.write (inByte[1]);
        Serial.write (inByte[2]);
        Serial.write (inByte[3]);
        //Если первый символ=S тогда следующие два - номер шага
        //Serial.println();
        */
        ii++;
      //delay(1);               // wait for a second
      digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
   //   delay(50);               // wait for a second
      }
    }


   
   if (CountByte>2)
   {
        CountByte=0;
        //Если первый символ=S тогда следующие два - номер шага
        //Serial.println();
       // Serial.println(inByte[0]);
        if (inByte[0]==83) //83 - код "S"
        {
              Serial.write ("Kom S");
              if (inByte[1]==48) //48 - код "0"
              {//stepMotor(0);
              USTstep--;
              Serial.println ("0 ok");}
              if (inByte[1]==49) //49 - код "1"
              {//stepMotor(1);
              USTstep++;
              Serial.println ("1 ok");}
             
        }
        if (inByte[0]==76) //76 - код "L"
        {
              Serial.println (i);
              Serial.write ("Kom L");
              if (inByte[1]==48) //48 - код "0"
              {digitalWrite(laserpin, LOW);
              Serial.println ("0 ok");}
              if (inByte[1]==49) //49 - код "1"
              {digitalWrite(laserpin, HIGH);
              Serial.println ("1 ok"); }
         }
        if (inByte[0]==77) //77 - код "M"
        {
              Serial.write ("Kom M");
              USTstep=inByte[1]; //Ставим нужный шаг
              Serial.print (USTstep);
              Serial.println (" ok");
         }
        if (inByte[0]==82) //82 - код "R" Начальное позиционирование - дописать
        {
              Serial.write ("Kom R");
              ZeroPos();
              Serial.println (" ok");
         }
    }
 
}
   //   Разберемся с "потерянными" командами
   if (CountByte) //Если в буфере есть что-то
    {
      countwrong++; //Увеличиваем счетчик
    }
    else
    {countwrong=0;}
    if (countwrong>500)//Если это что-то (типа 1 байт) больше 500 циклов
    {
      Serial.println ("CountWrong!");
      countwrong=0;
      CountByte=0;
    }
   
}



void serialEvent() {
//Serial.write ("Event0");
  if (Serial.available()) {
    digitalWrite(led, HIGH);
   //Serial.write ("Event1");
    // get the new byte:
    inByte[CountByte] = Serial.read();
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inByte[CountByte] == 10) {// '\n', новая строка
      CountByte=3;
         //Serial.write ("EndString!");
         //Serial.write ("EndL!");
    }
    else{    CountByte++;}
  }
}




void stepMotor( int Step) // Step 0 или +1
{
//Serial.println(curstep[Motor]);
int i; //Сдвиг для номеров пинов мотора
  if (Step)
   {
//      Serial.println("StepMotor Step=1");
     if (curstep==3)
     {curstep=0;}
    else
     {curstep++;}
   }
  else
  {
//    Serial.println("StepMotor Step=0");
    if (curstep==0)
     {curstep=3;}
    else
      {curstep--;}
   }
   
   switch (curstep) { //переделать, убрать массив с ногами моторов, аменить на дефиненные
      case 0:    // 1000
      digitalWrite(MotorPins[0], HIGH);
      digitalWrite(MotorPins[1], LOW);
      digitalWrite(MotorPins[2], LOW);
      digitalWrite(MotorPins[3], LOW);
      break;
     case 1:    // 0010
      digitalWrite(MotorPins[0], LOW);
      digitalWrite(MotorPins[1], LOW);
      digitalWrite(MotorPins[2], HIGH);
      digitalWrite(MotorPins[3], LOW);
      break;
     case 2:    // 0100
      digitalWrite(MotorPins[0], LOW);
      digitalWrite(MotorPins[1], HIGH);
      digitalWrite(MotorPins[2], LOW);
      digitalWrite(MotorPins[3], LOW);
      break;
     case 3:    // 0001
      digitalWrite(MotorPins[0], LOW);
      digitalWrite(MotorPins[1], LOW);
      digitalWrite(MotorPins[2], LOW);
      digitalWrite(MotorPins[3], HIGH);
      break;

  }
}



#define TIMER_CLOCK_FREQ 15625.0
//15625 for /1024
//2MHz for /8 prescale from 16MHz
//Установка Таймера2.
//Конфигурирует 8-битный Таймер2 ATMega168 для выработки прерывания
//с заданной частотой.
//Возвращает начальное значение таймера, которое должно быть загружено в TCNT2
//внутри вашей процедуры ISR.
//Смотри пример использования ниже.
unsigned char SetupTimer2(float timeoutFrequency)
{
  unsigned char result; //Начальное значение таймера.
  //Подсчет начального значения таймера
  result=(int)((257.0-(TIMER_CLOCK_FREQ/timeoutFrequency))+0.5);
  //257 на самом деле должно быть 256, но я получил лучшие результаты с 257.
   
  //Установки Таймер2: Делитель частоты /8, режим 0
  //Частота = 16MHz/1024 = 15625 герц или 64 мкс
  //Делитель /1024 дает нам хороший рабочий диапазон
  //так что сейчас мы просто жестко запрограммируем это.
  TCCR2A = 0;
  //TCCR2B = 0<<CS22 | 1<<CS21 | 0<<CS20; //это на 8
  TCCR2B = 7;
   
  //Подключение прерывания по переполнению Timer2
  TIMSK2 = 1<<TOIE2;
  //загружает таймер для первого цикла
  TCNT2=result;
  return(result); //значение (начальное) счетчика.
}


//Timer2 указатель вектора прерывания по переполнению
ISR(TIMER2_OVF_vect) {

  if (MOTstep>USTstep)
    {
      stepMotor(0);
      MOTstep--;
    }
  if (MOTstep<USTstep)
    {
      stepMotor(1);
      MOTstep++;
    }

TCNT2=timerLoadValue;
}


void ZeroPos() //калибровка шаговика
{
  USTstep=0; //Уставка - ноль

  Serial.print ("USTstep ");
  Serial.println (USTstep);
  Serial.print ("MOTstep ");
  Serial.println (MOTstep);

  Serial.print ("PosSensor ");
  Serial.println (digitalRead(PosSensor));
 
  while(!digitalRead(PosSensor)) //До срабатывания датчика - шагать
  {
    MOTstep=1;
   // Serial.println ("While");
  }
  Serial.println ("OK");
}


Там много лишнего, но работать будет и просто со светодиодом.
Отправляем команду L1 - светодиод загорается. L0 - тухнет.
Разберите, посмотрите как оно сделано.
И очень рекомендую все же комментировать свой код.

ЗЫ. И еще - предусматривайте обработку ошибок. Ибо что например будет если придет строка "3"? У меня - обработается и ничего не произойдет.
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Пред.

Вернуться в Arduino и другие Xduino

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 15