Умная подсветка комнаты на Ардуино

Проект на адресной светодиодной ленте для создания умной подсветки комнаты, коридора или кухни с датчиком движения и возможностью настройки (цвета, яркости и световых эффектов) с помощью пульта ДУ. Все настройки сохраняются в энергонезависимой памяти eeprom Arduino. На этой странице представлена схема сборки умной подсветки и приведена рабочая программа для платы Ардуино.

С помощью ИК пульта в программе предусмотрена дистанционная настройка цвета адресной ленты (все цвета можно настроить отдельно), яркость освещения и выбор эффекта при срабатывании датчика движения. В самом скетче есть возможность настройки периода времени, после которого лента будет выключаться при отсутствии движения в помещении, а также скорости включения визуальных эффектов.

Подсветка на ws2812 с ИК пультом и датчиком движения

Для этого проекта потребуется:

  • Arduino Uno / Arduino Nano;
  • адресная лента ws2812 / ws2811;
  • датчик движения HCSR04;
  • ИК приемник и пульт ДУ;
  • источник питания 5В или 12В;
  • резистор 220 Ом, провода.

Схема сборки данного проекта представлена на картинке ниже, обратите внимание, что для ленты ws2811 потребуется источник питания 12 Вольт, а для ленты ws2812 или ws2815 блок питания на 5 Вольт. Схема подключения адресной ленты и Ардуино при этом остается неизменной. Так же необходимо, чтобы в адресной ленте было четное количество светодиодов для симметричности включения световых эффектов.

Сборка подсветки для ванной комнаты на Ардуино

Схема умной подсветки комнаты на Ардуино
Схема умной подсветки комнаты, кухни или ванной на Ардуино

Для создания эффектов на ws2811 используется библиотека Adafruit_NeoPixel.h, для ИК пульта необходима библиотека IRremote.h, а для записи настроек в память eeprom необходима библиотека EEPROM.h — скачать библиотеки можно здесь. После сборки электрической схемы умной подсветки в комнате на Arduino и ws2812, установите необходимые библиотеки и загрузите следующую программу в плату.

Скетч. Подсветка комнаты или кухни на Ардуино

#include "EEPROM.h"
#include "IRremote.h"
#include "Adafruit_NeoPixel.h"

// пины подключения ИК приемника, адресной ленты, датчика
#define IR_PIN    2
#define LED_PIN 7
#define PIR_PIN  A1

int PIX = 119; // количество светодиодов в ленте (120 шт)
int TIME = 1;  // через сколько минут отключать подсветку

// коды от кнопок ИК пульта
#define ENT 16726215   // ok - вход в настройки
#define RGT 16734885   // -> - увеличить задержку
#define LFT 16716015    // <- - уменьшить задержку
#define TOP 16718055   // увеличить яркость
#define BOT 16730805   // уменьшить яркость
#define EF1 16753245   // 1 - первый эффект
#define EF2 16736925   // 2 - второй эффект
#define EF3 16769565   // 3 - третий эффект
#define RED 16769055  // 7 - настройка красного цвета
#define GRN 16754775  // 8 - настройка зеленого цвета
#define BLU 16748655   // 9 - настройка синего цвета
#define UPD 16756815  // # - сохранить настройки

int pix_l_start = 0;
int pix_l_finis = PIX / 2;
int pix_r_start = PIX / 2;
int pix_r_finis = PIX;
int brg, del, p, x, i, j, e, w;
byte r, g, b;
unsigned long timer;
unsigned long t = t * 60 * 1000;

IRrecv irrecv(IR_PIN);
decode_results results;
Adafruit_NeoPixel strip (PIX, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  // считываем информацию из энергонезависимой памяти
  r = EEPROM.read(1);      // значение красного цвета
  g = EEPROM.read(2);      // значение зеленого цвета
  b = EEPROM.read(3);     // значение синего цвета
  brg = EEPROM.read(4);  // значение яркости ленты
  del = EEPROM.read(5);  // значение скорости эффектов
  e = EEPROM.read(6);     // номер эффекта при включении

  Serial.begin(9600);
  irrecv.enableIRIn();
  strip.begin();
  strip.setBrightness(brg);
  strip.clear();
  pinMode(IR_PIN, INPUT);
  pinMode(PIR_PIN, INPUT);
}

