
Недавно на Geektimes был обзор про модули ITEAD TH10. Хочу поделиться опытом разработки собственной прошивки для этих устройств.
SONOFF — серия выключателей, розеток и других приборов категории «Интернета вещей» от компании ITEAD. Их характеризует довольно низкая цена, использование «народного WiFi модуля» ESP8266 и работа в собственном сервисе, расположенном в облаке Amazon AWS global server.
Для этих модулей есть сторонние прошивки. Например, MQTT OTA, собираемой с ESP SDK или тоже самое но в среде Arduino IDE
Я хочу поделиться опытом создания собственной прошивки на Sonnoff в среде Ardiono IDE.
Модули Sonoff мне понравились сразу. Начиная от упаковки:

Внешнего вида:


Качественной сборки и пайки:


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


Поддержкой же и документацией своих устройств компания ITEAD может заткнуть за пояс многих именитых производителей, не утруждающих себя публикацией технических подробностей на свои железки. Да и список продуктов компании ITEAD вполне впечатляет
По сути своей Sonoof TH10/16- это ESP8266 с сетевым блоком питания, периферией в виде реле, светодиодов, датчиков температуры и влажности, с колодкой подключения и в приличном корпусе.

Я опущу описание, как подключить Sonoff к облачному сервису и управлять приложением eWeLink на смартфоне. На мой взгляд, полностью неприменимо, когда управление контроллерами зависит от интернета и учетной записи в каком то облаке, пусть и на амазоновских серверах. Поэтому оставим приложение eWeLink для демонстрации возможности Sonoff и напишем свою управляющую программу.
Для этого нужно впаять 4-х штырьковый разъем для подключение к USB/TTL конвертеру.

Имея негативный опыт перепрошивки Sonoff POW, очень рекомендую все работы по программированию проводить с отключенной силовой частью Sonoff и питанием через штырек 3.3В.
Последний USB/TTL у меня героически погиб вместе с модулем Sonoff POW, поэтому использую для подключения Arduino UNO с RESETот подтянутым к земле. 3.3-вольтовый стабилизатор Уны отлично справляется с нагрузкой в виде ESP8266 и всей периферии модуля.

Как среду разработки буду использовать Arduino IDE и за легкости установки и обилия готовых библиотек и примеров, хотя как программист со стажем по прежнему считаю, что для разработки программ любой сложности вполне достаточно VI и make ))).
Как устанавливать ESP8266 Cire for Arduiono IDE посвящено много материалов в интернете. От себя хочу рекомендовать версию Arduino IDE 1.6.5, как имеющую меньше всего глюков при работе с ESP.

Так как на плате установлена микросхема памяти на 1Мбайт, выбираем соответствующую конфигурацию при загрузке в Board Manager:

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

Для того чтобы самому программировать контроллер, нужно понимать, к каким портам что подключено. Для этого можно воспользоваться схемой на сайте ITEAD, ссылку на которую я приводил выше и тестером.
Итак, что мы имеем:
GPIO0 — кнопка (это понятно, когда мы включали бутлоадер)
GPIO12 — красный светодиод и реле
GPIO13 — синий светодиод
GPIO14 и GPIO4 выведены на разъем подключения датчиков.
Причем оба датчика однопроводные и используют GPIO14. GPIO4 еще нужно включить перемычкой на плате.
Да. Не густо, хотя и больше чем у ESP01.
GPIO2 и GPIO15 имеют подтягивающие резисторы на плате, можно подпаяться к ним. GPIO5 и ADC вообще никуда не распаяны и нужно подключаться прямо к микросхеме ESP. Оставим эти четыре вывода в покое и приступим к программированию.
Скетч мигания светодиодами на sonoff
/** * Прошивка SONOFF TH10/16 * Copyright 2016 Алексей Шихарбеев * http://samopal.pro */ #include <arduino.h> uint8_t PIN_RELAY = 12; uint8_t PIN_LED2 = 13; void setup() { pinMode(PIN_RELAY,OUTPUT); pinMode(PIN_LED2, OUTPUT); }
Светодиоды работают в противофазе. Синий загорается, когда на нем низкий уровень. Реле срабатывать не должно из за отсутствия питания 5В. В дальнейшем я буду использовать синий светодиод для отображения различных режимов. Подробно про это я написал в этой статье
На кнопке я подробно останавливаться не буду. Да управления кнопками я написал удобную библиотеку, которая отлавливает длинное и короткое нажатие, автоповторение при длинном нажатии и давит дребезг контактов. Все это я подробно описал в своем блоге.
Теперь сенсоры. Мне прислали датчик температуры/влажности AM2301 и датчик температуры DS18B20 в водонепроницаемом исполнении.

