Помогите с циклом и IR датчиком

fayvlad
Offline
Зарегистрирован: 27.03.2014

В общем делаю дипломную работу и разбираю за одно Ардуино. Воплотил свои планы уже в реальность, но есть несколько проблем. Работаю с TSOP датчиком, подключил библиотеку, все работает, пока не испоьзую циклы... Раскажу о функционале, сам "робот" слеплен с ардуино копии мини, 2х переделаных серво привода (использую как редуктор-мотор), сенсора линии, микрафона, и на днях поставлю еще серво машинку, чтобы опускать карандаш или маркер в отрывке программы. Есть пульт, которым могу управлять этим роботом (вперед, назад, право, лево) и есть пока что 3 программы:

1 еду по линии, используя датчики линии

2 рисую что-то подобное на цветок (позже еще пару алгоритмов разберу, может красивое научусь рисовать)

3 слушаю микрофон (включаю песню на телефоне) и рандомно выбираю один из 4х действий - вперед, назад, разворот в право/лево - что-то подобное должно получится на мини колоночку sony которая под музыку танцевала.

Ближе о проблеме, ниже код, в нем я использую цикл while и нужно чтобы при нажатии на кнопку "стоп" - выходило из цикла по типу break. Но программа в цикле не принимает значения с датчика, может что-то не так пишу? Помогите пожалуйста, очень надо, перепробывал много способов - не получается, нужен новый взгляд.

#include <IRremote.h>
int RECV_PIN = 5;
int led = 13;
int in1 = 2;
int in2 = 3;
int in3 = 4;
int ml1 = 6;
int ml2 = 7;
int mr1 = 8;
int mr2 = 9;
int mark = 10;
int microphone = 11;
int i = 0;
int invalue1;
int invalue2;
int invalue3;
long randmic;
int mic;
int n; 
IRrecv irrecv(RECV_PIN);
decode_results results;
//========================
void setup() {                
  pinMode(in1, INPUT);
  pinMode(in2, INPUT);
  pinMode(in3, INPUT);
  pinMode(ml1, OUTPUT);
  pinMode(ml2, OUTPUT);
  pinMode(mr1, OUTPUT);
  pinMode(mr2, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(mark, OUTPUT); 
  pinMode(microphone, INPUT); 
  Serial.begin(9600);  
  irrecv.enableIRIn(); 
}
//=======================
void loop() {
  invalue1 = digitalRead(in1);
  invalue2 = digitalRead(in2);
  invalue3 = digitalRead(in3);
 if (irrecv.decode(&results)) 
 {
switch (results.value) 
{

//=========================
  
  case 0xFF02FD : //кнопка стоп
   digitalWrite(ml1, LOW);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, LOW);
   Serial.println("off");  
break;
  
//=========================
  
case 0xFF629D : // вперед
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW);
   Serial.println("go"); 
break;

//======================

case 0xFFA857: //назад
   digitalWrite(ml1, LOW);
   digitalWrite(ml2, HIGH);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, HIGH);
   Serial.println("rear_go");  
break;

//=====================

case 0xFF22DD: //в право
   digitalWrite(ml1, LOW);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW); 
   delay(500);
   digitalWrite(mr1, LOW);
   Serial.println("right");
break;

//====================

case 0xFFC23D: //влево
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, LOW);  
   delay(500);
   digitalWrite(ml1, LOW);
   Serial.println("left");
break;

//========================

case 0xFF30CF : // программа 1 - езда по линии
while(results.value!=0xFF02FD) //по идее должно выходить, если кнопка зажмется стоп
{
  if(invalue1==1 && invalue3==1)  //это проверка сенсоров, где они находятся 
  {
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW);
   Serial.println("left = 1; right = 1 ");
 }
   
   if(invalue3!=1)   //это проверка сенсоров, где они находятся 
   {
   digitalWrite(ml1, LOW);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW);
   Serial.println("right = 1");
   }
   
   if(invalue1!=1)   //это проверка сенсоров, где они находятся 
   {
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, LOW);
   Serial.println("left = 1");
   }
   
   if(results.value==0xFF02FD) // ну хотя бы здесь выйди.... нет, не хочет =(
   {
     Serial.println("off!!!!!!!!!!!!!!!!! ");
     break;
   }
}
break;

//=======================

case 0xFF18E7:  // рисуем типо цветочек
 while(i<6)
 {
   digitalWrite(mark, HIGH);
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW);
     delay(500);
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, HIGH);
     delay(400);
     i++;
   Serial.println(" ----paint---- ");     
     if(results.value==0xFF02FD) //ну и здесь пытаюсь выйти, если надоест...
   {
   Serial.println("off!!!!!!!!!!!!!!!!! ");
   break;
   }
 }
   digitalWrite(ml1, LOW);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, LOW);
   digitalWrite(mark, LOW);
   i=0;
   Serial.println("motors_off; i = 0;");
