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

Спасибо за попытку помочь! Посёрфил немного просторы интернета и понял, я полагая что всё просто, замахнулся на достаточно сложный вопрос использования Neopixel и IR.
Кому интересно, можно почитать вот тут.

Или в переводе на русский, мысль неоднократно озвученная на форуме - процессор надо брать под задачу, а не натягивать имеющуюся сову на глобус.

1 лайк

Возможно и так, но нам новичкам то не вдомёк… :slight_smile:

И в догонку. Если взять маленький дешёвенький attiny25 и залить в него приёмник IR, а уже им управлять наной - типа нажимать кнопочки, всё будет работать.

1 лайк

Как вариант, спасибо за идею!

Если есть желание - ещё один костыль попробуйте
Немного изменил функцию RGBLoop():

Спойлер
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();
	  if(DecON)
	   return;
      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();
	   if(DecON)
	   return;
      delay(3);
    }
  }
}

P.S. Весь код из #17

======
P.P.S.
Ну и ещё, хоть шансов мало)))

Спойлер
// приёмник на 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++) {
	  if(DecON)
		Dec();
      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--) {
	  if(DecON)
		Dec();
      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 Dec()
{
  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;
   }
}
//=====================
void loop() {
	
	if(DecON)     
      Dec();
    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();
}
1 лайк
  1. Найти старые версии библиотек не конфликтовавшие друг с другом.
  2. К уно взять ещё уно или про мини - поделить библиотеки по модулям.
  3. Взять rp2040 (дешевле уно) и разделить скетч на два “сетап” “лууп”.
  4. Взять ЕСП32 - для неё исключение в библиотеке неопиксель и конфликта нет.
    Проверял все варианты - работает.
    …На этом форуме есть тема безбиблиотечной IR.
1 лайк

Вечером обязательно попробую, отпишусь.

По ссылке выше которую я давал, человек пишет что с ESP32 там тоже не всё гладко, да и мой проект яйца выеденного не стоит, чтобы на него ESPшку тратить :slight_smile: Проще уж на Тини плюс НАНО заморочиться, но всё равно, спасибо вам за информацию.

Ага, проще… Трудоемкость программирования раза в 3 выше, а так проще, само собой

Кстати, из любопытства залез на Алик - и Мини и ЕСП23 стоят по $0.99

Когда я писал о “ESPшку тратить”, я не имел ввиду деньги, просто как то стыдно что ли, для трёх эффектов LED ленты использовать такой чип :slight_smile:

Как уже написали выше - нужно техническое решение подбирать под задачу. Тем более, если у вас реализация вызывает затруднения. А то вы сами себе создали проблему и теперь ее все вытаются героически решить методом телемедицины

А еще есть ЕСП8266 - должна в ваши психологические ограничения встроиться

1 лайк

На мой взгляд, у вас две разные прблеммы
1 - совместная работа IR и Leds
2 - не оптимальный алгоритм скетча.

1 - Вывод 8 диодов занимает около 250 мкс, и в принципе не должен ломать работу IR. Но библиотека NecDecoder.h возможно не оптимальна по настройкам таймингов.
Если вы измените 150 на 350, то В ВАШЕМ случае, нажатия ВОЗМОЖНО станут определяться увереннее
#define _NEC_TOLERANCE 350 // было 150 // допуск high/low, мкс
2 - О чем вероятно писали до этого. В самом скетче факт нажатия проверяется раз ~ 5 секунд, что наверное не удобно. И это можно изменить изменив логику скетча.

Так и есть Дим, обновлённая процедура заставляет мигать ленту если удерживать кнопку на пульте но counter не изменяет, а второй вариант программы так же ничего не делает с counterом…
Всё равно, спасибо за попытку помочь!

Спасибо за ваше мнение, надо как то собраться с мыслями попытаться осознать ваши выводы… Почитав статью по моей ссылке выше у меня как то запал сильно упал на положительное решение этой проблемы том контроллере который я пытался использовать…

Статью не читал. Кратко повторюсь.
Работать с 8 LED и IR можно на UNO и NANO легко.
Пункт 2 не подходящий алгоритм - мало зависит от микроконтроллера.

Если надо больше led то (мое мнение)

  • если нравится решать программные головоломки, то до 30 led можно продолжать использовать UNO или NANO.
  • Если прям очень нравится, то UNO или NANO можно использовать пока памяти хватает.
  • Не хочется - берите двухядерный МК.

Дополнение. Это написано, в предположении, что нельзя терять комманды от IR. Если допустима потеря, то UNO и NANO используют пока памяти хватает. Например цветомузыка Гайвера.

1 лайк

Ну так переписать RGBLoop() в стиле blink without delay и, соответственно, убрать из него delay().

PS. Я тут посмотрел, можно для начала попытаться вставить конструкцию

if(DecON)     
      Dec();

Прямо внутрь циклов в RGBLoop().
Ну и заодно убрать showStrip(); либо из RGBLoop(), либо из setAll().

Именно это Дим-мычъ уже предлагал, не получилось…

Да, справедливо, это наведение лоска

Спасибо и вам за помощь и попытку вникнуть…

Так в коде этот counter и никак не используется вроде. Глянул в библиотеки - там тоже нет.Но, да, если дописать немного - видно, что не пашет.

В общем так должно работать:

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

#define IR_1    0x50
#define IR_2    0x68
#include "NecDecoder.h"
NecDecoder ir;
volatile 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();
  sei();
  Dec();
  delay(4);//подобрать максимально/минимальное значение
}          //чтобы успел сериал отработать

//=====================
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 Dec()
{
  if (ir.available()){ 
    switch (ir.readCommand()) {
      case IR_1: {
       // Serial.println("Pressed UP"); 
      counter++;
        Serial.println(counter);
        break;
      }
      case IR_2: {
       // Serial.println("Pressed DOWN"); 
      counter--;
        Serial.println(counter);
        break;
      }
    }

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

Скорость сериала лучше увеличить, и, использовать по минимуму, т.к. тоже тормозит.
Если он нужен только для отладки - sei() и delay() из irIsr()(стр.30) можно потом убрать.(Это только для работы сериала).

2 лайка

Не удержался, снова включил комп перед работой… Дим-мычъ ты монстр! Всё работает, переменная изменяется, спасибо! :slight_smile:

1 лайк