Подсветка лестницы на Ардуино

Автоматическая подсветка лестницы на Arduino с адресной лентой WS2812B — простой проект, который способен в лучшую сторону преобразить интерьер вашего дома. Наш вариант этого популярного DIY проекта отличается простой электрической схемой и программой (скетчем). Для автоматического включения лестничных светильников можно использовать датчики движения или ультразвуковые датчики расстояния.

В лестничных светильниках используется по два адресных светодиода ws2812b (это количество можно увеличить по желанию), поэтому для подсветки лесенки можно использовать блок питания на 5 Вольт с минимальной мощностью. Включателем можно задействовать «ночной режим» в котором лестничный марш будет всегда подсвечиваться с установленной яркостью, что смотрится очень эффектно.

Подсветка лестницы на Ардуино своими руками

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

  • Arduino Nano / Arduino Uno / Arduino Mega;
  • адресная лента WS2812B;
  • блок питания DC 5V;
  • датчик движения или расстояния;
  • включатель;
  • провода, припой, термоусадка и т.д.

В первом варианте проекта для индикации наличия движения используются HC-SR04 ультразвуковые датчики расстояния Ардуино. Далее размещена схема сборки умной лестницы — подключение адресной ленты и датчиков к плате Arduino Nano (можно использовать Arduino Uno) и рабочая прошивка для микроконтроллера. Библиотеки для работы программы можно скачать на странице — Библиотеки Ардуино.

Схема на Arduino и ws2812b для подсветки ступеней лестницы

Схема сборки подсветки лестницы на Arduino с датчиками расстояния с адресной лентой
Схема подсветки лестницы на Arduino с датчиками расстояния и адресной лентой

Все настройки, которые можно внести в скетч, даже без знаний основ программирования Arduino — расположены в начале программы. Но при изменении количества светодиодов, размещенных на одной ступени, в код потребуется внести небольшие правки. В этом случае, необходимо будет добавить или убавить строчки в циклах for — strip.setPixelColor(i + 1, strip.Color(j, j, j * 2));

Скетч. Подсветка лестницы на ws2812b с датчиком расстояния

#include "Ultrasonic.h"
#include "Adafruit_NeoPixel.h"

// === настройки, которые можно поменять === //

#define LESENKA 6    // количество ступеней на лесенке
#define LED 2             // количество светодиодов на одной ступени
#define PIN_LED 3     // пин для подключения адресной ленты
#define PIN_VKL 9     // пин для подключения переключателя

#define TIMER 5        // пауза для плавного включения/выключения
#define PAUSA 100    // пауза между включениями ступенек
#define BRIGHT 200  // максимальная яркость ленты
#define LIGHT 10       // минимальная яркость ленты
#define DIST1 50       // расстояние срабатывания 1 датчика
#define DIST2 50       // расстояние срабатывания 2 датчика

// === настройки, которые можно поменять === // 
 
Ultrasonic ultrasonic1 (15, 14);   // Trig - A1, Echo - A0
Ultrasonic ultrasonic2 (19, 18);   // Trig - A5, Echo - A4

int NUM_LED = LESENKA * LED;
Adafruit_NeoPixel strip (NUM_LED, PIN_LED, NEO_GRB + NEO_KHZ800);

int cm1, cm2, t, i, j, g, J;
byte w;

void setup() {
  strip.begin();                             // инициализируем объект NeoPixel
  strip.show();                              // отключаем все пиксели на ленте
  strip.setBrightness(BRIGHT);  // указываем яркость (максимум 255)
  Serial.begin(9600);
  pinMode (PIN_VKL, INPUT);  // инициализируем пин для включателя
}

// узнаем расстояние с 1 датчика
void u1() {
  for (byte i = 0; i <= 3; i++) {
    cm1 = ultrasonic1.Ranging(CM);
    cm1 = cm1 + cm1;
    delay(10);
  }
  cm1 = cm1 / 3;
  Serial.print("DIST1 - ");
  Serial.println(cm1);
}

