Главная chevron_right Наши уроки chevron_right Arduino chevron_right Светильник Бэтмен на базе Arduino

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

Собираем декоративный светильник в стиле Бэтмена на Arduino с адресными светодиодами NeoPixel. Управление яркостью и режимами — через ИК-пульт и энкодер с памятью

Видео-обложка запускается при наведении

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

В этом уроке мы создадим стильный светильник с управлением адресными светодиодами 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);

Ссылки:

Комплект для повторения проекта

Что понадобится

Это быстрый ориентир по основным модулям и деталям. Полный список для повторения проекта смотрите в самой статье.

13 позиций
NeoPixel (Trema-модуль) Модуль с четырьмя адресными RGB светодиодами, их «адресность» позволяет управлять цветом каждого светодиода Открыть в iArduino Arduino Pro Mini (Без ног / 5 В / 16 МГц) Миниатюрная платформа c микроконтроллером ATmega328P на ядре AVR с рабочим напряжением 5 В для разработки электронных устройств на языке C++ Открыть в iArduino Piranha Pro Mini (С ногами) Прямой аналог Arduino Pro Mini c микроконтроллером ATmega328P на ядре AVR для разработки электронных устройств на языке C++ Открыть в iArduino Piranha Pro Mini (Без ног) Прямой аналог Arduino Pro Mini c микроконтроллером ATmega328P на ядре AVR для разработки электронных устройств на языке C++ Открыть в iArduino Преобразователь интерфейсов USB-UART (CP2102 / USB Type-A) Конвертер сигналов на чипе CP2102 для прошивки и отладки контроллеров без собственного USB Открыть в iArduino Энкодер с эффектом памяти (Trema-модуль) Определять угол поворота вала, его направление и нажатие на вал. В отличие от обычных энкодеров, данный модуль сам определяет факт и направление каждого шага поворота вала Открыть в iArduino ИК-приёмник (Trema-модуль) Управление проектами на расстоянии с помощью обычного ИК-пульта от телевизора или другой техники Открыть в iArduino i2C Hub Будет полезен в проектах с большим количеством устройств с интерфейсом I2C Открыть в iArduino Соединительные силиконовые провода «мама-мама» (20 шт. / 20 см) Пучок из 20 мягких силиконовых проводов «мама-мама» длиной 20 см для прототипирования электронных устройств Открыть в iArduino Источник питания на 5В. 2А. Источник питания 5 вольт, 2 ампера, центр положительный, DC jack 5,5*2,5 мм Открыть в iArduino Стойка нейлоновая чёрная «папа-мама» М3 / 20 мм (4 шт.) Комплект из четырёх нейлоновых чёрных стоек длиной 20 мм с наружной и внутренней резьбой М3 Открыть в iArduino Стойка нейлоновая чёрная «папа-мама» М3 / 8 мм (4 шт.) Комплект из четырёх нейлоновых чёрных стоек длиной 8 мм с наружной и внутренней резьбой М3 Открыть в iArduino Винт нейлоновый чёрный М3×8 (4 шт.) Комплект из четырёх нейлоновых чёрных винтов с резьбой М3 и длиной ножки 8 мм Открыть в iArduino
Все уроки Arduino