AM2301 совместим с сенсором DHT21. Для его работы нужна библиотека DHT. Форков библиотеки DHT существует великое множество, я рекомендую брать версию от Adafruit в которой есть автонастройка на частоту контроллера и которая корректно работает на ESP8266.
Скетч работы с сенсором AM2301
/** * Прошивка SONOFF TH10/16 * Copyright 2016 Алексей Шихарбеев * http://samopal.pro */ #include <arduino.h> // DHT от Adafruit // https://github.com/adafruit/DHT-sensor-library #include <DHT.h> uint8_t PIN_DHT = 14; DHT dht(PIN_DHT, AM2301); void setup() { // Последовательный порт для отладки Serial.begin(115200); Serial.printf("DHT init ..."); dht.begin(); } void loop() { delay(1000); Serial.print("Temperature="); Serial.print(dht.readTemperature(),1); Serial.println(" C"); Serial.print("Humidity="); Serial.print(dht.readHumidity(),0); Serial.println("%"); }

Для подключения DS18B20 нужна библиотека OneWire. Полностью совместима с ESP мультиплатформенная версия этой библиотеки
Алгоритм опроса датчика берем из примера:
Скетч работы с сенсором DS18B20
/** * Прошивка SONOFF TH10/16 * Copyright 2016 Алексей Шихарбеев * http://samopal.pro */ #include <arduino.h> // Мультиплатформенная библиотека // https://github.com/PaulStoffregen/OneWire #include <OneWire.h> #define ERROR_VALUE 2147483647 float GetDS18X20(); uint8_t PIN_DS = 14; OneWire ds(PIN_DS); void setup() { // Последовательный порт для отладки Serial.begin(115200); Serial.printf("DS18B20 init ..."); } void loop() { delay(1000); float t = GetDS18X20(); if( t!= ERROR_VALUE ){ Serial.print("Temperature="); Serial.print(t,1); Serial.println(" C"); } } /** * Опрос датчика температуры */ float GetDS18X20(){ byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; float celsius; if ( !ds.search(addr)) { // Serial.println("DS18B20: No more addresses."); ds.reset_search(); delay(250); return ERROR_VALUE; } if (OneWire::crc8(addr, 7) != addr[7]) { // Serial.println("DS1820: CRC is not valid!"); return ERROR_VALUE; } // the first ROM byte indicates which chip switch (addr[0]) { case 0x10: type_s = 1; break; case 0x28: type_s = 0; break; case 0x22: type_s = 0; break; default: // Serial.println("Device is not a DS18x20 family device."); return ERROR_VALUE; } ds.reset(); ds.select(addr); ds.write(0x44, 1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } // Convert the data to actual temperature // because the result is a 16 bit signed integer, it should // be stored to an "int16_t" type, which is always 16 bits // even when compiled on a 32 bit processor. int16_t raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; // 9 bit resolution default if (data[7] == 0x10) { // "count remain" gives full 12 bit resolution raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); // at lower res, the low bits are undefined, so let's zero them if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms //// default is 12 bit resolution, 750 ms conversion time } celsius = (float)raw / 16.0; return celsius; }

Ну вот, периферия работает. Дальше я использую существующие свои наработки. Полностью всю прошивку можно взять отсюда
Особенности прошивки:
- Автоматическое определение сенсоров AM2301 и DS18B20
- Длинное нажатие кнопки — вкл/откл режима точки доступа
- Короткое нажатие кнопки — вкл/откл реле
- Синий светодиод горит — соединение установлено, двойная вспышка — нет подключения, одинарное мигание — режим точки доступа
- Локальный WEB-сервер в режиме точки доступа 192.168.4.1
- при подключении к WiFi по тому IP адресу который настроен
- Авторизация доступа по паролю. По умолчанию admin/12345
- Сохранение параметров на сервер в интернете обычным HTTP запросом. Можно настроить любой сервер, например, народный мониторинг. А можно и локальный без всякого интернета.
- Сохранение настроек в EEPROM
- При подключении к интернету установка времени по NTP


Для любителей готовых сервисов. легко прикручивается готовая библиотека MQTT, BLYNK И пр. Но это уже за пределами данной статьи.
Итог
SONOFF — это удобная платформа в первую очередь для тех, кто может самостоятельно разрабатывать и дорабатывать управляющие программы.
Тем кто знаком с ESP8266 — Sonoff это экономия на сборке, пайке и деталях, при условии, что вам нужна именно такая конфигурация устройства, как заложена в конкретном модуле Sonoff.
Самый большой недостаток данных модулей то, что часть GPIO не разведены на разъемы. Ну что стоит сделать компании ITEAD гребенку с 8 pin и завести туда все свободные GPIO от ESP. Я думаю, популярность бы таких модулей при существующей цене сильно бы выросла.
Что касается конкретных применений, такой контроллер вполне можно реализовать на модуле Sonoff TH10.
