Ночник с выключением по расписанию

image

С рождением ребёнка встал вопрос о ночнике. Где-то прочитали, что он необходим для спокойного сна. Быстро привыкли спать с тусклым светом. Очень удобно просыпаться от криков и воев среди ночи и видеть на что жалуется малыш (если удастся понять). Так же при тусклом свете можно укачать, перевернуть и продолжить спать.

Вначале был изготовлен тестовый образец светильника из куска жёлтой светодиодной ленты (12 вольт), который использовался 1,5 года.


image

Помимо хлипкости конструкции стало раздражать каждое утро вынимать блок питания светильника из розетки. Встаю я утром, с улицы в комнату поступает достаточно света. Таким образом, светильник работает впустую несколько часов каждый день. Ещё раз в пол года китайский контроллер RGB ленты забывал текущую настройку и нужно было искать пульт управления чтобы напомнить ему как нужно работать. Решил сделать новый светильник с автоматическим отключением, с регулировкой цвета как с помощью потенциометров, так и по радио.

Быстро собрал прототип на базе arduino nano. Отладил базовую функциональность.

image

Пользуясь случаем попробовал Fritzing. Не понравилось, но картинки получаются наглядные и «весёлые». Как видно ничего нового не изобрёл.

image

Заменил “nano” на малоизвестный, ардуино-совместимый модуль с встроенным радио приёмо-передатчиком (контроллер 8-ми битный, производительность и нафаршерованность сравнима с «наной»). Дома у меня уже есть одно устройство работающее на частоте 868 МГц, это будет второе. Краткие характеристики с сайта производителя:

Краткие характеристики
image


image

Не вижу больших проблем сделать тоже самое на ESP8266 (есть удобный онлайн сборщик прошивок для скриптов на LUA). Немного сложнее на Bluetooth (для перепрошивки модуля HM-10 нужен недорогой программатор, среда для разработки и понимание протокола). Хотя можно использовать Bluetooth модуль вместе с ардуиной. Но я использовал ZUNo, потому что уже давно лежит и ждёт меня, а также готова вся инфраструктура по соединению и управлению подобными устройствами в одну сеть (я про контроллер сети умного дома).
Для всех используемых ножек на ардуино нашлись аналоги в модуле.

image

Чтобы работать с модулем из Arduino IDE нужно её настроить (описание настройки есть на сайте производителя). Чуда не произошло. При попытке компиляции получил ошибку “doesn't support «for» statement with empty columns or without body!”. Я использовал библиотеку Adafruit_NeoPixel. Залез в неё увидел сколько в ней циклов и закрыл. Пришлось опять идти на сайт производителя и искать в примерах работу со светодиодами (пример быстро нашёлся). Значит, я не первый, кто столкнулся с подобной проблемой.

Чтобы данный светильник управлялся по радио в код ардуино нужно добавить макрос и реализовать несколько функций:

ZUNO_SETUP_CHANNELS(
      ZUNO_SWITCH_MULTILEVEL(getRed, setRed),
      ZUNO_SWITCH_MULTILEVEL(getGreen, setGreen),
      ZUNO_SWITCH_MULTILEVEL(getBlue, setBlue),
      ZUNO_SWITCH_BINARY(switch_getter, switch_setter)
);

Данный макрос описывает устройство Z-Wave c тремя многоуровневыми переключателями (управление RGB) и одним простым переключателем (простое включение/выключение).

Реализация функций у меня простейшая (как в примерах на сайте производителя). Посмотреть можно в прикреплённом листинге.

Подбор корпуса


Корпус у меня уже был. Герметичный с прозрачной крышкой. Под крышкой поместилось 25 светодиодов. Испытания прошли успешно. Светильник имеет большой запас по яркости, для моей комнаты. Крышка у данного корпуса прозрачная, поэтому решил немного рассеять свет.

image

Набросал цветных бусинок и акриловых кубиков, залил прозрачной эпоксидкой. Краска с цветных бусинок под воздействием смолы растворилась.

image

Самое интересное, что крышка от герметичного корпуса протекла и почти вся смола вытекла. Не знаю где я успел ударить крышку, но после высыхания трещина отчётливо видна.

image

Печатную плату изготовил фоторезистивным методом.

image

image

После травления и механической обработки

image

Модуль с микроконтроллером заменил на его прототип, валявшийся в шкафу (потому что не жалко, а ZUNo нужно беречь). Первая версия ZUNo, но габариты больше и хуже антенна, да и не купишь уже. Испытания прошли более-менее успешно. Последний сегмент пришлось перепаять. Изначально был впаян не той стороной. И скорректировать количество светодиодов в прошивке.

