одновременное выполнение кода

Люди, подскажите на каком нибудь примере как запрограммировать робота чтоб он ехал и одновременно зондировал расстояние ик-дальномером закреплённым на серво-машинке? Т.е. — чтоб не останавливался перед препятствием а заранее принимал решение и не останавливаясь поворачивал. При этом ещё хочу чтоб крутил датчиком освещённости на другой серве и поворачивал солнечную батарею в наиболее освещённую сторону (на солнце). А то у меня никак не получается… Надо использовать «прерывание»? Или ещё как то?

Комментарии (15)

RSS свернуть / развернуть
+
+1
зачем прерывания?

простой конечный автомат + система сообщений + таймер.

а вопрос немного странный, ведь когда работают двигатели, процессор ничем не занят — ничто ему не мешает отдавать команды сервам, опрашивать дальномеры и т.д.
avatar

xtile

  • 28 апреля 2011, 11:29
+
0
так в том то и дело что я не знаю как это сделать(запрограммировать) в программе как написано по порядку — так по порядку и выполняется — движение затем опрос дальномера потом опрос солнечной батареи. я не профи по программированию :-(
avatar

Serega0209

  • 28 апреля 2011, 17:58
+
+1
вы, наверное, функцией delay злоупотребляете — не стоит, лучше привязать все события к счетчику времени, а текущее состояние двигателей, серв и прочей периферии хранить хотя бы в отдельных переменных.

т.е. вместо

void loop()
{
move_forward();
delay( 1000 );
move_right()
delay( 1000 );
move_backward()
delay( 1000 );
stop();
}

писать хотя бы так
#define STOP 0
#define FORWARD 1
#define LEFT 2
#define RIGHT 3
#define BACKWARD 4
int STATE = STOP;
void loop()
{
if ( 0 == STATE && millis() > 0 )
{
move_forward();
STATE = FORWARD;
}
if ( FORWARD == STATE && millis() > 1000 )
{
move_left();
STATE = LEFT;
}
if ( LEFT == STATE && millis() > 2000 )
{
move_backward();
STATE = BACKWARD;
}
if ( BACKWARD == STATE && millis() > 3000 )
{
stop();
STATE = STOP;
}
}
avatar

xtile

  • 28 апреля 2011, 18:11
+
+1
Ошибочно советуете использовать millis(). Значение будет всегда только увеличиваться, а значит в данном примере после того как выполнится последнее сравнение(millis() > 3000) оно всегда будет millis() > 3000.

Чтобы пользоваться таймером надо объявить переменные типа long, скажем
long proshloevremy;//Эти две переменные определяют время
long tekusheevremy;//Вернее разница между ними
int ZNACHENIEms=3000;//Это значение с которым сравнивают

tekusheevremy=millis();//присваиваем прошедшее время переменной текущего времени
if (BACKWARD == STATE && (tekusheevremy-proshloevremy)>ZNACHENIEms)
{
proshloevremy=tekusheevremy;//то что было текущим теперь в прошлом
//дальше выполняются необходимые команды
stop();
STATE = STOP;
}

Хотя я ни в таймере, ни в delay не вижу необходимости.
Какой именно дальномер не знаю, допустим самый примитивный определитель препятствия на светодиоде+фотодиоде (отражение попало на фотодиод -есть препятствие, значение HIGH) Реализовать можно примерно так:

int ZNDATCHIK;//здесь храним значение датчика

//содаем функции движения
void VPERED()
{
 //здесь указываем действие для езды вперед
}
void OSTANOVKA()
{
 //здесь указываем действие для остановки
}
void PRAVO()
{
 //действия поворота
}
void LEVO()
{
 //действия поворота
}
//содаем функции проверки датчиком вокруг
//допустим центральное положение сервы 90о право 0о левое 180о
void DatcikPered()
{
//повернуть серве на 90о
}
void DatcikPravo()
{
//повернуть серве на 0о
}
void DatcikLevo()
{
//повернуть серве на 180о
}

void setup(){
//стандартный сетап с объявлениями и тд
}

void loop()
{
  DatcikPered();//датчик по умолчанию смотрит всегда вперед
if (ZNDATCHIK==1) //если не равен 0 в переди преграда
{
  DatcikPravo();// Посмотрим направо
  if (ZNDATCHIK==0)//если нет преграды
  {  
   PRAVO();Повернем направо
   break;//Прервем проверки и вернемся в цикл петлю
  }  
  DatcikLevo();// Посмотрим направо
  if (ZNDATCHIK==0)//если нет преграды
  {  
   LEVO();//повернем налево
   break;//Прервем проверки и вернемся в цикл петлю
  }  
OSTANOVKA();  //ну если везде преграда то встанем и не поедем никуда
}
else {VPERED();}//если нет сигнала о препятствии - выполняем функцию вперед   
}




avatar

mogalkov

  • 28 апреля 2011, 20:22
+
0
спасибо
avatar

Serega0209

  • 29 апреля 2011, 05:23
+
0
добавляете еще одно деление по модулю — будет вам закольцованный цикл
avatar

xtile

  • 29 апреля 2011, 10:17
+
0
Зачем? Ардуино иде это не С, loop и так перля (в дословном переводе тоже). Да и в с для создания закольцованного цыкла проще всего в main добавить while или for.
avatar

mogalkov

  • 29 апреля 2011, 21:42
+
0
ну расскажите, как вы будете стандартными инструкциями для циклов организовывать 2 _частично_ пересекающихся цикла.

или, например, с некратным вложением ( т.е. одна инструкция выполняется в 1.6576 раз чаще другой )
avatar

xtile

  • 29 апреля 2011, 23:17
+
0
Что такое «деление по модулю»?
avatar

Serega0209

  • 30 апреля 2011, 04:57
+
0
avatar

xtile

  • 30 апреля 2011, 11:34
+
+1
Вопрос про деление по модулю поставлен не верно, надо спрашивать не что это, а зачем оно здесь. AVR это не просто процессор — это микроконтроллер. Конечно возможно тут просто сказывается мое образование, и учись я на программиста а не на радиомонтажника, я предпочитал бы все решать программно а не возможностями железа.

В даташите на мегу168 в разделе о прерываниях Interrupt Vectors in ATmega168 описаны 3 таймера.
avatar

mogalkov

  • 30 апреля 2011, 19:24
+
0
а если трех таймеров не хватит? )

avatar

xtile

  • 21 мая 2011, 16:55
+
0
Таймер можно повесить и на внешние прерывания, но смысл вопроса понятен.
Попробую правильно составить тех. задание. Если не хватает возможностей железа, то возможно не то железо выбрано.
Хотя не против посмотреть и на программную реализацию. Возможно это окажется действительно удобнее.
avatar

mogalkov

  • 23 мая 2011, 08:37
+
0
как написанно по поярдку-так и выполняется. все верно. Но такая штука как микроконтроллер намного умнее нашего мозга и может сосчитать квадратный корень из 234567 и почесать попу… и это за менее чем секунду. думаю понятно описал ситуацию.
Вы, простите в ардуину код заливали, тестировали. Чем вызван сей вопрос то?
avatar

Alek

  • 28 апреля 2011, 19:29
+
0
сей вопрос вызван незнанием и неумением программировать — но я учусь и пока вроде успешно
avatar

Serega0209

  • 29 апреля 2011, 05:18

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.