// узнаем расстояние со 2 датчика
void u2() {
  for (byte i = 0; i <= 3; i++) {
    cm2 = ultrasonic2.Ranging(CM);
    cm2 = cm2 + cm2;
    delay(10);
  }
  cm2 = cm2 / 3;
  Serial.print("DIST2 - ");
  Serial.println(cm2);
}
 
void loop() {
 
  // если переключатель включен устанавливаем минимальную яркость ленты
  if (digitalRead(PIN_VKL) == HIGH) { J = 0; }
  if (digitalRead(PIN_VKL) == LOW) { J = LIGHT; }
 
  // включаем все ступени на лестнице с заданной яркостью
  for (i = 0; i <= NUM_LED; i++) {
    strip.setPixelColor(i, strip.Color(J, J, J * 2));
    strip.show();
  }
 
  // поочередно опрашиваем ультразвуковые датчики
  u1();
  delay(100);
  u2();
  delay(100);

  if (cm1 < DIST1) { w = 1; }  // если сработал первый датчик  -  заходим в 1 цикл
  if (cm2 < DIST2) { w = 2; }  // если сработал второй датчик  -  заходим во 2 цикл
 
  while (w == 1) { 
    // плавное включение адресной ленты на лестнице снизу-вверх
    for (i = 0; i <= NUM_LED + 1; i = i + LED) {
      for (j = J; j <= 125; j++) {
        strip.setPixelColor(i, strip.Color(j, j, j * 2));
        strip.setPixelColor(i + 1, strip.Color(j, j, j * 2));
        strip.show();
        delay(TIMER);
      }
      delay(PAUSA);
    }
    w = 5; // переход в пятый цикл для ожидания
  }
 
  while (w == 2) {
    // плавное включение адресной ленты на лестнице сверху-вниз
    for (i = NUM_LED + 1; i >= 0; i = i - LED) {
      for (j = J; j <= 160; j++) {
        strip.setPixelColor(i, strip.Color(j, j, j * 2));
        strip.setPixelColor(i - 1, strip.Color(j, j, j * 2));
        strip.show();
        delay(TIMER);
      }
      delay(PAUSA);
    }
    w = 5; // переход в пятый цикл для ожидания
  }
 
  while (w == 5) {
    // плавное затухание подсветки лестницы на адресной ленте
    for (j = 124; j >= J; j = j - 2) {
      for (i = 0; i <= NUM_LED; i++) {
        strip.setPixelColor(i, strip.Color(j, j, j * 2 ));
        strip.show();
      }
 
      // поочередно опрашиваем ультразвуковые датчики
      u1();
      delay(j / 4);
      u2();
      delay(j / 4);
      
      // если сработал один из датчиков - переходим в соответствующий цикл
      if (cm1 < DIST1) { w = 3; goto w3; }
      if (cm2 < DIST2) { w = 4; goto w4; }
    }
    w = 0; // если ни один из датчиков не сработал выходим из цикла
  }

  while (w == 3) {
w3:
    t = map (j, 10, 125, 20, 0);
    // плавное выключение подсветки лестницы снизу-вверх
    for (i = 0; i <= NUM_LED + 1; i = i + LED) {
      for (g = j; g >= J; g--) {
        strip.setPixelColor(i, strip.Color(g, g, g * 2));
        strip.setPixelColor(i + 1, strip.Color(g, g, g * 2));
        strip.show();
        delay(TIMER + t / 2);
      }
      delay(PAUSA);
    }
    w = 0; // выходим из цикла в начало программы
  }

  while (w == 4) {
w4:
    t = map (j, 10, 125, 20, 0);
    // плавное выключение подсветки лестницы сверху-вниз
    for (i = NUM_LED + 1; i >= 0; i = i - LED) {
      for (g = j; g >= J; g--) {
        strip.setPixelColor(i, strip.Color(g, g, g * 2));
        strip.setPixelColor(i - 1, strip.Color(g, g, g * 2));
        strip.show();
        delay(TIMER + t / 2);
      }
      delay(PAUSA);
    }
    w = 0; // выходим из цикла в начало программы
  }

}

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

  1. в начале программы можно указать количество ступеней в лестнице, скорость включения «умной» подсветки и задать минимальную яркость освещения;
  2. оттенок свечения адресной ленты можно также указать свою, по умолчанию стоит голубоватый цвет для автоматической подсветки лестницы;
  3. лучше всего использовать в схеме ультразвуковые датчики, так как, в отличие от датчиков движения, можно самому указать расстояние для срабатывания подсветки и производить сразу несколько измерений для исключения ошибки.