image

image

Вот что получилось:

image

Управление по радио


Главное окно с каналами управления светильника

image

Настройка яркости одного канала светодиодной ленты

image

Настройка утреннего отключения ночника

image

Заключение


Устройство работает. Оно компактное и аккуратное. Питается от зарядки мобильного телефона.
Из замеченных проблем:

  • во время сборки оторвал часть дорожек на переменных резисторах, поэтому в ручном режиме можно управлять только одним каналом.
  • из 25 светодиодов нормально работают только 20. Мне и этого много, поэтому, скорее всего, оставлю до выявления более серьёзных недостатков

Скетч ночника
#include "ZUNO_NeoPixel.h"

#define MAX_PIXELS 20 // NB! Z-Uno can not control more than 25 WS2811 without harming RF communications
#define PIXEL_SIZE 3  // Three colors per pixel
#define BUFF_SIZE (MAX_PIXELS * PIXEL_SIZE)

byte pixel_buff[BUFF_SIZE];

NeoPixel pixels(pixel_buff, BUFF_SIZE);

#define B_PRESSED 1
#define BUTTON_PIN   1    // Digital IO pin connected to the button.  This will be

#define DEF_RED 30
#define DEF_GREEN 20

byte red = DEF_RED;
byte green = DEF_GREEN;
byte blue = 0;

#define POWER_ON 1
#define POWER_OFF 0
byte light_power = POWER_ON;
byte last_light_power = POWER_OFF;


ZUNO_SETUP_CHANNELS(
      ZUNO_SWITCH_MULTILEVEL(getRed, setRed),
      ZUNO_SWITCH_MULTILEVEL(getGreen, setGreen),
      ZUNO_SWITCH_MULTILEVEL(getBlue, setBlue),
      ZUNO_SWITCH_BINARY(switch_getter, switch_setter)
);


void switch_setter(byte value) 
{
  Serial.println("switch");
  Serial.print("value= ");
  Serial.println(value);
  if(value > 1)
    light_power = POWER_ON;
  else
    light_power = POWER_OFF;
}

byte switch_getter() 
{
  return light_power;
}

int getRed() {
  return red/2.56;
}

int getGreen() {
  return green/2.56;
}

int getBlue() {
  return blue/2.56;
}

void setRed(byte value) {
  red = value * 2,56;
  for(uint8_t i = 0; i < MAX_PIXELS; i++) 
    pixels.setPixelColor(i, pixels.Color(red, green, blue)); 
  pixels.show();
  Serial.print("set red = ");
  Serial.println(value);
}

void setGreen(byte value) {
  green = value * 2,56;
  for(uint8_t i = 0; i < MAX_PIXELS; i++) 
    pixels.setPixelColor(i, pixels.Color(red, green, blue)); 
  pixels.show();
  Serial.print("set red = ");
  Serial.println(value);
}

void setBlue(byte value) {
  blue = value * 2,56;
  for(uint8_t i = 0; i < MAX_PIXELS; i++) 
    pixels.setPixelColor(i, pixels.Color(red, green, blue)); 
  pixels.show();
  Serial.print("set red = ");
  Serial.println(value);
}

void set_LEDS()
{
   for(uint8_t i = 0; i < MAX_PIXELS; i++) 
    pixels.setPixelColor(i, pixels.Color(red, green, blue)); 
   pixels.show();
}

void read_resistors()
{
  red = (analogRead(A0) >> 2) & 0xff;
  green = (analogRead(A1) >> 2) & 0xff;
  blue =  (analogRead(A3) >> 2) & 0xff;
  Serial.print(red);
  Serial.print(" ");
  Serial.print(green);
  Serial.print(" ");
  Serial.print(blue);
  Serial.print(" ");
  Serial.println();
  set_LEDS();
}

#define DEBOUNCE_ACK 10
byte check_button()
{
  static bool oldState = HIGH;
  byte debounce_cnt = 0;
  static byte ret = 0;
  if(digitalRead(BUTTON_PIN) == LOW)
  {
    if(ret != B_PRESSED)
      while(digitalRead(BUTTON_PIN) == LOW)
      {
        if(debounce_cnt == DEBOUNCE_ACK)
        {
          ret = B_PRESSED;
          break;
        }
        else
          debounce_cnt++;
       delay(10);
      } 
  }
  else
  {
    debounce_cnt = 0;
    ret = 0;
  }
    
  return ret;
}

