MQTT прошивка сенсорного WiFi выключателя King-Art TuYa Curtain для жалюзи

King-Art TuYa Curtain - настенный Wifi выключатель с сенсорным управлением. Основан на микросхеме ESP8266 и может управлять двумя реле.

Для управления выключателем  в локальной сети по протоколу MQTT необходим  MQTT брокер mosquitto, предустановленный на компьютер или роутер с прошивкой OpenWRT. Также необходим MQTT клиент такой как MQTT Dash для Андроид или же что-то более масштабное такое как умный дом MajorDoMo.


Подготовка к прошивке выключателя.

Снимаем крышку, для этого отвёрткой снизу поддеваем Touch панель.
Снимаем плату. 
Все контакты, в том числе и GPIO0 для перевода чипа в режим записи прошивки, выведены на плате.



Подпаиваемся к контактам.

Для прошивки чипа нужен  USB-TTL конвертер, к примеру CP2104 CNT-003A работающий с напряжением 3.3В.


Соединяем конвертер и выключатель 4 проводами следующим образом:

GND выключатель     - GND конвертер
RX выключатель        - TX конвертер
TX выключатель        - RX конвертер
3.3В выключатель      - 3.3В конвертер (VCC)
GPIO0 выключатель  - GND конвертер


Осторожно напряжение должно быть не более 3.3В.


В Arduino IDE устанавливаем настройки чипа в меню Инструменты ->


Если конвертер используете впервые, то в разделе "Порт"  запоминаем всё что там есть.
После подключения конвертера и установки драйверов, появится ещё один порт, его и нужно будет выбрать для прошивки выключателя. В моём случае это 12 порт.


Простейший скетч для выключателя.

Остаётся только присвоить значения переменным

  1. ssid                - название Wi-Fi сети
  2. password       - пароль от Wifi
  3. mqtt_server   - IP адрес MQTT брокера в локальной сети к примеру 192.168.178.2
  4. NAME          - Имя выключателя к примеру kitchenSwitch значит команды на вкл/выкл будут ходить по пути kitchenSwitch/status, а подтверждения по пути kitchenSwitch/alive.

Если MQTT брокер защищён логином и паролем необходимо так же присвоить переменным mqtt_user и mqtt_password правильные значения. И не забыть убрать слеш // перед ними.

Вот теперь можно заливать скетч.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

//--------------WIFI---------------------//
const char* ssid = "................";  // SSID Имя Wifi
const char* password = "............";  // Введи пароль от Wifi
const char* mqtt_server = ".........";  // IP адрес MQTT брокера
#define NAME  "..........."           // Имя выключателя

//const char* mqtt_user = "majordomo";
//const char* mqtt_password = "123456";

/*/--------------MQTT и топики----------------/*/
const char *COMAND = NAME "/comand";
const char *TOPIC_IP = NAME "/IP";           // отправляет IP
const char *TOPIC_INFO = NAME "/Info";

const char *STATUS_TOPIC =  NAME "/status";
const char *ALIVE_TOPIC =  NAME "/alive";

// #define NeuStart    "Vremja/timeNow"      // Время нового старта
/*/--------------Пины-----------------/*/
#define BUTTON_PIN1 5
#define RELAY_PIN1 15
#define LED_PIN 0

#define BUTTON_PIN2 14

#define BUTTON_PIN3 12
#define RELAY_PIN3 13

/*/--------------Переменные-----------------/*/
int releStatus1 = 0;
int releAlive1 = 0;
int releStatus3 = 0;
int releAlive3 = 0;

boolean Button1 = false;
boolean Button3 = false;
boolean sperButton1 = false;
boolean sperButton3 = false;
int tajmer = 0;

unsigned long lastMQTTCheck = -5000; //This will force an immediate check on init
boolean infoCom = false;

/*/--------------Инициализация----------------/*/
WiFiClient espClient;
PubSubClient client(espClient);


void setup_wifi() {
  delay(10);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
  randomSeed(micros());
}

