Не удается оборвать цикл

Руслан Садилов

✩✩✩✩✩✩✩
2 Апр 2020
3
0
Всем привет!

Я начинающий в деле кодирования Arduino, потому сильно не ругайте за дичь которую я понаписал.

Программа следующая:
При отсутствии сигнала с ИК датчика светодиоды горят красным.
При наличии сигнала светодиоды начинают переливаться в зеленый.
По условию, после того как "красный" падает до нуля, начинается мягкий перелив яркости зеленого по всем светодиодам.

В чем проблема:
Когда программа входит в цикл "Перелива яркости зеленого по всем светодиодам", не удается ее оборвать. Пытался всяко разно, кучу способов перепробовал. По итогу складывается ощущение, что он не считывает сигнал во время цикла.

По задаче нужно, чтобы в любой момент, когда сигнал от ИК пропадет, все снова загаралось красным.

Делается это все на Digispark Attiny85. Пробовал еще с attachInterrupt, поискал информацию, вроде на Digispark не пашет.

Буду благодарен совету!


C++:
#include <iarduino_NeoPixel.h> 
iarduino_NeoPixel led(0,4);
  uint8_t j;     ///сдвиг                               
  uint8_t k;                                 
  uint8_t r, g, blue;  ////RGB
  uint8_t z;  ///delay
  int IR_signal=1;   /////IR Pin
  bool IR;

//////////////////////ПЕРЕМЕННЫЕ ДЛЯ ПЕРЕЛИВА ЯРКОСТИ КАЖДОГО СВЕТОДИОДА//////////////////////
  uint8_t a_1;
  uint8_t a;
  uint8_t b_1;
  uint8_t b;
  uint8_t c_1;
  uint8_t c;
  uint8_t d_1;
  uint8_t d;
    
/////////////////////////////////////////////////////////////////////////
void setup() {                           
    led.begin();       
    pinMode(IR_signal, INPUT);
}
    
void loop() {

IR = !digitalRead(IR_signal);

 //////////////////////ПЕРЕЛИВ ВСЕХ СВЕТОДИОДОВ ОТ КРАСНОГО К ЗЕЛЕНОМУ//////////////////////
  if(IR == 1)
  {   
    j++;
    z=50;
    r=255-g; g=j*3; blue=0;
    led.setColor(NeoPixelAll, r,g,blue);
    led.write();
    delay(z);
    
    a_1=45;  ///значения яркости при переливе светодиодов
    a=45;
    b_1=90;
    b=90;
    c_1=135;
    c=135;
    d_1=180;
    d=180;
    
//////////////////////ПЕРЕЛИВ КАЖДОГО СВЕТОДИОДА ПО ЯРКОСТИ////////////////////////////////////   
    while(r == 0){
 
      z=1;
      if (a>0){
      led.setColor(0, r, a_1--, 0);
      led.write();
      delay(z);
      a--;
      }
    else {
      led.setColor(0, r, a_1++, 0);
      led.write();
      delay(z);
      }
      ////////
          if (b>0){
      led.setColor(1, r, b_1--, 0);
      led.write();
      delay(z);
      b--;
      }
    else {
      led.setColor(1, r, b_1++, 0);
      led.write();
      delay(z);}
      /////////
          if (c>0){
      led.setColor(2, r, c_1--, 0);
      led.write();
      delay(z);
      c--;
      }
    else {
      led.setColor(2, r, c_1++, 0);
      led.write();
      delay(z);}
      ///////////
          if (d>0){
      led.setColor(3, r, d_1--, 0);
      led.write();
      delay(z);
      d--;
      }
    else {
      led.setColor(3, r, d_1++, 0);
      led.write();
      delay(z);}
      

        
if(a_1>180){
      a=180;}
if(b_1>180){
      b=180;}
if(c_1>180){
      c=180;}
if(d_1>180){
      d=180;}   

if(IR == 0) break;
    }
  }


//////////////////////ВСЕ СВЕТОДИОДЫ КРАСНЫЕ ПРИ ОТСУТСТВИИ СИГНАЛА С ИК-ДАТЧИКА//////////////////////
  if (IR == 0){
    j = 0;
    r = 255;
    g = 0;
    blue = 0;
    led.setColor(NeoPixelAll, r,g,blue);
    led.write();
  }
}
 

Эдуард Анисимов

★★★★★✩✩
23 Сен 2019
1,023
300
54
Марий-Эл
По итогу складывается ощущение, что он не считывает сигнал во время цикла.
Да Вы правы. В цикле не считывается датчик.
А из цикла не вываливается так как переменная r всегда равна нулю. Нигде в цикле не изменяется. Поэтому цикл становится бесконечным. Вам нужно в цикле или изменять r, или считывать датчик. И по условию изменения сигнала с датчика вываливаться из цикла.
 

Руслан Садилов

✩✩✩✩✩✩✩
2 Апр 2020
3
0
@Эдуард Анисимов, подскажите пожалуйста.
Я вписал if (IR == 0) break; - эта строчка не подразумевает, что я считываю датчик в цикле? Или я что-то упускаю?

@Старик Похабыч, правильно ли я понимаю, что отдельный цикл мне надо прописать в void (название функции) до void setup?

Спасибо!
 

Старик Похабыч

★★★★★★✩
14 Авг 2019
2,010
508
Москва
@Руслан Садилов, Нет. Я уже говорил и говорю. Уже есть цикл loop
к примеру нужен цикл который будет увеличивать i на 1 до тех пор кока , к примеру , j=0 или i меньше 200
в обычном виде линейном программирование будет что то типа
C++:
while (j==0)
{
i++;
if (i==200) break;
}
Я тут специально поставил доп. условие для i , что бы было нагляднее. если i не более 200, то можно так и оставить. а если 200 000 ? то цикл loop уже будет изрядно подтормаживать и управление ухудшидся.

Можно сделать так
C++:
void loop
{
static int i=0;
if (j==0)
{
if (i<200) i++;
};
else
{
i=0;
};
}
выполнение 1-го loop будет соотв. 1 шагу while в 1-ом примере. и останется время на другие процессы.

Я вписал if (IR == 0) break; - эта строчка не подразумевает, что я считываю датчик в цикле? Или я что-то упускаю?
Упускаешь конечно. ты тут проверяешь не ДАТЧИК , а ПЕРЕМЕННУЮ, которая хранит ПОСЛЕДНЕЕ СЧИТАННОЕ С ДАТЧИКА ЗНАЧЕНИЕ, а считывание датчика происходит вот тут:
IR = !digitalRead(IR_signal);