Люди, подскажите на каком нибудь примере как запрограммировать робота чтоб он ехал и одновременно зондировал расстояние ик-дальномером закреплённым на серво-машинке? Т.е. — чтоб не останавливался перед препятствием а заранее принимал решение и не останавливаясь поворачивал. При этом ещё хочу чтоб крутил датчиком освещённости на другой серве и поворачивал солнечную батарею в наиболее освещённую сторону (на солнце). А то у меня никак не получается… Надо использовать «прерывание»? Или ещё как то?
Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…
15 комментариев на «“одновременное выполнение кода”»
зачем прерывания?
простой конечный автомат + система сообщений + таймер.
а вопрос немного странный, ведь когда работают двигатели, процессор ничем не занят — ничто ему не мешает отдавать команды сервам, опрашивать дальномеры и т.д.
так в том то и дело что я не знаю как это сделать(запрограммировать) в программе как написано по порядку — так по порядку и выполняется — движение затем опрос дальномера потом опрос солнечной батареи. я не профи по программированию 🙁
вы, наверное, функцией 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;
}
}
Ошибочно советуете использовать 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) Реализовать можно примерно так:
спасибо
добавляете еще одно деление по модулю — будет вам закольцованный цикл
Зачем? Ардуино иде это не С, loop и так перля (в дословном переводе тоже). Да и в с для создания закольцованного цыкла проще всего в main добавить while или for.
ну расскажите, как вы будете стандартными инструкциями для циклов организовывать 2 _частично_ пересекающихся цикла.
или, например, с некратным вложением ( т.е. одна инструкция выполняется в 1.6576 раз чаще другой )
Что такое «деление по модулю»?
то же, что деление с остатком 🙂
Вопрос про деление по модулю поставлен не верно, надо спрашивать не что это, а зачем оно здесь. AVR это не просто процессор — это микроконтроллер. Конечно возможно тут просто сказывается мое образование, и учись я на программиста а не на радиомонтажника, я предпочитал бы все решать программно а не возможностями железа.
В даташите на мегу168 в разделе о прерываниях Interrupt Vectors in ATmega168 описаны 3 таймера.
а если трех таймеров не хватит? )
Таймер можно повесить и на внешние прерывания, но смысл вопроса понятен.
Попробую правильно составить тех. задание. Если не хватает возможностей железа, то возможно не то железо выбрано.
Хотя не против посмотреть и на программную реализацию. Возможно это окажется действительно удобнее.
как написанно по поярдку-так и выполняется. все верно. Но такая штука как микроконтроллер намного умнее нашего мозга и может сосчитать квадратный корень из 234567 и почесать попу… и это за менее чем секунду. думаю понятно описал ситуацию.
Вы, простите в ардуину код заливали, тестировали. Чем вызван сей вопрос то?
сей вопрос вызван незнанием и неумением программировать — но я учусь и пока вроде успешно