Статья

Разработка DIY диммера 220V на esp8266 (nodeMCU+RobotDyn Thyristor AC)

Как разрабатываются устройства IoT? Это сложно? Китайская компания Espressif Systems в свое время сделала переворот в индустрии IoT, представив свой новый чип ESP8266 по необычайно низкой цене, ставший культовым для производства DIY устройств умного дома. Под новый чип от  Espressif Systems программисты начали активно писать библиотеки и адаптировать существующие библиотеки платформы Arduino. Это сделало разработку IoT устройств необычайно простой и увлекательной. Сегодня существует множество коммерческих устройств на базе чипа ESP8266. Я решил поделиться с вами своим опытом создания устройства IoT на базе чипа ESP8266. 

Сколько вольт "в розетке"?

Большинство ответит: около 220 вольт и будут правы, но не совсем. Напряжение в сети питания представляет собой синусоиду с амплитудой около 311 вольт (tnx to AlexAW), на четверти цикла которой напряжение равно 110 вольт, а иногда и вовсе равно нулю!

Тоесть, если включать нагрузку каждый раз, когда синусоида приближается к нуля, можно напрямую без адаптеров из розетки заряжать мобильный телефон! 

Управлять этими сигналами мы будем с помощью модуля nodemcu, на борту у которого установлена ESP8266. Подключаем пины Z-C и pwm к цифровым пинам ESP8266, подаем питание на модуль и... Ничего не происходит! Верно, нам необходимо еще написать свою прошивку для модуля. Устанавливаем Atom и PlatformIO и приступаем к написанию микропрограммы. Китайские товарищи из RobotDyn уже написали библиотеку для управления таймерами, что упрощает  написание микропрограммы для модуля. Хотя так было не всегда, библиотека появилась около полугода назад, в первоначальной версии прошивки я использовал собственный код для диммирования. 

Что должно уметь наше устройство?

Во-первых, конечно, оно должно управляться из внешних систем по радиоканалу (Wi-Fi в нашем случае): должно принимать команды и отправлять ответ о результате их выполнения. Во-вторых, должна быть возможность найти устройство в сети. И конечно же, возможность обновления "по воздуху" (OTA Update).  Приступим к реализации. Полный листинг кода прошивки я думаю будет интересен небольшому кругу читателей, поэтому всю программную реализацию я оставлю "за кадром", сосредоточимся на принципиальном проектировании устройства. 

Наше устройство должно быть безопасным. Т.к. во время циклов включения-выключения наш транзистор нагревается, установим на плату вот такой простой термодатчик DALLS DS18B20 за 35 рублей. Датчик обменивается с микроконтроллером данными по однопроводной линии связи интерфейса 1-Wire, диапазон измерения температуры составляет от -55 до 125 градусов цельсия, этого должно нам вполне хватить. После превышения температуры 40 градусов, устройство автоматически отключит само себя и перестанет принимать команды до того, пока температура не снизится.  Callback функция отключения выглядит следующим образом:

void emergencyCallback() { sensors.requestTemperatures(); float temperature = sensors.getTempC(insideThermometer); if (temperature > 40) { dimmer.setState(OFF); digitalWrite(LED_PIN, LOW); Serial.printf("Temperature is %.2f degrees celsius. Swith OFF on emergency reason.\n\r", temperature); } else Serial.printf("Temperature is %.2f degrees celsius\n\r", temperature); }

Подключаем все по следующей схеме:

Для корректной работы датчика между пинами DATA и VDD необходимо припаять резистор на 4,7 кОм. Конфигурация пинов следующая:

#define LED_PIN D6 #define AC_LOAD D8 #define ZC_PIN D1 #define ONE_WIRE_BUS D5

Собираем все на макетной плате:

Чтобы устройством можно было управлять, поднимем на нашей ESP8266 TCP сервер на порту 2000. Для отправки на устройство команд я выбрал текстовый формат сериализации и десериализации данных json т.к. он легко читается как людьми, так и машиной, не придется писать свой парсер, можно отправлять и принимать произвольное количество параметров, да и просто с ним удобно работать в целом (особенно в python). Какие команды нам могут понадобится?

