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()
Спасибо!
Возможно ли с каждым нажатием прерывать этот цикл и запускать заново, чтобы не дожидаться пока он закончится? Надеюсь понятно описал вопрос.