FastLED и Адресные ленты
- Войдите на сайт для отправки комментариев
Пт, 03/12/2021 - 11:21
Доброго времени суток! Ломаю голову уже несколько дней. Делаю контролируемый свет (через midi сигналы). Если кратко, то использую midi сигнал как контроллер (например при нажатии ноты C4 - ее номер 72, загорается лента №1 определенным цветом).
Столкнулся с такой проблемой: в коде есть функция загорания и затухания света, но загораются все подключенные ленты и затухают все ленты. Хотелось бы настроить эту функцию для каждой ленты отдельно. Пытаюсь понять как это реализовать\прописать.
Полный скетч:
// Подключаем библиотеку для управления светодиодами #include "FastLED.h" // обозначим цифровые выходы на ардуино #define LEFT_LONG 6 #define LEFT_SHORT 4 #define NUM_STRIPS 2 // количество лент #define NUM_LEDS_PER_STRIP 8 // количество светодиодов в 1 ленте // создаем двухмерный массив для удобного управления CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP]; // задаем массив цвета byte colors[] = {0, 32, 64, 96, 128, 160, 192, 224, 239 }; // Значение цвета и Master (яркости) по-умолчанию byte ColorBasic = 0; byte Master = 255; byte commandByte; // первый байт MIDI-сообщения, здесь будут хранится значения команды (noteOn, noteOff, Controller) byte noteByte; // второй (номер ноты) byte velocityByte; // третий байт — значение (для команд noteOn/Off имеет смысл velocity, а для Controller — это значение крутилки). byte velocityByte1; // используем функцию map() с 0-127 на 0-255 byte noteOn = 144; // нота нажата byte noteOff = 128; // отпустили ноту byte faza = 0; // через эту переменную будем задавать задержку delay(faza) в некоторых командах void setup() { // запускаем Serial-порт со скорость 115200 Serial.begin(115200); FastLED.addLeds<NEOPIXEL, LEFT_LONG>(leds[0], NUM_LEDS_PER_STRIP); FastLED.addLeds<NEOPIXEL, LEFT_SHORT>(leds[1], NUM_LEDS_PER_STRIP); } // pointer() включает определенный светодиод в определенной ленте независимо от других светодиодов // num_strip = номер ленты (от 0 до 3, см рис в [Обозначении фонарей]) // num_led = номер светодиода в ленте с номером num_strip // master = яркость светодиодов // color = цвет void pointer(byte num_strip, byte num_led, byte master, byte color) { leds[num_strip][num_led] = CHSV(color, 255, master); FastLED.show(); } // blackout() выключает определенный светодиод в определенной ленте независимо от других светодиодов void blackout(byte num_strip, byte num_led) { leds[num_strip][num_led] = CHSV(0, 0, 0); FastLED.show(); } void checkMIDI(){ do{ // считываем первые 3 байта команды if (Serial.available()){ commandByte = Serial.read();//read first byte noteByte = Serial.read();//read next byte velocityByte1 = Serial.read();//read final byte velocityByte = map(velocityByte1, 0, 127, 0, 255); Master = velocityByte; // связали Master со значением Velocity ноты // Контроллеры if(commandByte == 176 && noteByte == 91) Master = velocityByte; // Master if(commandByte == 176 && noteByte == 74) faza = velocityByte; // Velocity byte faza1 = map(faza, 0, 200, 0, 30); // все светодиоды загораются одновременно и постепенно затухают через промежуток faza в миллисекундах, кратный максимальному значению i в цикле. if(noteByte == 72 && commandByte == noteOn) { faza1 = map(faza, 0, 200, 0, 30); for(byte i = 255; i > 0; i=i-5) { FastLED.showColor(CHSV(ColorBasic = colors[7], 255, i)); delay (faza1); } for(byte i = 0; i < NUM_LEDS_PER_STRIP; i++){ blackout(0, i); } } }// end if }// end do while (Serial.available() > 2);// считываем первые 3 байта } void loop(){ // запускаем функцию работы с MIDI checkMIDI(); delay(50); }
Участок отвечающий за загорание и плавное угасание:
// все светодиоды загораются одновременно и постепенно затухают через промежуток faza в миллисекундах, кратный максимальному значению i в цикле. if(noteByte == 72 && commandByte == noteOn) { faza1 = map(faza, 0, 200, 0, 30); for(byte i = 255; i > 0; i=i-5) { FastLED.showColor(CHSV(ColorBasic = colors[7], 255, i)); delay (faza1); } for(byte i = 0; i < NUM_LEDS_PER_STRIP; i++){ blackout(0, i); } }
Всем заранее спасибо!
из документации к библиотеке FastLED :
Метод showColor() для того и создан, чтобы вывести на ВСЕ ленты один и тот же цвет. Если Вам нужно выводить разные цвета или не на все светодиоды - не используйте эту функцию в программе.
Для Вашей задачи простое решение "в лоб" - задавать цвет каждого пикселя отдельно.
В библиотеке есть замечательный класс crgbset
В библиотеке есть замечательный класс crgbset
посмотрел - классная идея. И такая вроде очевидная :)
Да, это сработало! Спасибо!
Есть еще один вопрос, возможно вы направите меня в нужное русло или подскажите реально ли вообще это.
Смотрите, этот параметр отвечает у меня за скорость угасания delay (faza1) и пока светодиоды не погаснут следующее нажатие клавиши (новый запуск этого цикла) не произойдет. Возможно ли с каждым нажатием прерывать этот цикл и запускать заново, чтобы не дожидаться пока он закончится? Надеюсь понятно описал вопрос. Заранее спасибо
Возможно ли с каждым нажатием прерывать этот цикл и запускать заново, чтобы не дожидаться пока он закончится?
Возможно, но код ппридется переписать процентов на 80.
Вам нужно будет удалить из кода все delay()
Спасибо!
Возможно ли с каждым нажатием прерывать этот цикл и запускать заново, чтобы не дожидаться пока он закончится? Надеюсь понятно описал вопрос.