void reconnect() {
  while (!client.connected()) {
    digitalWrite(LED_PIN, HIGH); //LED off.
    if (client.connect(NAME)) {
      client.subscribe(COMAND);
      client.subscribe(STATUS_TOPIC);
      //client.subscribe(NeuStart);
      digitalWrite(LED_PIN, LOW);
    } else {
      delay(5000);
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  // Преобразование входящего массива байтов в строку
  payload[length] = '\0'; // Null terminator используется для завершения массива char
  String message = (char*)payload;
  String top = topic;
  /*-------------Info ESP-----------------*/
  if (top == COMAND) {
    if (message == "Info") {
      String esp = "KingArt Tuya_3, BUTTON: 5.14.12, Relay: 15.X.13, и т.д.";
      client.publish(TOPIC_INFO, esp.c_str(), true);
    } else if (message == "IP") {
      infoCom = false;
    }
  }

  /*-------------Новый старт-----------------
  if (top == NeuStart) {
    if (message == "03:06") {
      ESP.reset();
    }
  }*/

  if (top == STATUS_TOPIC) {
    if (message == "1" || message == "ON") {
      digitalWrite(RELAY_PIN3, LOW);
      releStatus1 = 1;
    }
    else if (message == "3" || message == "STOP") {
      releStatus3 = 0;
      releStatus1 = 0;
      client.publish(ALIVE_TOPIC, String("3").c_str(), true);
    }
    else if (message == "0" || message == "OFF") {
      digitalWrite(RELAY_PIN1, LOW);
      releStatus3 = 1;
    }
  }
}


void setup() {
  Serial.begin(115200);

  pinMode(RELAY_PIN1, OUTPUT);
  digitalWrite(RELAY_PIN1, LOW);
  pinMode(BUTTON_PIN1, INPUT_PULLUP);

  pinMode(BUTTON_PIN2, INPUT_PULLUP);

  pinMode(RELAY_PIN3, OUTPUT);
  digitalWrite(RELAY_PIN3, LOW);
  pinMode(BUTTON_PIN3, INPUT_PULLUP);

  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH); //LED off.


  setup_wifi();
  ArduinoOTA.setHostname(NAME);               // Задаем имя сетевого порта
  ArduinoOTA.begin();                             // Инициализируем OTA

  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {
  ArduinoOTA.handle();   // Всегда готовы к прошивке

  if (millis() - lastMQTTCheck >= 5000) {
    reconnect();
    lastMQTTCheck = millis();
  }
  client.loop();
  delay(100);

  /*---- Отправляем IP при старте МК и по запросу ----*/
  if (!infoCom && WiFi.status() == WL_CONNECTED) {
    String ipInfo = WiFi.localIP().toString();
    client.publish(TOPIC_IP, ipInfo.c_str(), true);
    infoCom = true;
  }
  
  /*---- Опрос кнопок ----*/
  if (digitalRead(BUTTON_PIN1) == 0) {
    digitalWrite(RELAY_PIN3, LOW);
    delay(100);
    releStatus1 = !releStatus1;
  }

  if (digitalRead(BUTTON_PIN2) == 0) {
    releStatus1 = 0;
    releStatus3 = 0;
    client.publish(ALIVE_TOPIC, String("3").c_str(), true);
  }

  if (digitalRead(BUTTON_PIN3) == 0) {
    digitalWrite(RELAY_PIN1, LOW);
    delay(100);
    releStatus3 = !releStatus3;
  }

  /*---- Управление реле ----*/
  if (releAlive1 != releStatus1) {
    if (releStatus1 == 1) {
      digitalWrite(RELAY_PIN3, LOW);
      delay(100);
      digitalWrite(RELAY_PIN1, HIGH);
      releAlive1 = releStatus1;
      client.publish(ALIVE_TOPIC, String("1").c_str(), true);
      tajmer = 1;
    } else {
      digitalWrite(RELAY_PIN1, LOW);
      releAlive1 = releStatus1;
      client.publish(ALIVE_TOPIC, String("3").c_str(), true);
    }
  }
  if (releAlive3 != releStatus3) {
    if (releStatus3 == 1) {
      digitalWrite(RELAY_PIN1, LOW);
      delay(100);
      digitalWrite(RELAY_PIN3, HIGH);
      releAlive3 = releStatus3;
      client.publish(ALIVE_TOPIC, String("0").c_str(), true);
      tajmer = 1;
    } else {
      digitalWrite(RELAY_PIN3, LOW);
      releAlive3 = releStatus3;
      client.publish(ALIVE_TOPIC, String("3").c_str(), true);
    }
  }
    /*---- Таймер отключения реле ----*/
  if (tajmer != 0) {
    if (tajmer >= 150) {
      digitalWrite(RELAY_PIN1, LOW);
      digitalWrite(RELAY_PIN3, LOW);
      delay(100);
      releStatus1 = 0;
      releStatus3 = 0;
      delay(100);
      tajmer = 0;
    } else {
      tajmer++;
    }
  }
  delay(100);
}


И прошиваем чип. Вот и всё. Удачи


Комментарии

Популярные сообщения из этого блога

Перенос Armbian на SSD

Установка Home Assistants на Orange pi

Радиореле 220В 433МГц c кодировкой сигнала eV1527