Конфликт 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, пробовал закомментить, но в скетче есть команды, которые заставляют диоды загораться без этой команды. Если пришлете, буду благодарен