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 порт.
Простейший скетч для выключателя.
Остаётся только присвоить значения переменным
- ssid - название Wi-Fi сети
- password - пароль от Wifi
- mqtt_server - IP адрес MQTT брокера в локальной сети к примеру 192.168.178.2
- 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);
}
И прошиваем чип. Вот и всё. Удачи
Комментарии
Отправить комментарий