Светильник Бэтмен на базе Arduino

Общие сведения:

В этом уроке мы создадим стильный светильник с управлением адресными светодиодами NeoPixel с помощью ИК-пульта и/или энкодера с памятью, выполненный в стиле атрибутики известного супергероя.

Светильник поддерживает смену режимов, а так же изменение уровня яркости светодиодов.

Видео:

Нам понадобится:

    Для реализации проекта необходимо установить библиотеки:

    • 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);

    Ссылки:

    Обсуждение