Схема подсветки лестницы на Arduino с датчиками движения и адресной лентой
Схема подсветки лестницы на Arduino с датчиками движения и адресной лентой

Скетч. Подсветка лестницы на ws2812b с датчиком движения

#include "Adafruit_NeoPixel.h"
 
// === настройки, которые можно поменять === //

#define LESENKA 6     // количество ступеней на лесенке
#define LED 2              // количество светодиодов на одной ступени
#define PIN_LED 3      // пин для подключения адресной ленты
#define PIN_VKL 9      // пин для подключения переключателя
#define PIN_PIR1 15    // пин для подключения 1 датчика движения
#define PIN_PIR2 19    // пин для подключения 2 датчика движения

#define TIMER 5         // пауза для плавного включения/выключения
#define PAUSA 100    // пауза между включениями ступенек
#define BRIGHT 200  // максимальная яркость ленты
#define LIGHT 10       // минимальная яркость ленты
 
// === настройки, которые можно поменять === //

int NUM_LED = LESENKA * LED;
Adafruit_NeoPixel strip (NUM_LED, PIN_LED, NEO_GRB + NEO_KHZ800);

int t, i, j, g, J;
byte w;

void setup() {
  strip.begin();                            // инициализируем объект NeoPixel
  strip.show();                           // отключаем все пиксели на ленте
  strip.setBrightness(BRIGHT);  // указываем яркость (максимум 255)

  pinMode (PIN_VKL, INPUT);   // инициализируем пин для включателя
  pinMode (PIN_PIR1, INPUT);  // инициализируем пин для датчика движения
  pinMode (PIN_PIR2, INPUT);  // инициализируем пин для датчика движения
}

void loop() {

  // если переключатель включен устанавливаем минимальную яркость ленты
  if (digitalRead(PIN_VKL) == HIGH) { J = 0; }
  if (digitalRead(PIN_VKL) == LOW) { J = LIGHT; }

  // включаем все ступени на лестнице с заданной яркостью
  for (i = 0; i <= NUM_LED; i++) {
    strip.setPixelColor(i, strip.Color(J, J, J * 2));
    strip.show();
  }
  
  // поочередно опрашиваем датчики движения
  if (digitalRead(PIN_PIR1) == HIGH) { w = 1; }
  delay(100);
  if (digitalRead(PIN_PIR2) == HIGH) { w = 2; }
  delay(100);

  while (w == 1) {
    // плавное включение адресной ленты на лестнице снизу-вверх
    for (i = 0; i <= NUM_LED + 1; i = i + LED) {
      for (j = J; j <= 125; j++) {
        strip.setPixelColor(i, strip.Color(j, j, j * 2));
        strip.setPixelColor(i + 1, strip.Color(j, j, j * 2));
        strip.show();
        delay(TIMER);
      }
      delay(PAUSA);
    }
    w = 5; // переход в пятый цикл для ожидания
  }

while (w == 2) {
    // плавное включение адресной ленты на лестнице сверху-вниз
    for (i = NUM_LED + 1; i >= 0; i = i - LED) {
      for (j = J; j <= 160; j++) {
        strip.setPixelColor(i, strip.Color(j, j, j * 2));
        strip.setPixelColor(i - 1, strip.Color(j, j, j * 2));
        strip.show();
        delay(TIMER);
      }
      delay(PAUSA);
    }
    w = 5; // переход в пятый цикл для ожидания
  }

while (w == 5) { for (j = 124; j >= J; j--) {
    // плавное выключение подсветки лестницы на адресной ленте
      for (i = 0; i <= NUM_LED; i++) {
        strip.setPixelColor(i, strip.Color(j, j, j * 2 ));
        strip.show();
      }
      
      // поочередно опрашиваем датчики движения
      if (digitalRead(PIN_PIR1) == HIGH) { w = 3; goto w3; }
      delay(TIMER + j / 2);
      if (digitalRead(PIN_PIR2) == HIGH) { w = 4; goto w4; }
      delay(TIMER + j / 2);
    }
    w = 0; // если ни один из датчиков не сработал выходим из цикла
  }

  while (w == 3) {
w3:
    t = map (j, 10, 125, 20, 0);
 
    // плавное выключение подсветки лестницы на Ардуино снизу-вверх
    for (i = 0; i <= NUM_LED + 1; i = i + LED) {
      for (g = j; g >= J; g--) {
        strip.setPixelColor(i, strip.Color(g, g, g * 2));
        strip.setPixelColor(i + 1, strip.Color(g, g, g * 2));
        strip.show();
        delay(TIMER + t / 2);
      }
      delay(PAUSA);
    }
    w = 0; // выходим из цикла в начало программы
  }

  while (w == 4) {
w4:
    t = map (j, 10, 125, 20, 0);
 
    // плавное выключение подсветки лестницы на Ардуино сверху-вниз
    for (i = NUM_LED + 1; i >= 0; i = i - LED) {
      for (g = j; g >= J; g--) {
        strip.setPixelColor(i, strip.Color(g, g, g * 2));
        strip.setPixelColor(i - 1, strip.Color(g, g, g * 2));
        strip.show();
        delay(TIMER + t / 2);
      }
      delay(PAUSA);
    }
    w = 0; // выходим из цикла в начало программы
  }

}

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

  1. радиус срабатывания PIR датчиков движения HC-SR501 программно изменить нельзя, в отличие от ультразвуковых датчиков движения;
  2. датчики движения можно заменить датчиками препятствия (KY-032 Arduino), при этом схема сборки и прошивка микроконтроллера не изменится.