break;

//=============================

case 0xFF7A85:  //работа с микрофоном, тоже хотелось бы выйти в любой момент...
  for (n=0; n <= 500; n++)
   {
    mic = digitalRead(microphone);
     if(mic==1)
     {
       Serial.print("mic if =");
       Serial.println(mic);
       digitalWrite(ml1, LOW);
       digitalWrite(ml2, LOW);
       digitalWrite(mr1, LOW);
       digitalWrite(mr2, LOW);
       Serial.print("N =");
       Serial.println(n);
     }
       
    if(mic==0)   //проверка значений с микрафона
    {
      Serial.print("mic if = ");
      Serial.println(mic);
      Serial.print("N =");
      Serial.println(n);
      randmic = random(4); // придумываю как двигаться  
       if(randmic==0)   //двигаюсь...
       {
       digitalWrite(ml1, HIGH);
       digitalWrite(ml2, LOW);
       digitalWrite(mr1, LOW);
       digitalWrite(mr2, HIGH);
       Serial.print("random = ");
       Serial.println(randmic);
       delay(50);
       }
       else if(randmic==1)  //двигаюсь...
       {
       digitalWrite(ml1, LOW);
       digitalWrite(ml2, HIGH);
       digitalWrite(mr1, HIGH);
       digitalWrite(mr2, LOW);
       Serial.print("random = ");
       Serial.println(randmic);
       delay(50);
       }
       else if(randmic==2) //двигаюсь...
       {
       digitalWrite(ml1, HIGH);
       digitalWrite(ml2, LOW);
       digitalWrite(mr1, HIGH);
       digitalWrite(mr2, LOW);
       Serial.print("random = ");
       Serial.println(randmic);
       delay(50);
       }
       else if(randmic==3) //двигаюсь...
       {
       digitalWrite(ml1, HIGH);
       digitalWrite(ml2, LOW);
       digitalWrite(mr1, LOW);
       digitalWrite(mr2, HIGH);
       Serial.print("random = ");
       Serial.println(randmic);
       delay(50);
      }
    }
   delay(50);   
 }
 n=0;
    break;
    
//=================
    
}
 irrecv.resume(); 
  }
}

 

fayvlad
Offline
Зарегистрирован: 27.03.2014

Админы извиняйте, помоему не получилось свернуть код...

Клапауций
Offline
Зарегистрирован: 10.02.2013

fayvlad пишет:

Админы извиняйте, помоему не получилось свернуть код...

коде, вкладка "Дополнительно", "Свернуть".

#include <IRremote.h>
int RECV_PIN = 5;
int led = 13;
int in1 = 2;
int in2 = 3;
int in3 = 4;
int ml1 = 6;
int ml2 = 7;
int mr1 = 8;
int mr2 = 9;
int mark = 10;
int microphone = 11;
int i = 0;
int invalue1;
int invalue2;
int invalue3;
long randmic;
int mic;
int n; 
IRrecv irrecv(RECV_PIN);
decode_results results;
//========================
void setup() {                
  pinMode(in1, INPUT);
  pinMode(in2, INPUT);
  pinMode(in3, INPUT);
  pinMode(ml1, OUTPUT);
  pinMode(ml2, OUTPUT);
  pinMode(mr1, OUTPUT);
  pinMode(mr2, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(mark, OUTPUT); 
  pinMode(microphone, INPUT); 
  Serial.begin(9600);  
  irrecv.enableIRIn(); 
}
//=======================
void loop() {
  invalue1 = digitalRead(in1);
  invalue2 = digitalRead(in2);
  invalue3 = digitalRead(in3);
 if (irrecv.decode(&results)) 
 {
switch (results.value) 
{

//=========================
  
  case 0xFF02FD : //кнопка стоп
   digitalWrite(ml1, LOW);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, LOW);
   Serial.println("off");  
break;
  
//=========================
  
case 0xFF629D : // вперед
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW);
   Serial.println("go"); 
break;

//======================

case 0xFFA857: //назад
   digitalWrite(ml1, LOW);
   digitalWrite(ml2, HIGH);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, HIGH);
   Serial.println("rear_go");  
break;

//=====================

case 0xFF22DD: //в право
   digitalWrite(ml1, LOW);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW); 
   delay(500);
   digitalWrite(mr1, LOW);
   Serial.println("right");
break;

//====================

case 0xFFC23D: //влево
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, LOW);  
   delay(500);
   digitalWrite(ml1, LOW);
   Serial.println("left");
break;

//========================

