HELP! переключение режимов (авто \ ручной) работы робота с ИК пульта.
- Войдите на сайт для отправки комментариев
Пнд, 17/02/2014 - 20:27
Помогите с кодом. Подскажите как правильно сделать такое:
1. Есть робот с 2-мя двигателями, ИК приемником, ИК пультом, Ультразвуковым дальномером.
2. Алгоритм работы. При включении питания робот ждет сигнал с пульта. Есть запрограммированные 4 кнопки ( ВПЕРЕД, НАЗАД, Разворот налево, Разворот направо) . Еще одна кнопка - Включение Авто режима.
Авто режим.- Робот управляется от Ультразвукового дальномера.
Проблема!!! При включении питания, я могу управлять движением робота с пульта. Когда я нажимаю кнопку Авто режима, робот работает в авторежиме, но остановить его С ПУЛЬТА я не могу.
Вот код, подскажите как правильно организовать ВЫХОД с АВТО режима.
#include <IRremote.h> // библиотека #define Trig 9 //пины дальномера #define Echo 8 int RECV_PIN = 11; //вход ИК приемника IRrecv irrecv(RECV_PIN); decode_results results; //eventTime, для паузы, вместо delay,будем использовать функцию millis. unsigned long eventTime=0; //индикация таймера int timer = 12; unsigned int impulseTime=0; //для ультразвукового дальномера unsigned int distance_sm=0; // motor A int dirForw_A = 2; int dirBack_A = 3; // motor B int dirForw_B = 4; int dirBack_B = 5; int L13 = 13; //пины управляющие моторами, светодиодами, или реле, чем угодно. void setup() { irrecv.enableIRIn(); // включить приемник pinMode(L13, OUTPUT); // назначаем пины как выходы pinMode(timer, OUTPUT); pinMode(dirForw_A, OUTPUT); pinMode(dirBack_A, OUTPUT); pinMode(dirForw_B, OUTPUT); pinMode(dirBack_B, OUTPUT); pinMode(Trig, OUTPUT); //инициируем как выход pinMode(Echo, INPUT); //инициируем как вход //Serial.begin(9600); } // функция Едем вперед void go() { digitalWrite(L13, HIGH); digitalWrite(dirForw_A, HIGH); // Задаем направление вращения 1 двиг digitalWrite(dirBack_A, LOW); digitalWrite(dirForw_B, HIGH); // Задаем направление вращения 2 двиг digitalWrite(dirBack_B, LOW); } // функция Едем назад void back() { digitalWrite(L13, HIGH); digitalWrite(dirForw_A, LOW); // Задаем направление вращения 1 двиг digitalWrite(dirBack_A, HIGH); digitalWrite(dirForw_B, LOW); // Задаем направление вращения 2 двиг digitalWrite(dirBack_B, HIGH); } // функция стоп void st() { digitalWrite(L13, LOW); digitalWrite(dirForw_A, LOW); // Задаем направление вращения 1 двиг digitalWrite(dirBack_A, LOW); digitalWrite(dirForw_B, LOW); // Задаем направление вращения 2 двиг digitalWrite(dirBack_B, LOW); } // функция поворот налево void left() { digitalWrite(L13, HIGH); digitalWrite(dirForw_A, HIGH); // Задаем направление вращения 1 двиг digitalWrite(dirBack_A, LOW); digitalWrite(dirForw_B, LOW); // Задаем направление вращения 2 двиг digitalWrite(dirBack_B, HIGH); } // функция поворот направо void right() { digitalWrite(L13, HIGH); digitalWrite(dirForw_A, LOW); // Задаем направление вращения 1 двиг digitalWrite(dirBack_A, HIGH); digitalWrite(dirForw_B, HIGH); // Задаем направление вращения 2 двиг digitalWrite(dirBack_B, LOW); } // функция управления с пульта void pult() { /* Эта конструкция нужна чтобы конвертировать пульсирующий (-) с (ИК) преемника сигнал в постоянный. После появление и пропадания сигнала, состояние сразу не меняется! а ждет 100 миллисекунд. Если 100 миллисекунд не прошло, и поступил еще один сигнал с пульта, тогда таймер заново запускается на 100 миллисекунд. Проще говоря, пока кнопка на пульте нажата таймерПИН остается вКлюченным, если кнопка на пульте отпущена таймерПИН вЫключен. */ // Читаем данные с (ИК) приемника. В момент приема данных у (ИК) приемника на выходе появляется пульсирующий (-)отрицательный сигнал if (digitalRead(RECV_PIN) == LOW) // Если обнаружен отрицательный сигнал запускаем таймер,и включаем таймерПИН //(timer, HIGH); eventTime=millis(),digitalWrite(timer, HIGH); // Продолжительность работы таймера >100 миллисекунд. И ТаймерПИН выключаем //(timer, LOW) if(millis()-eventTime>100) digitalWrite(timer, LOW) // и вЫключаем все ,digitalWrite(L13, LOW), digitalWrite(dirForw_A, LOW), digitalWrite(dirBack_A, LOW), digitalWrite(dirForw_B, LOW), digitalWrite(dirBack_B, LOW); if (irrecv.decode(&results)) { /*ВАЖНО !!! ( FF18E7 ) это код кнопки №2 - моего (ИК)! (инфракрасного пульта)!, - у вашего пульта будет другой код, замените на свой! Только при условии если, (Одновременно),Обнаружен поступивший код кнопки и выключен ТаймерПИН,"и" "&&" (digitalRead(timer) == HIGH) включаем нужный нам pin, digitalWrite(L13, HIGH); */ if (results.value == 0xFF18E7 && (digitalRead(timer) == HIGH) ) //едем вперед { go(); } else if (results.value == 0xFF4AB5 && (digitalRead(timer) == HIGH) )//едем назад { back(); } else if (results.value == 0xFF10EF && (digitalRead(timer) == HIGH) ) //поворот налево { left(); } else if (results.value == 0xFF5AA5 && (digitalRead(timer) == HIGH) ) //поворот направо { right(); } else irrecv.resume(); } } //стоп // if (irrecv.decode(&results) && results.value == 0xFFB04F) // код с пульта для остановки авто режима // { // int STOP; // STOP = st(); // } //функция Авто режим void ultras() { digitalWrite(Trig, HIGH); //Подаем импульс на вход trig дальномера delayMicroseconds(10); // равный 10 микросекундам digitalWrite(Trig, LOW); // Отключаем impulseTime=pulseIn(Echo, HIGH); // Замеряем длину импульса distance_sm=impulseTime/58; // Пересчитываем в сантиметры //return distance_sm;// Serial.println(distance_sm); // Выводим на порт // начинаем движение if (distance_sm>30) // Если расстояние более 30 сантиметром едем вперед { go(); } else // делаем поворот { st(); left(); } delay(50); //пауза между повторами } void loop() { //Serial.println(results.value, HEX); if (irrecv.decode(&results) && results.value == 0xFF52AD) { ultras(); } else { pult(); } }