{"id":1, "method":"set_power", "power":"50", "state":"ON"} {"id":1, "method":"set_power", "power":"50", "state":"OFF"} {"id":1, "method":"set_state", "state":"OFF"} {"id":1, "method":"set_state", "state":"ON"} {"id":1, "method":"set_config", "SSID":"Wi-Fi SSID", "PASSWD": "PASSWORD"} {"id":1, "method":"set_mode", "mode":"TOGGLE_MODE"} {"id":1, "method":"get_temperature"} {"id":1, "method":"get_state"} {"id":1, "method":"update", "IP":"192.168.1.43", "url":"/update/firmware.bin"}

Параметр method определяет команду для выполнения, set_power устанавливает яркость освещения (диммирование), state - определяет включена или выключена при этом нагрузка. Это может быть удобно, когда в системах управления умным домом вызывается метод "включить" без установки уровня диммирования, в этом случае при включении будет установлен заданный ранее (например, в сцене по времени) уровень освещенности. set_state включает или выключает нагрузку, set_config - посылает на устройство конфигурацию Wi-Fi сети. При первом включении (либо в случае невозможности подключиться к существующей сети) наше устройство переходит в режим точки доступа (с адресом 192.168.4.1), подключившись к которой можно отправить конфигурацию нашей Wi-Fi сети. get_temperature возвращает текущую температуру с сенсора, get_state - текущий статус (выключено или включено), метод update инициирует обновление прошивки, он принимает в качестве параметров IP адрес сервера, на котором находится обновление и сам путь к этом обновлению (url). Само обновление можно, например, разместить в локальной сети на малинке. Отправить команды можно прямо из терминала с помощью утилиты netcat. На запрос

echo '{"id":1, "method":"get_state"}' | nc -w1 192.168.1.43 2000

получим ответ:

{"id":1,"power":30,"state":"ON"}

Для чего нужен id? Дело в том, что ESP8266 отправляет ответ всем подключенным клиентам и чтобы различать ответы, которые предназначены именно нам как раз и нужен id запроса. 

echo '{"id":1, "method":"get_temperature"}' | nc -w1 192.168.1.43 2000

вернет нам текущую температуру с датчика DS18B20

{"id":1,"temperature":21.9}

Уже сейчас наше устройство можно интегрировать с системами управления умным домом путем выполнения shell команд, например можно легко добавить в homebridge, который прокинет устройство в HomeKit. 

Demo

Статические IP. Не люблю я статические IP, поэтому для своего устройства я предусмотрел возможность сетевого поиска. 

void discoverResponder() { if (Udp.parsePacket()) { char packetBuffer[255] = ""; if (Udp.read(packetBuffer, 255) == 0) return; Serial.printf("Received broadcast message: %s from %s\n", packetBuffer, Udp.remoteIP().toString().c_str()); if (String(packetBuffer) == "discover") { Udp.beginPacket(Udp.remoteIP(),Udp.remotePort()); StaticJsonDocument<100> jsonResult; jsonResult["deviceID"] = String(ESP.getChipId(), HEX); WiFi.localIP() ? jsonResult["IP"] = WiFi.localIP().toString() : jsonResult["IP"] = WiFi.softAPIP().toString(); jsonResult["model"] = MODEL; String jsonReply; serializeJson(jsonResult, jsonReply); Udp.print(jsonReply); Udp.endPacket(); } } }

Для поиска в сети ESP8266 DIY Smart Home устройств достаточно отправить на порт 1000 широковещательный UDP пакет с содержанием "discover". Скрипт (поиска) на Python выглядит так:

import json import socket print('Starting discover ESP8266 DIY Smart Home devices...') helobytes = 'discover'.encode() s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) s.settimeout(5) s.sendto(helobytes, ('<broadcast>', 1000)) data, addr = s.recvfrom(1024) reply = json.loads(data.decode()) deviceID = reply["deviceID"] IP = reply["IP"] hardware = reply["hardware"] print('Discovered. Device ID: , IP: , Model: '.format(deviceID, IP, hardware))

 В результате придет ответ:

{"deviceID":"d7531с","IP":"192.168.1.43","hardware":"ZCACD1"}