case 0xFF30CF : // программа 1 - езда по линии
while(results.value!=0xFF02FD) //по идее должно выходить, если кнопка зажмется стоп
{
  if(invalue1==1 && invalue3==1)  //это проверка сенсоров, где они находятся 
  {
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW);
   Serial.println("left = 1; right = 1 ");
 }
   
   if(invalue3!=1)   //это проверка сенсоров, где они находятся 
   {
   digitalWrite(ml1, LOW);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW);
   Serial.println("right = 1");
   }
   
   if(invalue1!=1)   //это проверка сенсоров, где они находятся 
   {
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, LOW);
   Serial.println("left = 1");
   }
   
   if(results.value==0xFF02FD) // ну хотя бы здесь выйди.... нет, не хочет =(
   {
     Serial.println("off!!!!!!!!!!!!!!!!! ");
     break;
   }
}
break;

//=======================

case 0xFF18E7:  // рисуем типо цветочек
 while(i<6)
 {
   digitalWrite(mark, HIGH);
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW);
     delay(500);
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, HIGH);
     delay(400);
     i++;
   Serial.println(" ----paint---- ");     
     if(results.value==0xFF02FD) //ну и здесь пытаюсь выйти, если надоест...
   {
   Serial.println("off!!!!!!!!!!!!!!!!! ");
   break;
   }
 }
   digitalWrite(ml1, LOW);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, LOW);
   digitalWrite(mark, LOW);
   i=0;
   Serial.println("motors_off; i = 0;");
break;

//=============================

case 0xFF7A85:  //работа с микрофоном, тоже хотелось бы выйти в любой момент...
  for (n=0; n <= 500; n++)
   {
    mic = digitalRead(microphone);
     if(mic==1)
     {
       Serial.print("mic if =");
       Serial.println(mic);
       digitalWrite(ml1, LOW);
       digitalWrite(ml2, LOW);
       digitalWrite(mr1, LOW);
       digitalWrite(mr2, LOW);
       Serial.print("N =");
       Serial.println(n);
     }
       
    if(mic==0)   //проверка значений с микрафона
    {
      Serial.print("mic if = ");
      Serial.println(mic);
      Serial.print("N =");
      Serial.println(n);
      randmic = random(4); // придумываю как двигаться  
       if(randmic==0)   //двигаюсь...
       {
       digitalWrite(ml1, HIGH);
       digitalWrite(ml2, LOW);
       digitalWrite(mr1, LOW);
       digitalWrite(mr2, HIGH);
       Serial.print("random = ");
       Serial.println(randmic);
       delay(50);
       }
       else if(randmic==1)  //двигаюсь...
       {
       digitalWrite(ml1, LOW);
       digitalWrite(ml2, HIGH);
       digitalWrite(mr1, HIGH);
       digitalWrite(mr2, LOW);
       Serial.print("random = ");
       Serial.println(randmic);
       delay(50);
       }
       else if(randmic==2) //двигаюсь...
       {
       digitalWrite(ml1, HIGH);
       digitalWrite(ml2, LOW);
       digitalWrite(mr1, HIGH);
       digitalWrite(mr2, LOW);
       Serial.print("random = ");
       Serial.println(randmic);
       delay(50);
       }
       else if(randmic==3) //двигаюсь...
       {
       digitalWrite(ml1, HIGH);
       digitalWrite(ml2, LOW);
       digitalWrite(mr1, LOW);
       digitalWrite(mr2, HIGH);
       Serial.print("random = ");
       Serial.println(randmic);
       delay(50);
      }
    }
   delay(50);   
 }
 n=0;
    break;
    
//=================
    
}
 irrecv.resume(); 
  }
}

 

fayvlad
Offline
Зарегистрирован: 27.03.2014

ну что, кто-то что-то подскажет, как быть?

как я понял, нужно в цикле считать даные с датчика IR

 

Клапауций
Offline
Зарегистрирован: 10.02.2013

fayvlad пишет:

ну что, кто-то что-то подскажет, как быть?

не видать тебе диплома, иди двор мети, тормоз.

fayvlad
Offline
Зарегистрирован: 27.03.2014

Помогти можешь? Зачем умничаешь? Я самоучка в этом и у нас в колледже это достаточно хорош проект.

leshak
Offline
Зарегистрирован: 29.09.2011

Клапауций пишет:

не видать тебе диплома, иди двор мети, тормоз.

Прочитал... и сразу не глядя понял кто автор сообщения :)

По сути, топикстартеру:

Давайте рассмотрим такой пример:

int val=10;

while(val>5){
  Serial.print(millis());
  Serial.print(": val=");
  Serial.println(val);
  delay(500);
}

Как, по вашему, в каком случае может завершится этот цикл?

Клапауций
Offline
Зарегистрирован: 10.02.2013

leshak пишет:

Прочитал... и сразу не глядя понял кто автор сообщения :)

Прочитал... и сразу не глядя понял кто автор сообщения :)

*не продолжай поучающую рекурсию, как не нужно посылать в пень навичков.