void loop() {
  p = digitalRead(A1);
  delay(100);

  // если есть движение включаем подсветку с эффектом
  if (p == HIGH && x == 0) { effect(e); svet(); x = 1; }
  // если нет движения включаем счетчик
  if (p == LOW && x == 1) { timer = millis(); x = 2; }
  // если движения не было, то выключаем подсветку
  if (p == LOW && x == 2 && millis() - timer > t) { timer = millis(); vykluchenie(); x = 0; }
  // если движение появилось отключаем отсчет времени
  if (p == HIGH && x == 2) { x = 1; }

  // выводим сигнал с ик пульта на монитор порта
  if (irrecv.decode(&results)) {
    Serial.println(results.value);
    // если пришел сигнал ENT - переходим в режим настройки
    if (results.value == ENT) { demo(); w = 1; }
    irrecv.resume();
  }

  while (w == 1) {
    // выводим сигнал с ик пульта на монитор порта
    if (irrecv.decode(&results)) {
      Serial.println(results.value);
 
      // выбор эффекта включения подсветки с демонстрацией
      if (results.value == EF1) { e = 1; effect(e); strip.clear(); }
      if (results.value == EF2) { e = 2; effect(e); strip.clear(); }
      if (results.value == EF3) { e = 3; effect(e); strip.clear(); }
 
      // настройка яркости подсветки
      if (results.value == TOP) { brg = brg + 60; if (brg > 240) { brg = 240; } }
      if (results.value == BOT) { brg = brg - 60; if (brg < 60) { brg = 60; } }
 
      // настройка скорости включения подсветки с демонстрацией
      if (results.value == LFT) {
        del = del - 10; if (del < 0) { del = 0; } effect(e); strip.clear(); }
      if (results.value == RGT) {
        del = del + 10; if (del > 50) { del = 50; } effect(e); strip.clear(); }
 
      // настройка цвета подсветки
      if (results.value == RED) { r = r + 60; if (r > 240 || r < 60) { r = 0; } }
      if (results.value == GRN) { g = g + 60; if (g > 240 || g < 60) { g = 0; } }
      if (results.value == BLU) { b = b + 60; if (b > 240 || b < 60) { b = 0; } }
 
      // при нажатии на кнопку UPD - сохраняем настройки в eeprom
      if (results.value == UPD) {
        delay(1); EEPROM.update(1, r);
        delay(1); EEPROM.update(2, g);
        delay(1); EEPROM.update(3, b);
        delay(1); EEPROM.update(4, brg);
        delay(1); EEPROM.update(5, del);
        delay(1); EEPROM.update(6, e);
        delay(1); effect(e);
      }
 
      // выход из режима настройки
      if (results.value == ENT) { effect(e); strip.clear(); w = 0; }
      demo();
      irrecv.resume();
    }
  }
}
 
// включение подсветки в режиме настройки
void demo() {
  strip.clear();
  strip.setBrightness(brg);
  for (i = 0; i < PIX; i = i + 2) {
    strip.setPixelColor(i, strip.Color(r, g, b));
    strip.show();
  }
}
 
// основной режим подсветки
void svet() {
  strip.setBrightness(brg);
  for (i = 0; i < PIX; i++) {
    strip.setPixelColor(i, strip.Color(r, g, b));
    strip.show();
  } 
}
 
// плавное выключение подсветки
void vykluchenie() {
  for ( j = brg; j >= 0; j = j - 20) {
    strip.setBrightness(j);
    for ( i = pix_l_start; i <= pix_r_finis; i++) {
      strip.setPixelColor(i, strip.Color(r, g, b));
      strip.show();
    }
  }
}

