FastLED и Адресные ленты

seyroland
Offline
Зарегистрирован: 03.12.2021

Доброго времени суток! Ломаю голову уже несколько дней. Делаю контролируемый свет (через 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);
    }
  }

Всем заранее спасибо!

b707
Offline
Зарегистрирован: 26.05.2017

из документации к библиотеке FastLED :

void  showColor (const struct CRGB &color)
  Set all leds on all controllers to the given color.

Метод showColor() для того и создан, чтобы вывести на ВСЕ ленты один и тот же цвет. Если Вам нужно выводить разные цвета или не на все светодиоды - не используйте эту функцию в программе.

Для Вашей задачи простое решение "в лоб" - задавать цвет каждого пикселя отдельно.

rkit
Offline
Зарегистрирован: 23.11.2016

В библиотеке есть замечательный класс crgbset

b707
Offline
Зарегистрирован: 26.05.2017

rkit пишет:

В библиотеке есть замечательный класс crgbset

посмотрел - классная идея. И такая вроде очевидная :)

seyroland
Offline
Зарегистрирован: 03.12.2021

Да, это сработало! Спасибо!

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

Смотрите, этот параметр отвечает у меня за скорость угасания delay (faza1) и пока светодиоды не погаснут следующее нажатие клавиши (новый запуск этого цикла) не произойдет. Возможно ли с каждым нажатием прерывать этот цикл и запускать заново, чтобы не дожидаться пока он закончится? Надеюсь понятно описал вопрос. Заранее спасибо

 
b707
Offline
Зарегистрирован: 26.05.2017

seyroland пишет:

Возможно ли с каждым нажатием прерывать этот цикл и запускать заново, чтобы не дожидаться пока он закончится?

Возможно, но код ппридется переписать процентов на 80.

Вам нужно будет удалить из кода все delay()

seyroland
Offline
Зарегистрирован: 03.12.2021

Спасибо!

Upper
Offline
Зарегистрирован: 23.06.2020

seyroland пишет:

Возможно ли с каждым нажатием прерывать этот цикл и запускать заново, чтобы не дожидаться пока он закончится? Надеюсь понятно описал вопрос. 

 
Возможно я не понял ваш вопрос. Т.к. на то, как я понял ответ очевиден. Проверяйте в этом цикле факт нажатия и прерывайте если надо, в чем трудность?