Конфликт FastLED и IrRemote
- Войдите на сайт для отправки комментариев
Чт, 19/10/2017 - 23:11
Всем добрый вечер.
Столкнулся с такой ситуацией, скорее всего, мне просто не хватает опыта, но...
Сделал простую гирлянду на диодах WS2812B, написал несколько режимов и управление переключениями режимов с ИК пульта. Ситуация такая, пока в массиве CRGB указано 5-6 диодов, все в порядке, как только количество диодов становится 8 и больше, данные с пульта начинают идти некорректно.
Возможно, в моем скетче что-то криво, но, смысл такой, что с 5 диодами все работает так, как я задумал, как только ставить больше, начинаются чудеса.
Скетч и скриншоты того, что происходит при разных значениях количества диодов прилагаю.
Очень надеюсь на коллективный разум. 

#include "IRremote.h"
#include "FastLED.h"
#define DATA_PIN 12
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define NUM_LEDS 5
#define FRAMES_PER_SECOND 120
IRrecv irrecv(2); // указываем вывод, к которому подключен приемник
decode_results results;
CRGB leds[NUM_LEDS];
int x = 0;
uint8_t gHue = 0;
int BRIGHTNESS = 150;
void setup() {
delay(2000); // 3 second delay for recovery
irrecv.enableIRIn(); // запускаем прием
Serial.begin(9600); // выставляем скорость COM порта
// tell FastLED about the LED strip configuration
FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
// set master brightness control
FastLED.setBrightness(BRIGHTNESS);
}
void loop()
{
FastLED.setBrightness(BRIGHTNESS);
// insert a delay to keep the framerate modest
FastLED.delay(1000/FRAMES_PER_SECOND);
EVERY_N_MILLISECONDS( 20 ) { gHue++; }
FastLED.show();
reader ();
}
void reader() // Функция считывания с приемника
{
if (irrecv.decode(&results)) // получили результат с приемника
{
if(results.value == 0xFF20DF)
{
x=1; // присваиваем значение переменной
}
if(results.value == 0xFFA05F)
{
x=2; // Режим 2
}
if(results.value == 0xFF609F)
{
x=3; // Режим 3
}
if(results.value == 0xFFE01F)
{
x=4; // Режим 4
}
if(results.value == 0xFF02FD)
{
x=5; // Выключение
}
if(results.value == 0xFF3AC5)
{
BRIGHTNESSPLUS (); // Увеличение яркости
}
if(results.value == 0xFFBA45)
{
BRIGHTNESSMINUS (); // Увеличение яркости
}
switch (x) // Сравниваем значение Х
{
case 1:
rainbow(); // Включаем режим 1
break;
case 2:
confetti(); // Включаем режим 2
break;
case 3:
sample2(); // Включаем режим 3
break;
case 4:
OrangeRed(); // Красно-оранжевый
break;
case 5:
Shutdown(); // Включаем режим 4
break;
}
delay(300);
irrecv.resume(); // Ждем следущей команды
Serial.println (x);
Serial.println (BRIGHTNESS); // Выводим в серийный порт значение переменной Х
Serial.println( results.value, HEX );
}
else // Если данные не пришли,
{
switch (x) // сравниваем значение переменной Х и включаем:
{
case 1:
rainbow(); // Включаем режим 1
break;
case 2:
confetti(); // Включаем режим 2
break;
case 3:
sample2(); // Включаем режим 3
break;
case 4:
OrangeRed(); // Включаем режим 4
break;
case 5:
Shutdown(); // Включаем режим 4
break;
}
}
}
void rainbow() // режим 1
{
fill_rainbow( leds, NUM_LEDS, gHue, 7);
}
void confetti() // Режим 2
{
fadeToBlackBy( leds, NUM_LEDS, 20);
byte dothue = 0;
for( int i = 0; i < 8; i++) {
leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
dothue += 32;
}
}
void sample2() // Режим 3
{
leds[0] = CRGB::Blue;
leds[1] = CRGB::Blue;
leds[2] = CRGB::White;
leds[3] = CRGB::Red;
leds[4] = CRGB::Red;
FastLED.show();
}
void OrangeRed() // Режим 4
{
fill_solid( leds, NUM_LEDS,CRGB::OrangeRed);
}
void BRIGHTNESSPLUS() // Функция увеличения яркости
{
if (BRIGHTNESS < 255)
{
BRIGHTNESS = BRIGHTNESS + 5;
}
}
void BRIGHTNESSMINUS() // Функция уменьшения яркости
{
if (BRIGHTNESS > 0)
{
BRIGHTNESS = BRIGHTNESS - 5;
}
}
void Shutdown()
{
fadeToBlackBy( leds, NUM_LEDS, 3); // Плавное выключение ленты
// fill_solid( leds, NUM_LEDS,CRGB::Black);
}
Есть у меня новогодняя коробочка с пиксельной гирляндой, фастледом и irremote... Тоже были проблемы с непонятными кодами. Не помню уж в чем там конкретно дело было, но в камментах я себе написал, что чем длиннее луп, тем больше приходит битых пакетов. А у вас там и дилеи и вывод в serial на 9600.
Так же, можно предположить, что у вас фастледом при выводе на 2812 запрещаются прерывания, а их использует irremote.
Ну и, в финале хочу отметить, что вижу ваш фастлед, нацеленным на, скорее всего, программную эмуляцию SPI. Попробуйте переключится на использование хардварной SPI/USART шины : https://github.com/FastLED/FastLED/wiki/SPI-Hardware-or-Bit-banging
Большое спасибо за наводку. Раньше шерстил документацию FastLED, но так и не дошел до этой главы. Похоже, проблема именно в прерываниях. Буду думать.
Использование хардварного SPI не помогает. Очевидно, проблему sadman41 определил правильно. Проблема в том, что WS2812 блокирует прерывания на момент формирования и отправки пакета. МОжет. у кого-нибудь, есть мысли, как обойти эту проблему?
Закомментируйте FastLed.show() и сразу узнаете, он ли гадит.
Или сообщите адрес - я вам свою мигалку дам, проверите.
Адрес: Blackmamba3356@gmail.com
На счет FastLED.show, пробовал закомментить, но в скетче есть команды, которые заставляют диоды загораться без этой команды. Если пришлете, буду благодарен