// включение эффекта (зависит от переменной 'e')
void effect(int e) {
  // вывод на монитор порта значений всех настроек подсветки
  // Serial.print("r - "); Serial.println(r);
  // Serial.print("g - "); Serial.println(g);
  // Serial.print("b - "); Serial.println(b);
  // Serial.print("e - "); Serial.println(e);
  // Serial.print("brg - "); Serial.println(brg);
  // Serial.print("del - "); Serial.println(del);
  // Serial.println("");
  strip.clear();
  strip.setBrightness(brg);

  // включение подсветки с первым эффектом
  while (e == 1) {
    j = 0;
    for (i = pix_r_start; i <= pix_r_finis; i++) {
      j++;
      strip.setPixelColor(i, r / 3, g / 3, b / 3);
      strip.setPixelColor(pix_l_finis - j, r / 3, g / 3, b / 3);
      strip.show();
      delay(del);
      }
    j = 0;
    for ( i = pix_r_finis; i >= pix_r_start; i--) {
      j++;       
      strip.setPixelColor(i, r / 2, g / 2, b / 2);
      strip.setPixelColor(i + 1,  r / 2, g / 2, b / 2);
      strip.setPixelColor(i + 2,  r / 2, g / 2, b / 2);
      strip.setPixelColor(i + 3,  r / 3, g / 3, b / 3);
      strip.setPixelColor(pix_l_start + j, r / 2, g / 2, b / 2);
      strip.setPixelColor(pix_l_start + j - 1,  r / 2, g / 2, b / 2);
      strip.setPixelColor(pix_l_start + j - 2,  r / 2, g / 2, b / 2);
      strip.setPixelColor(pix_l_start + j - 3,  r / 3, g / 3, b / 3);
      strip.show();
      delay(del);
      }
    j = 0;
    for (i = pix_r_start; i <= pix_r_finis; i++) {
      j++;
      strip.setPixelColor(i, r, g, b);
      strip.setPixelColor(pix_l_finis - j, r, g, b);
      strip.show();
      delay(del);
      }
    break;
  }

  // включение подсветки со вторым эффектом
  while (e == 2) {
    pix_l_finis = PIX / 2;
    while (pix_l_finis > 0) {
      j = 0;
      for ( i = pix_l_start; i <= pix_l_finis; i++) {
        j++;
        strip.setPixelColor(i, r / 2, g / 2, b / 2);
        strip.setPixelColor(i - 1,  r / 2, g / 2, b / 2);
        strip.setPixelColor(i - 2,  r / 2, g / 2, b / 2);
        strip.setPixelColor(i - 3,  0, 0, 0);
        strip.setPixelColor(pix_r_finis - j, r / 2, g / 2, b / 2);
        strip.setPixelColor(pix_r_finis - j + 1, r / 2, g / 2, b / 2);
        strip.setPixelColor(pix_r_finis - j + 2, r / 2, g / 2, b / 2);
        strip.setPixelColor(pix_r_finis - j + 3, 0, 0, 0);
        strip.show();
        delay(del / 10);
      }
      pix_l_finis = pix_l_finis - 3;
    }
    pix_l_finis = PIX / 2;
    j = 0;
    for (i = pix_r_start; i <= pix_r_finis; i++) {
      j++;
      strip.setPixelColor(i, r, g, b);
      strip.setPixelColor(pix_l_finis - j, r, g, b);
      strip.show();
      delay(del / 2);
    }
  break;
  }
 
  // включение ленты с третьим эффектом
  while (e == 3) {
    j = 0;
    for ( j = 0; j <= brg; j = j + 20) {
      strip.setBrightness(j);
      for ( i = pix_l_start; i <= pix_r_finis; i++) {
        strip.setPixelColor(i, strip.Color(r, g, b));
        strip.show();
      }
    }
    break;
  }
}
 

Пояснения к коду:

  1. после загрузки программы необходимо указать коды от кнопок пульта ДУ — они будут выводиться на мониторе порта Arduino IDE;
  2. также необходимо указать в скетче количество светодиодов в ленте (желательно использовать четное количество светодиодов в подсветке).



Заключение. После первой загрузки программы световые эффекты и цвет ленты будет отображаться некорректно, так как информация с настройками берется из EEPROM Arduino — по умолчанию в ячейках энергонезависимой памяти хранится число 250. Соответственно все переменные будут равны 250 при первой загрузке программы, чтобы это исправить сохраните свои настройки, при помощи ик пульта.



Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.