Общие сведения:
В этом уроке мы создадим стильный светильник с управлением адресными светодиодами NeoPixel с помощью ИК-пульта и/или энкодера с памятью, выполненный в стиле атрибутики известного супергероя.
Светильник поддерживает смену режимов, а так же изменение уровня яркости светодиодов.
Видео:
Нам понадобится:
- 1х Arduino / Piranha Pro Mini(с колодкой / без колодки);
- 1х USB-UART преобразователь;
- 4х Trema-модуль Адресный светодиод NeoPixel;
- 1х Trema-модуль Энкодер с памятью;
- 1х Trema-модуль ИК-приёмник;
- 1х Пульт ДУ;
- 1х Расширитель выводов I2C;
- 2х Комплект силиконовых проводов(толстая жила);
- 1х Источник питания(вариант 1 / вариант 2);
- 1х Комплект нейлоновых стоек 20мм;
- 7х Комплект нейлоновых стоек 8мм;
- 8х Комплект нейлоновых винтов 8мм;
- ПВХ-конструктор(или любой другой подходящий материал: фанера, плотный картон и т.д.);
Для реализации проекта необходимо установить библиотеки:
- iarduino_IR — для для работы с ИК-приёмопередатчиками.
- iarduino_NeoPixel — для работы с адресными светодиодами NeoPixel;
О том, как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki - Установка библиотек в Arduino IDE.
Описание работы светильника:
После подачи питания светильник готов к работе.
Для включения светильника нажмите центральную клавишу на пульте ДУ или на кнопку энкодера.
Светильник имеет следующие режимы работы светодиодов:
- Перелив всеми цветами радуги;
- Случайное включение случайным цветом;
- Смена одного цвета на другой;
- Имитация пламени;
- Один цвет на выбор по порядку(красный, зелёный, синий, жёлтый, фиолетовый, голубой, белый);
Для того, чтобы изменить уровень яркости светильника достаточно нажать на пульте ДУ кнопки "вверх"/"вниз" или покрутить ручку энкодера в одну или в другую сторону.
Для того, чтобы изменить режим работы, нажмите на пульте ДУ кнопки "влево"/"вправо". На энкодере для смены режима необходимо сначала нажать на кнопку и не отпуская её вращать ручку вправо или влево.
Схема сборки:
Arduino / Piranha Pro Mini:
Чтобы подключить Arduino/Piranha Pro Mini к компьютеру, воспользуйтесь USB-UART преобразователем.

Адресные светодиоды(кликабельно):
Подключите адресные светодиоды NeoPixel к Arduino/Piranha Pro Mini к выводу D5, а питание модуля к I2C Hub'у:

Все используемые в уроке Trema-модули NeoPixel соединены друг c другом, а первый модуль можно подключить к любому выводу Arduino. Номер вывода указывается в скетче (в примере используется вывод D5). Чем больше модулей в цепи, тем больше тока она потребляет!
ИК-приёмник(кликабельно):
Подключите ИК-приёмник к Arduino/Piranha Pro Mini к выводу D7, а питание модуля к I2C Hub'у:

Энкодер с памятью(кликабельно):
Подключите Энкодер с памятью к Arduino/Piranha Pro Mini к следующим выводам: D2(pinT), D3(pinK), D4(pinR), а питание модуля к I2C Hub'у:

Питание(кликабельно):
Подключите питание от источника питания к I2C Hub'у, а от него к Arduino/Piranha Pro Mini :

Схема корпуса(кликабельно):
Корпус состоит из следующих частей:
- Лицевая часть светильника;
- Подставка;
- Задняя стенка светильника с отверстием под энкодер;
- Дополнительный упор для задней стенки;
- Кронштейн для установки светильника на стену;

