Конфликт ИК-приемника и светодиодной ленты

Nikel097
Nikel097 аватар
Offline
Зарегистрирован: 14.04.2017

Добрый день!

Проблема следующая. Имеется Arduino Nano, управляющая двумя самопаяными светодиодными лентами из светодиодов ws2812b, по 8 штук в каждой. Также имеется обычный ИК-приемник, принимающий сигналы с любого пульта от телевизора. Если коротко, то суть заключается в том, чтобы по различным сигналам менять освещение и яркость светодиодов. Однако, как только я в программе добавляю строки 

  LED_tah.show();
  LED_spd.show();

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

Еще одно возможное влияение - это питание. Питается система от понижающего модуля mini360. Он импульсный, возможно создает помехи, конденсаторы еще не пробовал припаять.
 
Из кода программы максимально постарался все выкинуть и выглядит он следующим образом:
 
#include <IRremote.h>       //Библиотека для ИК-приемника
#include <Adafruit_NeoPixel.h>                            // подключаем библиотеку

#define LTAH 10      // пин подключения управления светодиодами тахометра
#define LSPEED 11      // пин подключения управления светодиодами спидометра
#define NUMPIXELS 8 //Число светодиодов в ленте

Adafruit_NeoPixel LED_tah = Adafruit_NeoPixel(NUMPIXELS, LTAH, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel LED_spd = Adafruit_NeoPixel(NUMPIXELS, LSPEED, NEO_GRB + NEO_KHZ800);

IRrecv irrecv(A1); // указываем пин, к которому подключен IR приемник
decode_results results;

void setup() {
  irrecv.enableIRIn();      //Инициализация ИК-приемника
  
  LED_tah.begin(); //Инициализируем библиотеку Adafruit_NeoPixel
  LED_tah.show(); //гасим светодиоды из указанного диапазона
  LED_spd.begin(); //Инициализируем библиотеку Adafruit_NeoPixel
  LED_spd.show(); //гасим светодиоды из указанного диапазона
  
  Serial.begin(9600);
}

void loop() {
        //--------- если был сигнал от ИК-приемника, то  ------- 
  if (irrecv.decode(&results)) // если данные пришли выполняем команды
  {
    switch(results.value) {
    case 2155806975 : //следующая программа
        programm++;
        if (programm >= 5) programm = 1;
        break;
    case 2155839615 : //предыдущая программа
        programm--;
        if (programm == 0) programm = 4;
        break;
    }
    irrecv.resume(); // принимаем следующий сигнал на ИК приемнике
  }
  turn_leds();  // п/п влючения светодиодов, соответственно текущим данным
}

// п/п влючения светодиодов, соответственно текущим данным
void turn_leds() {
  
  LED_tah.show();
  LED_spd.show(); 
}

Если кто сталкивался или знает решение проблемы, прошу подскажите пожалуйста.

Logik
Offline
Зарегистрирован: 05.08.2014

Сталкивались. Конфликтует оно по времени. И прием с ИК и динамическая индикация на ws2812b чувствительны к выдержке временных интервалов. При этом вывод в ws2812b нельзя прерывать, а опрос приемника надо делать часто и не откладывать. Вот и конфликтует. 

Я переставал выводить на ws2812b при обнаружении активности в ИК канале.

Можете здесь глянуть http://arduino.ru/forum/proekty/pokhvalimsya-khudozhestvennoi-samodeyatelnostyu-na-ws2812#comment-257986 .

Nikel097
Nikel097 аватар
Offline
Зарегистрирован: 14.04.2017

Logik пишет:

Сталкивались. Конфликтует оно по времени. И прием с ИК и динамическая индикация на ws2812b чувствительны к выдержке временных интервалов. При этом вывод в ws2812b нельзя прерывать, а опрос приемника надо делать часто и не откладывать. Вот и конфликтует. 

Я переставал выводить на ws2812b при обнаружении активности в ИК канале.

Можете здесь глянуть http://arduino.ru/forum/proekty/pokhvalimsya-khudozhestvennoi-samodeyatelnostyu-na-ws2812#comment-257986 .

Подскажите пожалуйста, а каким образом возможно, с помощью библиотеки IRremote.h, можно понимать, что по ИК-каналу связи идет передача данных, чтобы в этот момант также прерывать вывод для светодиодов?

Или же просто как правильно поменять конструкцию программы? Менял местами многое, но результата не дало.

Nikel097
Nikel097 аватар
Offline
Зарегистрирован: 14.04.2017

Проблему решил следующим способом:

как только на ИК-приемник поступает сигнал, на его логическом выходе образуется низкий сигнал (ардуиновская АЦП показывает 1 из промежутка от 0..1023). Таким образом, как только уровень сигнала становится низким, значит начался прием какого-то сигнала. Оконцовкой передачи можно считать рассшифровку этого сигнала. Общая конструкция выглядит следующим образом:

#include <IRremote.h>
IRrecv irrecv(A0); // указываем пин, к которому подключен IR приемник
decode_results results;

#include <Adafruit_NeoPixel.h>                            // подключаем библиотеку
Adafruit_NeoPixel LED_spd = Adafruit_NeoPixel(8, 10, NEO_GRB + NEO_KHZ800);

bool flag_IR=false;

void setup() {
  irrecv.enableIRIn();
  Serial.begin(9600);

  LED_spd.begin(); //Инициализируем библиотеку Adafruit_NeoPixel
  LED_spd.show(); //гасим светодиоды из указанного диапазона
}

void loop() {
  if (analogRead(A0)<10) flag_IR=true;
  if (irrecv.decode(&results)) // если данные пришли выполняем команды
  { 
    flag_IR=false;
    Serial.println(results.value);
    irrecv.resume(); // принимаем следующий сигнал на ИК приемнике
  }

  if (!flag_IR) LED_spd.show();
}