Здесь deviceID - уникальный идентификатор нашего устройства, нужен для того, чтобы различать несколько устройств в одной сети, IP - IP адрес, необходимый для отправки на устройство команд. 

Прошивка ESP8266

Заливать пошивку мы будем с помощью инструментов esptool и nodemcu-pyflasher. Устанавливаем. 

git clone https://github.com/espressif/esptool.git cd esptool sudo python setup.py install

После установки esptool запускаем nodemcu-pyflasher. Здесь нужно указать порт загрузки - он появляется после после подключения USB to TTL конвертера (либо после подключения USB кабеля если конвертер уже распаян на плате), путь к нашей прошивке, скорость можно оставить 115200. В случае ошибок загрузки, скорость нужно уменьшить, например до 9600. Указываем нужно ли нам стирать все данные на флеш памяти ESP, нажимаем кнопку Flash NodeMCU, ждем несколько секунд - все готово! Иногда перед подключением ESP к компьютеру нужно зажать на плате кнопку "flash", а уже потом подключать питание. Если кнопки flash нет на плате, просто замыкаем контакты GPIO0 и GND, затем подаем питание, это переведет наш модуль в режим прошивки, позволяя загрузить нашу микропрограмму на устройство. 

Интеграция в Domoticz

В конечном итоге я делал устройство для интеграции в системы управления умным домом. Можно конечно подключить его через shell скрипты, но ничто не сравнится с нативной поддержкой, "родные" устройства в Domoticz имеют  наивысший приоритет и работают очень шустро, к тому же будет обратная связь от устройства со статусом выполненной команды (включилось/выключилось), более того, появляется возможность реализовать коммуникацию напрямую через сокеты, что добавит скорости и стабильности нашему устройству. Настройка довольно проста и похожа на настройку других моих плагинов для Domoticz:

После запуска плагин создает выключатель типа диммер, и набор сцен. Bright - яркая сцена, TV - приглушенный до 30%  свет, Daily - включенный на половину диммер, Midnight - минимальное освещение. Можно так же реализовать аппаратные сцены, такие как "восход" или "закат" - все в наших руках! Дополнительно создается температурный сенсор с датчика DS18B20, который можно найти во вкладке "Температура". 

Для установки плагина клонируем репозитарий:

cd domoticz/plugins git clone https://github.com/Whilser/ESP-DIY-Samrt-Home.git ESPSmartHome sudo service domoticz restart

Там же, в репозитарии находится прошивка для модуля: файл firmware.bin.

Больше, чем просто диммер

По сути, наше устройство может измерять и посылать окружающую температуру. Да, если его расположить в корпусе, оно будет измерять внутреннюю температуру, но если вывести его за пределы корпуса - получится дополнительный термодатчик. Если заменить Zero-Cross Detector на реле (например, твердотельное), то получим умную розетку и все это легко интегрируется в систему умного дома, более того, имеется нативная поддержка системы управления умным домом Domoticz. Если закачать прошивку в существующее устройство на базе  ESP8266 (например, sonoff), или светодиодную лампочку (с некоторыми переделками, конечно), получим IoT устройство с нужным нам функционалом, это может говорить о том, что наш проект можно превратить в базовую платформу для разработки недорогих IoT устройств с нужным нам функционалом. Именно для этого в функции discover предусмотрена передача модели устройства. 

Что дальше?

Прототип получился немного громоздким, но на то он и прототип. Устройство можно уменьшить в размерах если:

Разработать и напечатать собственную платуНарисовать и напечатать корпус

Следующим устройством семейства DIY Smart Home будет счетчик воды для информирования о ресурсе фильтра питьевой воды и необходимости его замены. Спасибо за вдохновение Виталию. Так же я планирую доработать текущую прошивку, добавив некоторые аппаратные сцены (такие как восход, закат и может быть что-то еще).

Разработка собственных IoT устройств может быть довольно увлекательным занятием, время пролетает незаметно! Можно легко получить устройство с нужным мне функционалом. В дальнейшем я планирую развивать проект, разрабатывая все новые устройства с нужным мне функционалом, дорабатывая поддержку устройств в системе управления умным домом Domoticz (да, я знаю про существование Home Assistant, но так уж исторически сложилось, что начал строить свой умный дом на платформе Domoticz и если все работает и работает хорошо - не вижу особого смысла менять платформу, а все нужные мне устройства, поддержки который нет в Domoticz я могу легко и увлекательно добавить сам... ). 

