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();
}
}