Наверное у каждого была ситуация когда китайское чудо работает, а потом не работает. Стучать по ней бесполезно - программный сбой... Что делать? Зашить свой код, пусть работает.

По такому сценарию у меня прошло знакомство с rgbw-контроллером производителя ASMTLEDТ. Китайцы что-то напортачили с кодом и одним днем оно с мобильного приложения перестало выполнять мои команды.
Покрутив в руках я расколол этот "орех", а внутри.. тадам!

А там наш знакомый друг.. esp8285. Почти тоже самое, что esp8266. Для нас изменится лишь то, что в типе платы мы выберем не esp8266, а esp8285. Все, погнали шить...
Смотрим распиновку

Ага, все как обычнно для прошивки:
- IO15 на землю (минус)
- GND на землю (минус)
- IO0 на землю (минус)
- TX0 на RX usb-uart переходника
- RX0 на TX usb-uart переходника
Ну и питание на плату что-ли подать. К слову, подавать минус на IO0 нужно только в момент включения, потом не обязательно, но с минусом программа просто не запустится.
По этому лучше вынести IO0 на минус через кнопку. Выходит очень удобно:
Нажал кнопку,
подал питание,
отпустил кнопку,
залил скетч,
перезагрузил,
испытал как работает.


Теперь поговорим о скетче. Моя версия платы имеет 4 силовых ключа: RGBW. W мне не нужен - он используется при цветном освещении. Белый канал позволяет получить чистый белый свет, но моя подсветка используется как декоративная и такой необходимости нет. По тому в своем коде я оставлю канал W без внимания.
В коде используются наработки из статьи про mqwtt rgb контроллер и супермегоудобный конфигуратор wi-fi подключения (через приложение на смартфоне). Пожалуй хватит трепа:
#include <ESP8266WiFi.h> #include <PubSubClient.h> #include <EEPROM.h> // Подключение к mqtt брокеру const char *mqtt_server = "m13.cloudmqtt.com"; // Имя сервера MQTT const int mqtt_port = 14483; // Порт для подключения к серверу MQTT const char *mqtt_user = "xxxx"; // Логи к серверу MQTT const char *mqtt_pass = "xxxx"; // Пароль к серверу MQTT const char *topic_name = "light/rgb1"; // Название mqtt топика для передачи цвета // Конфигурация портов const int w = 15; // GIPO управления каналом цвета W - не используется const int r = 5; // GIPO управления каналом цвета R const int g = 12; // GIPO управления каналом цвета R const int b = 13; // GIPO управления каналом цвета B // конфигурация eprom памяти const int eprom_r = 0; // Область в памяти для R const int eprom_g = 1; // Область в памяти для G const int eprom_b = 2; // Область в памяти для B #define BUFFER_SIZE 100 int tm = 300; float temp = 0; int c_r = 0; // Текущий цвет R int c_g = 0; // Текущий цвет G int c_b = 0; // Текущий цвет B WiFiClient wclient; PubSubClient client(wclient); void setup_wifi() { delay(10); WiFi.beginSmartConfig(); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); Serial.println(WiFi.smartConfigDone()); } Serial.println(""); Serial.println("WiFi connected"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void reconnect() { // Повторять пока нет MQTT соединения while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Попытка подключения к MQTT if (client.connect("arduinoClient", mqtt_user, mqtt_pass)) { Serial.println("connected"); // Подписываемся по топики (которые мы будем слушать от брокера) client.subscribe(topic_name); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } } void setup() { Serial.begin(115200); delay(10); // Конфигурируем GPIO при старте pinMode(r, OUTPUT); pinMode(g, OUTPUT); pinMode(b, OUTPUT); // Читаем последний заданный цвет из энергонезависимой памяти EEPROM // Необходимо вызвать функцию EEPROM.begin(size) каждый раз перед началом чтения или записи. // Размер (указывается в байтах) соответствует размеру данных, которые вы намереваетесь использовать в EEPROM. // Размер данных должен быть в диапазоне от 4 до 4096 байт. EEPROM.begin(4); c_r = EEPROM.read(eprom_r); c_g = EEPROM.read(eprom_g); c_b = EEPROM.read(eprom_b); EEPROM.commit(); setColor(); setup_wifi(); client.setServer(mqtt_server, mqtt_port); client.setCallback(callback); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); } // Функция получения данных от MQTT сервера void callback(char* topic, byte* payload, unsigned int length) { // Присланное значение цвета String value = ""; for (int i=0; i<length; i++) { value = value + ((char)payload[i]); } Serial.print("The topic: "); Serial.println(topic); // Проверяем из нужного ли нам топика пришли данные if (String(topic) == String(topic_name)) { if (value != "") { Serial.print("HEX color: "); Serial.println(value); // Конвертируем пришедшие данные из hex #00AAFF в отдельные integer цвета long number = (long) strtol( &value[1], NULL, 16); c_r = number >> 16; c_g = number >> 8 & 0xFF; c_b = number & 0xFF; setColor(); // Запишем новые цвета в память, что бы при следующем включении цвет был такой же EEPROM.begin(4); EEPROM.write(eprom_r, c_r); EEPROM.write(eprom_g, c_g); EEPROM.write(eprom_b, c_b); EEPROM.commit(); } } } void setColor() { // Передадим значения на GPIO analogWrite(r, c_r); analogWrite(g, c_g); analogWrite(b, c_b); Serial.print("Set color RGB("); Serial.print(c_r); Serial.print(", "); Serial.print(c_g); Serial.print(", "); Serial.print(c_b); Serial.println(")"); }
Управление цветом происходит по mqtt протоколу. Процесс настройки и управления описан в статье.
Результат приятный:



Эта малышка тянет 25 метров rgb летны. Даже не вспотела. Лента дешевенькая, слабая - 4,5 Вт/м, а может меньше.