void setup() {
  Serial.begin(9600);
  pixels.begin();
  pixels.clear();
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  
}


void loop() 
{
  if(check_button() == B_PRESSED)
    read_resistors();
  if(last_light_power != light_power)
  {
    Serial.println("set power");
    if(light_power == POWER_OFF)
    {
      Serial.println("power off");
      red = 0;
      green = 0;
      blue = 0;
    }
    else
    {
      Serial.println("power on");
      red = DEF_RED;
      green = DEF_GREEN;
      blue = 0;
    }
    set_LEDS();
    last_light_power = light_power;
  }  
}

Share post

Similar posts

Comments 17

    +2
    Понятное дело, что это больше развлекательный проект, и хорошо, что хоть с какой-то целью, но как по мне, полученный результат не стоит и одной десятой затраченных усилий.
      0
      Согласен, RGB-лампа с али на пульте, любой примитивный светильник и розетка с таймером спасут отца российской демократии.
        +3
        коли на то пошло, алиэкспресс — главный враг радиолюбительского хобби — там можно найти 99% всего того, что только может прийти в голову.

        Это хобби, где процесс важнее результата. Покупка RGB лампы на али удовольствия не приносит.
          0

          А с энкодерами можно было бы сделать более точную ностройку яркости.

            0
            Можно поставить энкодеры с другой стороны для точной настройки, а резисторы оставить для грубой ). Но сейчас использую этот ночник как ночник, и ничего настраивать во время сна не хочется. А если одеть пластмассовые ручки и использовать как игрушку меняющую цвета, то можно и ещё пару кнопок добавить с интересными эффектами. А если пищалку…
            0
            На алиэкспресс можно найти 99% всего того, что только может прийти в голову 99% людей — если быть точнее.
            0

            Даже таймер в этом устройстве лишний. Датчик движения, возможно, пригодился бы.
            RGB подсветка в устройстве, которое, в основном никто не видит, тоже лишняя.
            А так да, куда же без микроконтроллера.

              0
              Поясните, пожалуйста, про датчик движения. Чьи движения нужно отслеживать? Таймера там и так нет. По идее он должен отключаться за пару часов до моего пробуждения, когда на улице становится светло. Сейчас это реализовано через контроллер умного дома, в будущем хочу сделать датчик освещённости. RGB подсветка, это основная функция ночника.
                0

                Ну, не знаю… мне кажется, основная функция ночника — не мешать спать, и, если уж проснулся — давать достаточно света, чтобы не наступить куда не нужно. Остальное — косметика. Против отключения по таймеру, астрономическим часам и по любой другой магии ничего против не имею… но если отключить утром вручную — это ведь никого не затруднит? ;)
                Датчик движения. — имел в виду следующее: встал из кровати — зажёгся ночник. Это может быть удобно.

                  0
                  Знаю нескольких людей, которые пытались поставить в спальне датчики движения на свет. В результате, чтобы уснуть им пришлось отключить их, потому что они всё время включали свет. А статью начинал со слов, что надоело вручную вынимать штекер из розетки)
                    0
                    ;)
                    Мы с ребенком нарукожопили построили подобную конструкцию. Только банка покрашена ребенком под ананас, а я врезал в крышку выключатель — так была решена проблема вынимания из розетки.
                    Самодельные светильники — это все равно что елку наряжать, любая безопасная конструкция годится.
            +3
            В любом случае автор заслуживает поощрительных комментариев, а то тут последнее время статьи все больше в стиле «компания XYZ обошла конкурентов уменьшив время зарада аккумулятора на NN cекунд».
            0
            Смысл таких петель в разводке не понятен.
            С фоторезистом такая куча перемычек — это надо суметь. Я прям по фото вижу, как убрать три штуки. Даже без схемы (там схема то!) Кстати, проводковая схема в стиле ардуины — зло.

            P. S. Совсем не понятно, зачем там вообще печатная плата. Для 3-х потенциометров? Крепишь их на корпус и соединяешь проводами с модулем — всего делов.
              +1
              нейронки не хватает и автономной системы питания на ветряках или солнечных элементах, а так все шикарно и очень просто для ночника
                –1
                Проект, конечно, интересный, но готовое решение стоит в $3 в IKEA.
                www.ikea.com/us/en/catalog/products/40268756
                  0
                  Я такой, но в другом корпусе брал в икее за 50р.
                  0
                  Хинт: если вместо давно затупившихся стальных свёрл использовать свёрла из карбида вольфрама, то отверстия будут получаться гораздо более аккуратными.

                  Only users with full accounts can post comments. Log in, please.