HELP! переключение режимов (авто \ ручной) работы робота с ИК пульта.

Нет ответов
zhitomir82@gmail.com
Offline
Зарегистрирован: 17.02.2014

Помогите с кодом. Подскажите как правильно сделать такое: 

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