Ссылка на проект GitHub: DIY Smart Home based on Espressif Systems (ESP32, ESP8266). Там правда пока мало чего документировано, но со временем я добавлю туда материалы. 

Если Вы ходите собрать подобное устройство, Вам понадобятся комплектующие, купить которые Вы сможете по ссылкам:


когда-то давно хотел заказать себе этот диммер, так и не дошли руки. теперь смело можно брать 

Увлекательная статья, особенно про снятие любого значения напряжения в определенный момент времени

Главный вопрос как работает диммир со светодиодными лампами???

Работает отлично, но светодиодная лампа должна быть диммируемая от сетевого напряжения. 



Пробовал пару штук - не понравилось. Вроде Гауссы, но по сравнению с лампами накаливания яркость изменяют нелинейно. Кстати светодиоды (светодиодные ленты)  при линейном изменении ШИМ тоже изменяют яркость нелинейно (это свойство светодиодов) может поэтому и Диммируемые светодиодки себя так ведут. Но ИМХО не понравилось мне.

Кстати не зря видимо появились диммируемые светодиодки на 3 уровня яркости. По факту больше и не требуется обычно. 

1000x_image.jpg?1561565767
Вообще, зная характеристики напряжение/яркость лампы можно сделать программную компенсацию, изменять напряжение нелинейно. Тогда яркость будет изменяться более-менее линейно. 

Да можно. Но это будет уже диммер для светодиодных диммируемых ламп, коих большое разнообразие и всем явно не "угодишь". Либо надо вводить какую нить опцию в настройки типа учета типа нагрузки, что бы можно было менять значение степени в функции нелинейного преобразования.

Кстати если делать диммер (ШИМ регулятор) для Светодиодных лент, там эту нелинейность надо обязательно закладывать.

Просто топ статья! Спасибо!

Лайк и подписка)

Как спаяешь на платке я бы купил парочку)

и кажется 

 https://github.com/Whilser?tab=projects">DIY а не 



 https://github.com/Whilser?tab=projects">DYI ))

Видимо сказывается нехватка сна 😂

Хороший диммер. 

Есть предложение по софтовому улучшению потребительских характеристик. Как то подсмотрел у Шнайдеровских однокнопочных диммерах. Краткое касание кнопки включает выключает свет на ранее установленном уровне яркости. долгое удержание приводит к плавной регулировке яркости. У вас по сути так и реализовано. Но фишка шнайдеровского в том, что при включении выключении (кратковременном нажатии) он устанавливал запомненное значение яркости плавно, и выключал соответственно тоже. Смотрится оч. приятно. Я в своих сделал очень нравится. Вот демка моего прототипа 

https://www.youtube.com/watch?v=1U6Oy17Ns0k&t=32s">https://www.youtube.com/watch?v=1U6Oy17Ns0k&t=32s

 Еще такой режим бережет лампы накаливания. 

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

Огромное спасибо за труды. Действительно годно и информативно. 

Годно, спасибо за труды. Ещё бы эту чудесную штуку прикрутить к ХА каким либо способом...

Вообще, можно доработать прошивку и подвязать через MQTT брокер. Я делал так с Domoticz раньше, но потом отказался т.к. в текущем решении без MQTT брокера не нужно промежуточное звено и взаимодействие с устройством происходит напрямую через сеть. 

Круто!

Хотя хотелось бы подробнее. Зачем тогда шим контролеры если тут так просто регулируется?

ШИМ работают с постоянным током, здесь ток переменный. Плюс частоту ШИМ можно регулировать, здесь - ограничены частотой сетевого напряжения около 50 Гц, что довольно мало для получения достаточно стабильных напряжений для высокоточной техники. 

Огонь статья и разработка! Сам использую RBDimmer почти год, сначала как просто выключатель, вместо твердотельных реле, затем как регулятор оборотов вентиляторов 220в (в санузлах, а потом и в приточках), последнее его применение подогрев приточного воздуха зимой (PID управление тэном).

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