Код программы (скетч):
//============================================================================================================================================================//
// Подключаем библиотеки:
#include <iarduino_NeoPixel.h> // Подключаем библиотеку iarduino_NeoPixel для работы со светодиодами NeoPixel
#include <iarduino_IR_RX.h> // Подключаем библиотеку для работы с ИК-приёмником
uint8_t neo_pin = 5; // Вывод, к которому подключены модули NeoPixel
uint16_t mod_num = 4; // Количество модулей
iarduino_NeoPixel led(neo_pin, mod_num*4 ); // Объявляем объект LED указывая (№ вывода Arduino к которому подключён модуль NeoPixel, количество используемых светодиодов)
iarduino_IR_RX IR(7); // Объявляем объект IR, с указанием вывода к которому подключён ИК-приёмник
//============================================================================================================================================================//
// Объявляем переменные:
uint8_t j; // Объявляем переменную для хранения значения сдвига спектра цветов для всех светодиодов (от 0 до 255)
uint8_t k; // Объявляем переменную для хранения положения сдвига спектра цвета для каждого светодиода на спектре j (зависит от количества светодиодов)
uint8_t r, g, b; // Объявляем переменную для хранения цветов RGB для каждого светодиода
uint8_t pinT = 2; // Определяем константу указывая ей номер вывода Arduino к которому подключён вывод T (Turn) энкодера с памятью (поворот)
uint8_t pinR = 4; // Определяем константу указывая ей номер вывода Arduino к которому подключён вывод R (Route) энкодера с памятью (направление)
uint8_t pinK = 3; // Определяем константу указывая ей номер вывода Arduino к которому подключён вывод K (Key) энкодера с памятью (кнопка)
uint8_t z = 1; // Определяем константу, указывающую задержку в мс (чем выше значение, тем медленнее перелив цветов)
uint8_t mode = 1; // Флаг режима работы светодиодов
uint8_t mode_old = 1; // Флаг предыдущего режима работы светодиодов
uint8_t brightness = 245; // Переменная значения яркости
bool flg_mode = false; // Флаг изменения режима работы NeoPixel
bool on_off = false; // Триггер включения/выключения света
bool flg_roll_encoder = true; // Флаг наичия поворота ручки энкодера
bool encoder_btn_flg = false; // Флаг нажатия кнопки энкодера
bool first_btn_flg = true; // Флаг, установленный при первом включении
uint32_t led_time; // Переменная для счёта времени работы анимации
bool encoder_use = true; // Флаг использования экодера. Если энкодер отключен, то флаг должен быть сброшен
//============================================================================================================================================================//
void setup(){
if(encoder_use){ // Если используется энкодер, то
pinMode(pinT, INPUT); // Устанавливаем режим работы вывода pinT Arduino как вход
pinMode(pinR, INPUT); // Устанавливаем режим работы вывода pinR Arduino как вход
pinMode(pinK, INPUT); // Устанавливаем режим работы вывода pinK Arduino как вход
}
IR.begin(); // Инициируем работу с ИК-приёмником
led.begin(); // Инициируем работу с модулем NeoPixel
led.setColor(NeoPixelAll,0, 0, 0); // Задаём чёрный цвет светодиодам (не гореть)
led.write(); // Выключаем светодиоды
delay(500); // Задержка 0,5с для завершения инициализации и калибровки
}
//============================================================================================================================================================//
void loop(){
//============================================================================================================================================================//
if(encoder_use){ // Если используется экодер, то
// НАЖАТИЕ КНОПКИ ЭНКОДЕРА
if(!encoder_btn_flg && digitalRead(pinK) || first_btn_flg && digitalRead(pinK)){ // Если флаг нажатия на кнопку сброшен И кнопка нажата ИЛИ флаг первого запуска установлен И кнопка нажата, то
first_btn_flg = false; // сбрасываем флаг первого запуска
flg_roll_encoder = false; // сбрасываем флаг наличия поворота ручки энкодера
}
encoder_btn_flg = digitalRead(pinK); // считываем состояния кнопки энкодера
//==========================================================================================================================================================//
// ВРАЩЕНИЕ РУЧКИ ЭНКОДЕРА
if(digitalRead(pinT)){ // Если ручка энкодера была повёрнута, то
flg_roll_encoder = true; // устанавливаем флаг наличия поворота
pinMode (pinT, OUTPUT); // Устанавливаем режим работы вывода pinT как выход
digitalWrite(pinT, LOW ); // Сбрасываем состояние вывода pinT в логический 0
pinMode (pinT, INPUT ); // Устанавливаем режим работы вывода pinT как вход
if( digitalRead(pinR)&& !digitalRead(pinK)&& on_off){brightness-=10; if(brightness < 10 ){brightness = 10; } mode_old = mode; flg_mode = true;} else // Если вывод pinR установлен в 1 И кнопка отжата И питание ВКЛ, то уменьшаем значение переменной brightness на 10
if(!digitalRead(pinR)&& !digitalRead(pinK)&& on_off){brightness+=10; if(brightness >= 250){brightness = 245;} mode_old = mode; flg_mode = true;} else // Если вывод pinR установлен в 0 И кнопка отжата И питание ВКЛ, то увеличиваем значение переменной mode на 1
if( digitalRead(pinR)&& digitalRead(pinK)&& on_off){mode--; if(mode < 1 ){mode = 11; } mode_old = mode; flg_mode = true;} else // Если вывод pinR установлен в 1 И кнопка нажата И питание ВКЛ, то уменьшаем значение переменной brightness на 10
if(!digitalRead(pinR)&& digitalRead(pinK)&& on_off){mode++; if(mode > 11 ){mode = 1; } mode_old = mode; flg_mode = true;} // Если вывод pinR установлен в 0 И кнопка нажата И питание ВКЛ, то увеличиваем значение переменной mode на 1
delay(2); // Подавляем дребезг контактов
}
//==========================================================================================================================================================//
// ВКЛЮЧИТЬ/ВЫКЛЮЧИТЬ ЛАМПУ
if(!flg_roll_encoder && !digitalRead(pinK)){ // Если флаг наличия поворота сброшен И кнопка отпущена, то
flg_roll_encoder = true; // взводим флаг и
on_off = !on_off; // меняем состояние флага ВКЛ/ВЫКЛ на противоположный тому, что установлен в данный момент
if(on_off) {mode = mode_old; flg_mode = true;} // Если флаг установлен, то включаем NeoPixel в последний установленный режим работы
else {mode = 12; flg_mode = true;} // Если флаг сброшен, то выключаем NeoPixel
}
}
//============================================================================================================================================================//
// НАЖАТИЕ КНОПОК ПУЛЬТА
if (IR.check(true)) { // Настраиваем считывание данных при нажатии и удержании кнопок
if (IR.data == 0xFF02FD) { // Если пришёл сигнал с кнопки "центр"
if (IR.key_press){ // и кнопка НАЖАТА, то
on_off=!on_off; // меняем состояние флага ВКЛ/ВЫКЛ на противоположный тому, что установлен в данный момент
if(on_off) {mode = mode_old; flg_mode = true;} // Если флаг установлен, то включаем NeoPixel в последний установленный режим работы
else {mode = 12; flg_mode = true;}} // Если флаг сброшен, то выключаем NeoPixel
}
if (IR.data == 0xFF22DD) {if(on_off){mode--; if(mode < 1 ){mode = 11; } mode_old = mode; flg_mode = true;}} // Если пришёл сигнал с кнопки "стрелка влево", и флаг наличия питания установлен, то увеличиваем значение mode на 1
if (IR.data == 0xFF629D) {if(on_off){brightness+=10; if(brightness >= 250){brightness = 245;} mode_old = mode; flg_mode = true;}} // Если пришёл сигнал с кнопки "стрелка вверх", и флаг наличия питания установлен, то увеличиваем значение brightness на 10
if (IR.data == 0xFFC23D) {if(on_off){mode++; if(mode > 11 ){mode = 1; } mode_old = mode; flg_mode = true;}} // Если пришёл сигнал с кнопки "стрелка вправо",и флаг наличия питания установлен, то уменьшаем значение mode на 1
if (IR.data == 0xFFA857) {if(on_off){brightness-=10; if(brightness < 10 ){brightness = 10; } mode_old = mode; flg_mode = true;}} // Если пришёл сигнал с кнопки "стрелка вниз", и флаг наличия питания установлен, то уменьшаем значение brightness на 10
if (IR.data == 0xFF30CF) {if(IR.key_press) {if(on_off){mode = 5; mode_old = mode; flg_mode = true;}}} // Если пришёл сигнал с кнопки "Красная", и флаг наличия питания установлен, то устанавливаем значение mode равным 5
if (IR.data == 0xFF18E7) {if(IR.key_press) {if(on_off){mode = 6; mode_old = mode; flg_mode = true;}}} // Если пришёл сигнал с кнопки "Зелёная", и флаг наличия питания установлен, то устанавливаем значение mode равным 6
if (IR.data == 0xFF7A85) {if(IR.key_press) {if(on_off){mode = 7; mode_old = mode; flg_mode = true;}}} // Если пришёл сигнал с кнопки "Синяя", и флаг наличия питания установлен, то устанавливаем значение mode равным 7
if (IR.data == 0xFF10EF) {if(IR.key_press) {if(on_off){mode = 8; mode_old = mode; flg_mode = true;}}} // Если пришёл сигнал с кнопки "Жёлтая", и флаг наличия питания установлен, то устанавливаем значение mode равным 8
if (IR.data == 0xFF38C7) {if(IR.key_press) {if(on_off){mode = 9; mode_old = mode; flg_mode = true;}}} // Если пришёл сигнал с кнопки "Розовая", и флаг наличия питания установлен, то устанавливаем значение mode равным 9
if (IR.data == 0xFF5AA5) {if(IR.key_press) {if(on_off){mode = 10; mode_old = mode; flg_mode = true;}}} // Если пришёл сигнал с кнопки "Голубая", и флаг наличия питания установлен, то устанавливаем значение mode равным 10
}
//============================================================================================================================================================//
// УСТАНОВКА РЕЖИМА РАБОТЫ NEOPIXEL
if(flg_mode){ //
switch (mode){ // Сверяем значение соответствующее режиму работы
//=================================================//
// ПЕРЕЛИВ ВСЕХ ЦВЕТОВ РАДУГИ
case 1: // Если значение mode = 1
if(millis() > (led_time + z)){ // Проверяем, прошло ли заданное время с момента последней сработки
led_time = millis(); // Обновляем счётчик
j++; // Смещаем спектр цветов для всех светодиодов
for(uint16_t i=0; i<led.count(); i++){ // Проходим по всем светодиодам
k=((uint16_t)(i*256/led.count())+j); // Определяем положение очередного светодиода на смещённом спектре цветов
if(k<85) { b=0; r=k*3; g=255-r;}else // Перелив от зелёного к красному, через жёлтый
if(k<170){k-=85; g=0; b=k*3; r=255-b;}else // Перелив от красного к синему , через фиолетовый
{k-=170; r=0; g=k*3; b=255-g;} // Перелив от синего к зелёному, через голубой
led.setColor(i, // Устанавливаем выбранный цвет для очередного светодиода
map(r, 0, 255, 0, brightness), // Задаём зависимость яркости красного от параметра brightness
map(g, 0, 255, 0, brightness), // Задаём зависимость яркости зелёного от параметра brightness
map(b, 0, 255, 0, brightness)); // Задаём зависимость яркости синего от параметра brightness
}
led.write(); // Записываем цвета в светодиоды
}
break;
//=================================================//
// ВКЛЮЧЕНИЕ СЛУЧАЙНЫМ ЦВЕТОМ
case 2: // Если значение mode = 2
if(millis() > (led_time + z*100)){ // Проверяем, прошло ли заданное время с момента последней сработки
led_time = millis(); // Обновляем счётчик
for(uint16_t t=0; t<led.count(); t++){ // Проходим по всем светодиодам
int8_t i=random(3); // Определяем какой из трех составляющих цветов будет отсутствовать R, G, или B
if(i==0){r=0;}else{r=random(0xFF);} // Определяем случайное значение для переменной r
if(i==1){g=0;}else{g=random(0xFF);} // Определяем случайное значение для переменной g
if(i==2){b=0;}else{b=random(0xFF);} // Определяем случайное значение для переменной b
led.setColor(t, // Устанавливаем цвет r,g,b для случайного светодиода
map(r, 0, 255, 0, brightness), // Задаём зависимость яркости красного от параметра brightness
map(g, 0, 255, 0, brightness), // Задаём зависимость яркости зелёного от параметра brightness
map(b, 0, 255, 0, brightness)); // Задаём зависимость яркости синего от параметра brightness
}
led.write(); // Записываем цвета в светодиоды
}
break;
//=================================================//
// ВСЕ СВЕТОДИОДЫ ЗАЖИГАЮТСЯ ОДНИМ ЦВЕТОМ
case 3: // Если значение mode = 3
if(millis() > (led_time + z*1000)){ // Проверяем, прошло ли заданное время с момента последней сработки
led_time = millis(); // Обновляем счётчик
uint16_t f; // Определяем переменную как коэффициент яркости
if(f==0 ){f=42; }else // f=60° (0 ... 42 ... 255 = 0° ... 60° ... 360°)
if(f==42 ){f=85; }else // f=120° (0 ... 85 ... 255 = 0° ... 120° ... 360°)
if(f==85 ){f=127;}else // f=180° (0 ... 127 ... 255 = 0° ... 180° ... 360°)
if(f==127){f=170;}else // f=240° (0 ... 170 ... 255 = 0° ... 240° ... 360°)
if(f==170){f=212;}else // f=300° (0 ... 212 ... 255 = 0° ... 300° ... 360°)
if(f==212){f=0; } // f=360° (0 ... 255 ... 255 = 0° ... 360° ... 360°)
if(f<85) { b=0; r=f*3; g=255-r;}else // Перелив от зелёного к красному, через жёлтый
if(f<170){f-=85; g=0; b=f*3; r=255-b;}else // Перелив от красного к синему , через фиолетовый
{f-=170; r=0; g=f*3; b=255-g;} // Перелив от синего к зелёному, через голубой
led.setColor(NeoPixelAll, // Устанавливаем выбранный цвет для очередного светодиода
map(r, 0, 255, 0, brightness), // Задаём зависимость яркости красного от параметра brightness
map(g, 0, 255, 0, brightness), // Задаём зависимость яркости зелёного от параметра brightness
map(b, 0, 255, 0, brightness)); // Задаём зависимость яркости синего от параметра brightness
led.write(); // Записываем цвета в светодиоды
}
break;
//=================================================//
// ГОРИТ СВЕЧА
case 4: // Если значение mode = 4
if(millis() > (led_time + random(100,200))){ // Проверяем, прошло ли заданное время с момента последней сработки
led_time = millis(); // Обновляем счётчик
for(uint16_t m=0; m<led.count(); m++){ // Проходим по всем светодиодам
if(m%2==0){ // Каждый второй светодиод настраиваем гореть красным
r = random(10,50); // Определяем случайное значение яркости красного
led.setColor(m, // Устанавливаем выбранный цвет для очередного светодиода
map(r, 0, 255, 0, brightness), // Задаём зависимость яркости красного от параметра brightness
0, // Устанавливаем зелёный равным 0
0); // Устанавливаем синий равным 0
}else { // Оставшиеся светодиоды настраиваем гореть жёлтым
r = random(50,256); g = r; // Определяем случайное значение яркости жёлтого
led.setColor(m, // Устанавливаем выбранный цвет для очередного светодиода
map(r, 0, 255, 0, brightness), // Задаём зависимость яркости красного от параметра brightness
map(g, 0, 255, 0, brightness), // Задаём зависимость яркости зелёного от параметра brightness
0); // Устанавливаем синий равным 0
}
}
led.write(); // Записываем цвета в светодиоды
}
break;
//=================================================//
// ГОРИТ КРАСНЫМ
case 5: // Если значение mode = 5
flg_mode = false; // Сбрасываем флаг изменения режима работы NeoPixel (установили цвет и больше не устанавливаем заново каждый цикл)
r = 255; g = 0; b = 0; // Выставляем значение RGB-спектра в красный цвет
led.setColor(NeoPixelAll, // Устанавливаем выбранный цвет для всех светодиодов
map(r, 0, 255, 0, brightness), // Задаём зависимость яркости красного от параметра brightness
g, // Устанавливаем зелёный равным 0
b); // Устанавливаем синий равным 0
led.write(); // Записываем цвета в светодиоды
break;
//=================================================//
// ГОРИТ ЗЕЛЁНЫМ
case 6: // Если значение mode = 6
flg_mode = false; // Сбрасываем флаг изменения режима работы NeoPixel (установили цвет и больше не устанавливаем заново каждый цикл)
r = 0; g = 255; b = 0; // Выставляем значение RGB-спектра в зелёный цвет
led.setColor(NeoPixelAll, // Устанавливаем выбранный цвет для всех светодиодов
r, // Устанавливаем красный равным 0
map(g, 0, 255, 0, brightness), // Задаём зависимость яркости зелёного от параметра brightness
b); // Устанавливаем синий равным 0
led.write(); // Записываем цвета в светодиоды
break;
//=================================================//
// ГОРИТ СИНИМ
case 7: // Если значение mode = 7
flg_mode = false; // Сбрасываем флаг изменения режима работы NeoPixel (установили цвет и больше не устанавливаем заново каждый цикл)
r = 0; g = 0; b = 255; // Выставляем значение RGB-спектра в синий цвет
led.setColor(NeoPixelAll, // Устанавливаем выбранный цвет для всех светодиодов
r, // Устанавливаем красный равным 0
g, // Устанавливаем зелёный равным 0
map(b, 0, 255, 0, brightness)); // Задаём зависимость яркости синего от параметра brightness
led.write(); // Записываем цвета в светодиоды
break;
//=================================================//
// ГОРИТ ЖЁЛТЫМ
case 8: // Если значение mode = 8
flg_mode = false; // Сбрасываем флаг изменения режима работы NeoPixel (установили цвет и больше не устанавливаем заново каждый цикл)
r = 255; g = 255; b = 0; // Выставляем значение RGB-спектра в жёлтый цвет
led.setColor(NeoPixelAll, // Устанавливаем выбранный цвет для всех светодиодов
map(r, 0, 255, 0, brightness), // Задаём зависимость яркости красного от параметра brightness
map(g, 0, 255, 0, brightness), // Задаём зависимость яркости зелёного от параметра brightness
b); // Устанавливаем синий равным 0
led.write(); // Записываем цвета в светодиоды
break;
//=================================================//
// ГОРИТ ФИОЛЕТОВЫЙ
case 9: // Если начение mode = 9
flg_mode = false; // Сбрасываем флаг изменения режима работы NeoPixel (установили цвет и больше не устанавливаем заново каждый цикл)
r = 255; g = 0; b = 255; // Выставляем значение RGB-спектра в фиолетовый цвет
led.setColor(NeoPixelAll, // Устанавливаем выбранный цвет для всех светодиодов
map(r, 0, 255, 0, brightness), // Задаём зависимость яркости красного от параметра brightness
g, // Устанавливаем зелёный равным 0
map(b, 0, 255, 0, brightness)); // Задаём зависимость яркости синего от параметра brightness
led.write(); // Записываем цвета в светодиоды
break;
//=================================================//
// ГОРИТ ГОЛУБЫМ
case 10: // Если значение mode = 10
flg_mode = false; // Сбрасываем флаг изменения режима работы NeoPixel (установили цвет и больше не устанавливаем заново каждый цикл)
r = 0; g = 255; b = 255; // Выставляем значение RGB-спектра в голубой цвет
led.setColor(NeoPixelAll, // Устанавливаем выбранный цвет для всех светодиодов
r, // Устанавливаем красный равным 0
map(g, 0, 255, 0, brightness), // Задаём зависимость яркости зелёного от параметра brightness
map(b, 0, 255, 0, brightness)); // Задаём зависимость яркости синего от параметра brightness
led.write(); // Записываем цвета в светодиоды
break;
//=================================================//
// ГОРИТ БЕЛЫМ
case 11: // Если начение mode = 11
flg_mode = false; // Сбрасываем флаг изменения режима работы NeoPixel (установили цвет и больше не устанавливаем заново каждый цикл)
r = 255; g = 255; b = 255; // Выставляем значение RGB-спектра в белый цвет
led.setColor(NeoPixelAll, // Устанавливаем выбранный цвет для всех светодиодов
map(r, 0, 255, 0, brightness), // Задаём зависимость яркости красного от параметра brightness
map(g, 0, 255, 0, brightness), // Задаём зависимость яркости зелёного от параметра brightness
map(b, 0, 255, 0, brightness)); // Задаём зависимость яркости синего от параметра brightness
led.write(); // Записываем цвета в светодиоды
break;
//=================================================//
// ВЫКЛЮЧЕН
case 12: // Если значение mode = 12
flg_mode = false; // Сбрасываем флаг изменения режима работы NeoPixel (установили цвет и больше не устанавливаем заново каждый цикл)
r = 0; g = 0; b = 0; // Выставляем значение RGB-спектра в чёрный цвет (не горят)
led.setColor(NeoPixelAll, // Устанавливаем выбранный цвет для всех светодиодов
r, // Задаём зависимость яркости красного от параметра brightness
g, // Задаём зависимость яркости зелёного от параметра brightness
b); // Задаём зависимость яркости синего от параметра brightness
led.write(); // Записываем цвета в светодиоды
break;
//=================================================//
}
}
}
Алгоритм работы скетча:
До кода void setup() определяются переменные, подключаются необходимые библиотеки.
Особо стоит отметить флаг encoder_use — если вы выбрали настенный вариант исполнения, то флаг необходимо установить в значение false, а если настольный вариант, то в значение true.
В коде void setup() настраиваются выводы энкодера(если используется), инициализируются ИК-приёмник и адресные светодиоды NeoPixel. Светодиоды гасятся.
Код void loop() делится на несколько частей:
- Блок работы с энкодером (если используется)
- Сначала выполняется проверка условия, не удерживается ли кнопка, и если да, то сбрасывается флаг наличия поворота -
flg_roll_encoder; - После этого повторно считывается состояние кнопки и записывается в значение флага
encoder_btn_flg, чтобы не происходило повторного входа в первый блок; - Далее выполняется проверка наличия вращения ручки энкодера:
- Если поворот был совершён, то устанавливается флаг
flg_roll_encoder, выполняется сброс состояния поворота (выводpinT), и проверяется, поворот был выполнен при нажатой или отпущенной кнопке:- Если кнопка была отпущена, то выполняем регулировку яркости в зависимости от направления вращения ручки;
- Если кнопка было нажата, то выполняем смену режима работы светодиодов NeoPixel в зависимости от направления вращения ручки;
- Если поворота не было, то входим в блок включения/выключения и меняем состояние флага
on_offна противоположное установленному, а значит включаем или выключаем светильник;
- Если поворот был совершён, то устанавливается флаг
- Сначала выполняется проверка условия, не удерживается ли кнопка, и если да, то сбрасывается флаг наличия поворота -
- Далее следует блок работы с ИК-приёмником и пультом ДУ:
- Если кнопка на пульте была нажата, то в зависимости от считанного значения выполняем одно из следующих действий:
- Если была нажата центральная кнопка, то светильник включается или выключается;
- Если нажата кнопка "вверх"/"вниз", то меняется яркость светодиодов;
- Если нажата кнопка "влево"/"вправо", то меняется режим работы светодиодов;
- Если нажата одна из "цветных" кнопок, то в постоянный режим отображения устанавливается указанный цвет;
- Если кнопка на пульте была нажата, то в зависимости от считанного значения выполняем одно из следующих действий:
- После этого следует блок режимов работы адресных светодиодов:
- В зависимости от значения переменной mode включается один из 11 режимов работы светодиодов:
- Для того, чтобы изменить скорость работы анимации (
mode= 1-4), достаточно изменить значение переменнойz; - Для того, чтобы светодиодам постоянно не назначался цвет, в скетч введён флаг flg_mode, который сбрасывается каждый раз после установки статичного цвета (
mode= 5-11);
- Для того, чтобы изменить скорость работы анимации (
- В зависимости от значения переменной mode включается один из 11 режимов работы светодиодов:

Обсуждение