Совместная работа ИК приёмника и засветка LED в цикле

Добрый день господа! Помогите пожалуйста с кодом. В том виде в котором код приведён ниже, без проблем читается информация с ИК пульта и caunter увеличивается или уменьшается, но стоит раскомментировать строку 60 и всё, приёмник перестаёт работать.
Я понимаю, что основное время программа “гуляет” в цикле RGBLoop() и поэтому сработки приёмника нет, но как победить эту задачу не знаю…

Буду благодарен если поможете.

// приёмник на D2

#define IR_1    0x50
#define IR_2    0x68
#include <NecDecoder.h>
NecDecoder ir;
byte counter;
//=============================
#include <Adafruit_NeoPixel.h>
#define PIN 5
#define NUM_LEDS 8
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(9600);
  attachInterrupt(0, irIsr, FALLING);

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void irIsr() {
  ir.tick();
}

//=====================
void RGBLoop(){
  for(int j = 0; j < 3; j++ ) {
    // Fade IN
    for(int k = 0; k < 256; k++) {
      switch(j) {
        case 0: setAll(k,0,0); break;
        case 1: setAll(0,k,0); break;
        case 2: setAll(0,0,k); break;
      }
      showStrip();
      delay(3);
    }
    // Fade OUT
    for(int k = 255; k >= 0; k--) {
      switch(j) {
        case 0: setAll(k,0,0); break;
        case 1: setAll(0,k,0); break;
        case 2: setAll(0,0,k); break;
      }
      showStrip();
      delay(3);
    }
  }
}
//=====================
void loop() {
//  RGBLoop();
    if (ir.available()) {
    switch (ir.readCommand()) {
      case IR_1: {
        Serial.println("Pressed UP"); 
        counter++;
        break;
      }
      case IR_2: {
        Serial.println("Pressed DOWN"); 
        counter--;
        break;
      }
    }
  }
}

void showStrip() {
   strip.show();
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));
}

void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}

Ну может if-у в 61 строке добавить else и там запускать RGBLoop() ?

Превратил основной цикл по вашему совету вот в это, особо это никак не помогло

void loop() {
    if (ir.available()) {
    switch (ir.readCommand()) {
      case IR_1: {
        Serial.println("Pressed UP"); 
        counter++;
        break;
      }
      case IR_2: {
        Serial.println("Pressed DOWN"); 
        counter--;
        break;
      }
    }
  }
  else RGBLoop();
}

Ну вообщем то да, это не сильно поможет, надо подумать…

а че у него делает это void RGBLoop(){ в сытапе >?

Переведи…

void setup() {

Хочется верить, что setup начинается в 21 и заканчивается в 27 строке, это не так?

Да он чета не в себе, внятно не может сказать.

ой извините мой косяк)))
не заметил что да там сетап заканчивается…

// приёмник на D2

#define IR_1    0x50
#define IR_2    0x68
#include <NecDecoder.h>
NecDecoder ir;
byte counter;
//=============================
#include <Adafruit_NeoPixel.h>
#define PIN 5
#define NUM_LEDS 8
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
Serial.begin(9600);
attachInterrupt(0, irIsr, FALLING);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}


//=====================
void loop() {
RGBLoop();
if (ir.available()) {
switch (ir.readCommand()) {
case IR_1: {
Serial.println("Pressed UP"); 
counter++;
break; }
case IR_2: {
Serial.println("Pressed DOWN"); 
counter--;
break; }
   }
 }
}

void showStrip() { strip.show(); }
void setPixel(int Pixel, byte red, byte green, byte blue) {
strip.setPixelColor(Pixel, strip.Color(red, green, blue)); }
void setAll(byte red, byte green, byte blue) {
for(int i = 0; i < NUM_LEDS; i++ ) {
setPixel(i, red, green, blue); }
showStrip(); }


void irIsr() { ir.tick(); }

//=====================
void RGBLoop(){
 for(int j = 0; j < 3; j++ ) {
   // Fade IN
   for(int k = 0; k < 256; k++) {
     switch(j) {
       case 0: setAll(k,0,0); break;
       case 1: setAll(0,k,0); break;
       case 2: setAll(0,0,k); break;
     }
     showStrip();
     delay(3);
   }
   // Fade OUT
   for(int k = 255; k >= 0; k--) {
     switch(j) {
       case 0: setAll(k,0,0); break;
       case 1: setAll(0,k,0); break;
       case 2: setAll(0,0,k); break;
     }
     showStrip();
     delay(3);
   }
 }
  }

попробуйте так

Не совсем понимаю что должно измениться? Вы просто перенесли процедуру RGBLoop() в конец кода или я невнимателен?
Попробовал, поведение никак не изменилось.

Вынеси с 61 по 74 строки код в отдельную функцию и вызывай её в циклах в функции RGBLoop().
Не уверен, что это решит проблему 100%, но попробовать стОит…

Вроде такого что-то:

// приёмник на D2

