Хабрахабр

[Из песочницы] Ночник с выключением по расписанию

image

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

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

image

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

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

image

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

image

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

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

image

image

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

image

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

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

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()
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; } }

Теги
Показать больше

Похожие статьи

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

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

Кнопка «Наверх»
Закрыть