Общие сведения:
В этом уроке мы создадим стильный светильник с управлением адресными светодиодами 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 режимов работы светодиодов:
Обсуждение