#define IR_1    0x50
#define IR_2    0x68
#include <NecDecoder.h>
NecDecoder ir;
byte counter;
//=============================
#include <Adafruit_NeoPixel.h>
#define PIN 5
#define NUM_LEDS 8
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(9600);
  attachInterrupt(0, irIsr, FALLING);

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void irIsr() {
  ir.tick();
}

void IR_AV() {
  if (ir.available()) {
    switch (ir.readCommand()) {
      case IR_1: {
          Serial.println("Pressed UP");
          counter++;
          break;
        }
      case IR_2: {
          Serial.println("Pressed DOWN");
          counter--;
          break;
        }
    }
  }
}

//=====================
void RGBLoop() {
  for (int j = 0; j < 3; j++ ) {
    // Fade IN
    for (int k = 0; k < 256; k++) {
      switch (j) {
        case 0: setAll(k, 0, 0); break;
        case 1: setAll(0, k, 0); break;
        case 2: setAll(0, 0, k); break;
      }
      showStrip();
      IR_AV();
      delay(3);
    }
    // Fade OUT
    for (int k = 255; k >= 0; k--) {
      switch (j) {
        case 0: setAll(k, 0, 0); break;
        case 1: setAll(0, k, 0); break;
        case 2: setAll(0, 0, k); break;
      }
      showStrip();
      IR_AV()
      delay(3);
    }
  }
}
//=====================
void loop() {
  RGBLoop();
}

void showStrip() {
  strip.show();
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
  strip.setPixelColor(Pixel, strip.Color(red, green, blue));
}

void setAll(byte red, byte green, byte blue) {
  for (int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
    IR_AV();
  }
  showStrip();
}

А вообще на прерывания бы IR “повесить”, но я не сталкивался с ним вообще и не знаю возможно ли это (не приходилось).

1 лайк

Я не до конца понимаю, что там couter делает, ну икремент/декримень дальше не вижу щоб он использовался,может ослеп.
Чет прям хочется код считывать в irIsr()
Знаю что какашка но прям в лоб решения не вижу.

1 лайк

так вроде правильно, все эти блоки должны идти после loop…
но а вообще я упился энергетиками))) и не слушайте меня
так же возможно уменьшение задержки или вовсе отдать таймер для задач пульта или выбора цвета поможет решить проблему…

Спасибо, мне кажется я нечто подобное пытался городить, но все равно не получалось… Попробую ваш код завтра вечером.
По прерываниям, строки 23, 29…31 как бы на него намекают, вот только ума как ими воспользоваться не хватает…
При нажатии кнопки на пульте я при любом раскладе мгновенно попадаю вот сюда

void irIsr() {
  ir.tick();
}

Как вариант

Спойлер
// приёмник на D2

#define IR_1    0x50
#define IR_2    0x68
#include <NecDecoder.h>
NecDecoder ir;
byte counter;
volatile bool DecON = false;

//=============================
#include <Adafruit_NeoPixel.h>
#define PIN 5
#define NUM_LEDS 8
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(9600);
  attachInterrupt(0, irIsr, FALLING);

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void irIsr() {
  ir.tick();
  DecON = true;
}

//=====================
void RGBLoop(){
  for(int j = 0; j < 3; j++ ) {
    // Fade IN
    for(int k = 0; k < 256; k++) {
      switch(j) {
        case 0: setAll(k,0,0); break;
        case 1: setAll(0,k,0); break;
        case 2: setAll(0,0,k); break;
      }
      showStrip();
      delay(3);
    }
    // Fade OUT
    for(int k = 255; k >= 0; k--) {
      switch(j) {
        case 0: setAll(k,0,0); break;
        case 1: setAll(0,k,0); break;
        case 2: setAll(0,0,k); break;
      }
      showStrip();
      delay(3);
    }
  }
}
//=====================
void loop() {
	
	if(DecON)   
   {   
    if (ir.available()) {
    switch (ir.readCommand()) {
      case IR_1: {
        Serial.println("Pressed UP"); 
        counter++;
        break;
      }
      case IR_2: {
        Serial.println("Pressed DOWN"); 
        counter--;
        break;
      }
    }
   }
    DecON = false;
   }
   else
   {	
      RGBLoop();
	  
   }
}

void showStrip() {
   strip.show();
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));
}

void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}

Эх, чешется же мне в одном месте… :slight_smile:
Быстренько включил комп перед выходом на работу, проверил. Ни код от уважаемого BOOMa ни код от уважаемого Дим-мыча не работают толком. Можно хоть обнажиматься на кнопку, происходит в начале одно-два совершенно случайных редких срабатывания но не более того, и то не всегда…

Инкремент/декримент планируется далее использовать для выбора эффекта на ленте, их должно быть несколько… Либо для изменения параметров мигания LED

В блокирующем коде это ожидаемо, просто немного “теплилась надежда”… ))

ЗЫ: Код то Ваш, просто немного измененный.