Перепрошивка китайского rgb контроллера

Публикация 21.07.2018

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

По такому сценарию у меня прошло знакомство с 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 Вт/м, а может меньше.

* комментарии публикуются после модерации
Нет комментариев