Попробую твой код, может не будет моргать лампа и я найду свою ошибку ;)

Проблема моргания на низком свечении может быть связана с тем, что ESP не успевает обрабатывать сигнал по причине плохой сборки ("шумов"), плохого сигнала и т.д., часть ресурсов процессора у него тратится на рутинные задачи, либо в качестве сборки самого RobotDyn Thyristor AC. На высоких вольтажах это может быть не сильно заметно т.к. спираль не успевает достаточно остыть. Проблема может решиться заменой компонентов либо в использовании более оптимизированного кода для диммирования (например, с аппаратными таймерами) - надо смотреть чем конкретно вызвана проблема.  

Добрый день! Ищу человека для помощи (возможно платной) в решении задачи по прокидки управления димерами (ТЕН+турбина) с ардуины в малину и потом ХА. Все, что есть в доме сейчас работает на есп, там научился, и вроде все просто (через мктт все кидаю по сети на малину, простыми мануалами научился пр окидывать в ХА), а тут ардуина, хочу по и2с передавать сигнал на малину и обратно, чувствую если сам в это влезу то потрачу вагон времени, хотя похожие мануалы уже нашел. Турбина и ТЕН установлены в системе приточной вентиляции (с очисткой от газов и пыли), в сети много людей пишут, что пытаются это сделать, я уже сделал, осталось автоматизировать, может получится очень крутая статья.

Доброго дня. Несколько вопросов. Вам они могут показаться глупыми, я в своем хобби пока не дорос до вашего уровня. 

Пробовал на Wemos D1 R2 mini  и  NodeMCU. ОС - Windows 10.

Итак, я взял прошивку с гитхаб, убрал всё, что касается датчика температуры, загрузил - работает. Но завис в моменте создания точки доступа платой. Подключаюсь к ней, а что дальше? Как передать данные о моей WiFi сети?  (Подключиться с ноутбука к точке доступа, открыть PowerShell и ввести команду (без nc) ?). Эту проблему пока не могу обойти.

Скачал Domoticz, не удалось установить плагин (папки plugin не было, создал сам, добавил файлы, перезагрузил - безрезультатно). Поднял на виртуальной машине Linux, но и там результата не было (не исключено, что слабое владение Linux сказалось).

Как бы лучше добавить возможность отправлять команды по UDP?  JSON при этом ведь можно задействовать (с json не сталкивался раньше, с python работал) ?  Как я понял во многих случаях интеграции (Domoticz, Home Assistant, Google Home и тд) часто используется передача json-данных, не хотелось бы нарушить текущую структуру кода, когда буду добавлять отправку по UDP .

библиотеку https://github.com/RobotDynOfficial/RBDDimmer">RBDDimmer проверяли на esp8266? в моем случае сперва вылезла ошибка ICACHE_RAM_ATTR которая вылечилась #define ARDUINO_ARCH_ESP8266 в файле сктеча.(нашел в RBDdimmer.h "#elif defined(ARDUINO_ARCH_ESP8266)")ну а теперь вылазит ошибка ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1392, room 16
tail 0
chksum 0xd0
csum 0xd0
v3d128e5c
~ld

которая просто никак не диагностируется. и нужно тщательно просматривать код в поисках неполадки. у кого-то есть еще такая же проблема?

С той библиотекой, которая идет в комплекте проекта на github  все работает на esp8266, с обновленными версиями библиотеки не тестировалось. 

заработал скетч https://github.com/nassir-malik/IOT-AC-Light-Dimmer-With-Alexa">https://github.com/nassir-malik/IOT-AC-Light-Dimmer-With-Alexa тоже от RoboDyn. но в библиотеку его еще нужно добавить,

не забудьте в этом скетче добавить до setup() "void ICACHE_RAM_ATTR zcDetectISR(); " и заменить "void zcDetectISR() {" на "void ICACHE_RAM_ATTR zcDetectISR() {"

написал в поддержку RobotDyn о проблеме. ответили "

Спасибо большое. Сделаем.

" будем ждать. я не знаю как написать библиотку на основе этого скетча. кто-то может помочь?


Вернуться назад

Устройства


Espressif Systems

ESP8266 NodeMcu v3

(16 отзывов)

Вернуться назад