fayvlad
Offline
Зарегистрирован: 27.03.2014

Я хочу выйти с этого цикла, там все остальное работает, а как работать с той библиотекой IRremte не знаю, точнее как даные получить в цикле



case 0xFF30CF : // программа 1 - езда по линии

while(results.value!=0xFF02FD) //по идее должно выходить, если кнопка зажмется стоп

{
invalue1 = digitalRead(in1);
  invalue2 = digitalRead(in2);
  invalue3 = digitalRead(in3);

  if(invalue1==1 && invalue3==1)  //это проверка сенсоров, где они находятся
  {
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW);
 }
   if(invalue3!=1)   //это проверка сенсоров, где они находятся
   {
   digitalWrite(ml1, LOW);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW);
   }

   if(invalue1!=1)   //это проверка сенсоров, где они находятся
   {
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, LOW);
   }

   if(results.value==0xFF02FD) // ну хотя бы здесь выйди.... нет, не хочет =(
   {
     break;
   }
}
break;

 

leshak
Offline
Зарегистрирован: 29.09.2011

>как работать с той библиотекой IRremte не знаю

Да причем тут библиотека? А вас пробой "по логике". Ниодна библиотека, никогда не знает "из цикла ее вызвают или нет".

Вы верно выделил проблемный код. А не выходить он потому что внури него нигде result.value не изменяется. Какое было значение у нее при входе в цикл. Такое и остается. Если только его святой дух не поменяет. Проверки results.value!=0xFF02FD и results.value==0xFF02FD всегда буду возвращать одно и тоже значение.

Можно, конечно сейчас до потери пульса бодатся с вашим циклом и все-таки заставить его работать (очевидно, это означает что ВНУТРИ него нужно делать очередной вызов библиотеки для получения нового кода кнопки, если он пришел), только... это очень кривой путь.

Зачем вам еще один цикл, если у вас уже фактически есть цикл loop() в котором уже регулярно опрашивается библиотека?

Вам нужно просто разделить логику "чтения кнопок" и "езда по линии". Заведите себе отдельную ГЛОБАЛЬНУЮ переменную. скажем mode (значение которой сохраняется между вызовам loop).

Если нажали кнопку  0xFF30CF - просто сделайте mode=1, если нажали кнопку stop - установили mode=0;

И где-нибудь в конце вашего Loop() пишите:

byte mode=0;
void loop(){

  // тут читаем кнопок
  ............... ваш код по работе с библитекой
  ...............


  if(mode==1){
     invalue1 = digitalRead(in1);
  invalue2 = digitalRead(in2);
  invalue3 = digitalRead(in3);

  if(invalue1==1 && invalue3==1)  //это проверка сенсоров, где они находятся
  {

   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW);
 }
   if(invalue3!=1)   //это проверка сенсоров, где они находятся
   {
   digitalWrite(ml1, LOW);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, HIGH);
   digitalWrite(mr2, LOW);

   }

   if(invalue1!=1)   //это проверка сенсоров, где они находятся

   {
   digitalWrite(ml1, HIGH);
   digitalWrite(ml2, LOW);
   digitalWrite(mr1, LOW);
   digitalWrite(mr2, LOW);
   }


 }

}

И все. Не морочте себе голову "выходами" и проч. Просто пререключайте-меняйте, по нажатию кнопки, значение переменной mode.

fayvlad
Offline
Зарегистрирован: 27.03.2014

А оно будет разви повторять условие? По идее оно рас пройдет этот цикл и все...

leshak
Offline
Зарегистрирован: 29.09.2011

>А оно будет разви повторять условие? По идее оно рас пройдет этот цикл и все...

Верно. Пройдет один раз.... а что дальше проиходить будет? Вот закончился loop(), что происходит дальше?

P.S. Какой цикл? Откуда опять цикл взялся?  Там же If обыкновенный.

leshak
Offline
Зарегистрирован: 29.09.2011

Вообщем вам, наверное, нужно не с библиотеки IRRemote начинать, а с базового примера. Самого первого Мигаем светодиодом

Посмотрите на него. Никаких while/for и т.п. там нет. А светодиод мигает годами.... как так выходит?

P.S. Подсказка: внизу примера есть ссылки "Смотрите также.." - они помогут разобратся почему пример работает именно так.

fayvlad
Offline
Зарегистрирован: 27.03.2014

Само собой, если кусок программы будет один - то будет оно вечно работать, а как у меня куча проверок....

leshak
Offline
Зарегистрирован: 29.09.2011

Какая куча проверок? Каких именно? Чем они будут мешать?

Нет, если конечно, вы где-то в тело Loop() воткнете delay(65535) или while(true){}, то само собой никакого эффекта многократного повторения - не будет. А если остальное тело loop() будет выполнятся за микросекунды, то в чем проблема состоит?