Заключение. Для создания «умной» подсветки лестницы своими руками на Ардуино существует множество вариантов исполнения. В нашем случае большинство настроек задается только в программе, что значительно упрощает схему сборки и прошивку DIY проекта, а менять с помощью тактовых кнопок цвет или вообще превратить подсветку лестницы в новогоднюю гирлянду на ws2812b Ардуино нам показалось не уместно.



16 Replies to “Умная подсветка лестницы своими руками”

  1. Менять цвет это конечно чушь, а во управлять подсветкой с помощью кнопок пд ступеньками это актуально, так как все ходят с разной скоростью.

  2. Спасибо.
    Скажите пожалуйста, а сколько максимально пикселей потянет эта система?

  3. Здравствуйте. Можете помочь. Собрал по схеме с датчиком растояния. скачал библиотеку Uktrasonic но выводит ошибку и подчеркивает вот эту строчку красным cm1 = ultrasonic1.Ranging(CM);

    1. Скорее всего у вас библиотека Ultrasonic.h стоит другая.
      Попробуйте заменить эту команду на cm1 = ultrasonic1.read();
      Или посмотрите из примеров в библиотеке, как получать информацию с УЗ датчиков

  4. Здравствуйте. Как изменить скорость включения ступеней? На #define PAUSA 100 // пауза между включениями ступенек, не реагирует.

    1. PAUSA — это пауза между включениями ступенек, а не скорость включения.
      Попробуйте изменить в этом месте:
      for (j = J; j <= 160; j = j + 5)

  5. Здравствуйте. а как подключить ленту ws 2811 ? нужно что то менять? там же чип на 3 светодиода

  6. Здравствуйте.помогите пожалуйста! Что нужно добавить или убавить чтобы загорались 8 светодиодов на ступени?

  7. Здравствуйте. Выдает такую ошибку:
    C:\Users\User\Documents\Arduino\sketch_feb11a\sketch_feb11a.ino: In function ‘void u1()’:
    C:\Users\User\Documents\Arduino\sketch_feb11a\sketch_feb11a.ino:40:23: error: expected unqualified-id before ‘;’ token
    cm1 = ultrasonic1.;

    Несколько библиотек найдено для «Ultrasonic.h»

    Библиотеки скачали, как решить эту проблему?

    1. 1 — cm1 = ultrasonic1.;

      2 — Несколько библиотек найдено для «Ultrasonic.h»

      Все же написано!

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

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

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