В первых двух частях мы разобрались с оборудованием, а также попробовали помигать светодиодами. Теперь будем заставлять их переключаться, как мы того хотим.
Чтобы проще было менять программу переключения, отдельные световые эффекты я вынес в функции, а в главной функции программы loop() оставил только их вызов и передачу параметров.
Итак, нам из второй части понадобится следующий код, добавив в него объявление массива и начальное его заполнение:
#include <FastLED.h>
#define NUM_LEDS 72 // измените количество на своё
#define NUM_HALF int(NUM_LEDS / 2)
#define NUM_QUARTER int(NUM_LEDS / 4)
#define DATA_PIN 7
#define CLOCK_PIN 13
#define BRIGHTNESS 192 // яркость можно менять от 0 до 255
CRGB leds[NUM_LEDS]; // массив со значениями цветов для светодиодов
CRGB colors[4]; // массив со значениями цветов для переключения
void setup() {
LEDS.setBrightness(BRIGHTNESS);
FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, NUM_LEDS);
// следующие цвета меняем на те, которые нравятся вам
colors[0] = 0xFF0000; // красный
colors[1] = 0xFFCC00; // жёлтый, значение 0xFFFF00 даёт зеленоватый оттенок
colors[2] = 0x00FF00; // зелёный
colors[3] = 0x0000FF; // синий
}
void loop() {
// здесь мы будем вызывать остальные функции
}
Для начала попробуем самый простой вариант – включить каждый четвёртый светодиод одним и тем же цветом и сдвигать его по ленте. Сразу замечание – в начале каждого эффекта очищаем массив, чтобы не было наложений на то, что осталось от предыдущего:
memset(leds, 0, NUM_LEDS * sizeof(struct CRGB));
Итак, пробуем:
void one_color_switch(byte count, CRGB color) {
for (int k = 0; k < count; k++) {
for (byte i = 0; i <=3; i++) {
memset(leds, 0, NUM_LEDS * sizeof(struct CRGB));
for (byte Led = 0; Led < NUM_QUARTER; Led++) {
leds[Led * 4] + i = color;
}
LEDS.show();
delay(400);
}
}
}
И почти так же переключаем четыре цвета:
void four_colors_switch(byte count) {
for (int k = 0; k < count; k++) {
for (byte i = 0; i <=3; i++) {
memset(leds, 0, NUM_LEDS * sizeof(struct CRGB));
for (byte Led = 0; Led < NUM_QUARTER; Led++) {
leds[Led * 4] + i = colors[i];
}
LEDS.show();
delay(400);
}
}
}
В этом случае значения цвета для светодиодов удобнее брать из массива, а передавать только количество повторов. Важное замечание – поскольку для количества повторов используется только один байт, не следует делать его больше, чем 255, иначе будет переполнение и программа не выйдет из цикла. Если нужно больше – используем двухбайтовые или четырёхбайтовые переменные. Также нужно следить за типами переменных в циклах внутри функций.
С переключением всё понятно, попробуем сделать что-то посложнее. Но вначале для этого напишем вспомогательную функцию для сдвига значений в массиве, чтобы делать меньше вычислений. Итак:
void shift_fwd() {
CRGB tmpColor;
tmpColor = leds[NUM_LEDS - 1];
for (int i = NUM_LEDS - 1; i > 0; i--) {
leds[i] = leds[i - 1];
}
leds[0] = tmpColor;
}
И теперь попробуем вывести на ленте радугу, но перед этим отметим, что библиотека умеет работать не только с RGB-моделью цвета, но и с HSB (также иногда называемой HSV). И сейчас для упрощения расчётов мы используем именно эту модель:
void rainbow_cycle(byte count, byte brightness, byte rainbows = 1) {
unsigned long hue;
for (byte Led = 0; Led < NUM_LEDS; Led++) {
hue = 256 *rainbows * Led;
leds[Led].setHSV(hue / NUM_LEDS, 255, brightness);
}
for (int i = 0; i < count * NUM_LEDS; i++) {
LEDS.show();
delay(400);
shift_fwd();
}
}
И после этого добавляем в основную функцию следующее:
void loop() {
one_color_switch(8, 0x00FF33); // 8 повторов со светло-зелёным цветом
four_colors_switch(10); // 10 циклов переключений
rainbow_cycle(4, 255, 2) // 4 цикла переключений на максимальной яркости (255), 2 радуги на ленте
}
И последний шаг – компилируем, загружаем в Arduino и смотрим результат.
В следующей, последней части мы попробуем не просто включать и выключать светодиоды, а сделать плавное включение и плавные переходы цвета.
Комментарии: