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

25 июня 2019, 23:00

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

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

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

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

Для определения точки, когда в сети напряжение равно нулю я воспользовался вот таким устройством от китайских товарищей из RobotDyn стоимостью 230 руб. Он уже содержит в себе сразу детектор нуля (zero-cross detector) и симмистор, который открывается при подаче импульса управления, оставаясь открытым до тех пор пока питающее напряжение не упадет практически до нуля. Для получения нужного  напряжения на выходе мы должны синхронизировать сигнал управления с переходом синусоиды питающего напряжения через ноль. Управление силовым симмистором заведено  через маломощный оптосиммистор, поэтому цепи управления гальванически развязаны с сетевым напряжением. Каждый раз, когда сетевое напряжение приближается к нулю, модуль  подает сигнал на один из своих выходов. Смещая фазу включения симмистора путем подачи управляющего сигнал на другой пин модуля можно получить на выходе любое напряжение в пределах от 220 вольт до нуля. 

Управлять этими сигналами мы будем с помощью модуля 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: {0}, IP: {1}, Model: {2}'.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:

Для настройки необходимо ввести только deviceID, встроенная система поиска "discover" сама найдет устройство в сети. Для получения deviceID при первой настройке нужно просто оставить поле равным 0, это запустит режим сетевого поиска и в логе Domoticz будет отображен deviceID, который нам нужен. 

После запуска плагин создает выключатель типа диммер, и набор сцен. 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). Там правда пока мало чего документировано, но со временем я добавлю туда материалы. 


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


Все новости мира умных домов - t.me/SprutAI_News

Остались вопросы? Мы в Telegram - t.me/soprut

Хочешь умный дом но нет времени разбираться?
Посмотри примеры работ и выбери себе интегратора.
  1. Дмитрий Батюшин (ReD)
    Дмитрий Батюшин (ReD) 4 месяца назад

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

  2. Владислав Попов (Vladislav_P)

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

  3. Илья Яшин (yshinig)
    Илья Яшин (yshinig) 4 месяца назад

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

    • Антон Киселёв (Whilser)
      Антон Киселёв (Whilser) 4 месяца назад

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

      • Александр Вайдуров (AlexAW)

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

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

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

          • Александр Вайдуров (AlexAW)

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

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

  4. Андрей Медведев (rjayone)
    Андрей Медведев (rjayone) 4 месяца назад

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

  5. Никита Герасимов  (Rapidshe)
    Никита Герасимов (Rapidshe) 4 месяца назад

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

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

    и кажется   DIY а не   DYI ))

  6. Александр Вайдуров (AlexAW)

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

    Есть предложение по софтовому улучшению потребительских характеристик. Как то подсмотрел у Шнайдеровских однокнопочных диммерах. Краткое касание кнопки включает выключает свет на ранее установленном уровне яркости. долгое удержание приводит к плавной регулировке яркости. У вас по сути так и реализовано. Но фишка шнайдеровского в том, что при включении выключении (кратковременном нажатии) он устанавливал запомненное значение яркости плавно, и выключал соответственно тоже. Смотрится оч. приятно. Я в своих сделал очень нравится. Вот демка моего прототипа  https://www.youtube.com/watch?v=1U6Oy17Ns0k&t=32s  Еще такой режим бережет лампы накаливания. 

    • Антон Киселёв (Whilser)
      Антон Киселёв (Whilser) 4 месяца назад

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

  7. Евгений Селянин (Shico)
    Евгений Селянин (Shico) 4 месяца назад

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

  8. (meta11ist87)
    (meta11ist87) 4 месяца назад

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

    • Антон Киселёв (Whilser)
      Антон Киселёв (Whilser) 4 месяца назад

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

  9. (maikl)
    (maikl) 4 месяца назад

    Круто!

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

    • Антон Киселёв (Whilser)
      Антон Киселёв (Whilser) 3 месяца назад

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

  10. Алексей Новосельцев (novo)

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

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

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

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

  11. (Paliy)
    (Paliy) 2 месяца назад

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

К списку статей

Скидки для сообщества

Ноотехника

+375 17 233-25-45
Промокод:
Sprut
Размер скидки:
10%
Действует у всех официальных представителей. Для применение необходимо указать в поле комментария или при звонке менеджеру.

Интернет-магазин yourhomekit.ru

+7 914 550-51-11
Промокод:
SPRUT-BLG
Размер скидки:
8%
Cамый большой ассортимент в России аксессуаров Apple HomeKit

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

04 сентября 2018, 12:14
Интеграция RGB ленты на ESP8266 с прошивкой tasmota в систему HomeBridge (HomeKit)
02 ноября 2018, 12:14
Кнопка звонка с уведомлениями в HomeKit
15 октября 2018, 09:05
Прошивка для Sonoff c нативным HomeKit
15 ноября 2018, 09:42
Способы автоматизации механических ворот
27 октября 2018, 12:20
Нативный Термостат для котла на ESP8266 с поддержкой Apple HomeKit
01 октября 2018, 07:43
Нативный HomeKit на ESP8266
15 июня 2018, 12:13
Охранная система в гараж на ESP8266 с интеграцией в Apple HomeKit
02 октября 2018, 18:41
Установка SDK для компиляции прошивок под HomeKit
22 октября 2018, 19:00
Сборка DIY Лабораторного блока питания из китайских модулей
03 октября 2018, 22:03
Как собрать и настроить Hyperion Ambilight - адаптивную подсветку ТВ.