Otto17
New member
Есть Скетч на ESP8266 "Witty Cloud", долго с ним возился, что бы заработал как мне нужно.... Вот только не могу понять как решить проблему и немного переделать его....
Что делает скетч: Скетч позволяет включать/выключать 2 реле по MQTT и с выключателей-кнопок. Имеет 3 режима: Off - выключено реле (отправл. 0 по MQTT), On - включено реле (отправл. 1 по MQTT), auto - в этом режиме идёт проверка датчика освещённости и реакция датчика движения, если в обоих случаях true - то включается реле (отправл. 2 по MQTT).
Работает это так: Есть 2 кнопка, при коротком нажатии любой из них происходит переключение режима на конкретное реле. Тем самым это не удобно, т.к. при нажатии на кнопку включается реле, и что бы выключить нужно ещё дважды нажать на эту кнопку.
Что хочу от скетча: Переделать так, что бы при обычных коротких нажатиях любой из кнопки просто включалось/выключалось реле, а при зажатии кнопки 1 (к примеру) более 2-х секунд включался режим auto(режим 3), а отключался простым коротким нажатием в режим Off(режим 0).
Кнопки подключены к GPIO12/14, Релюшки к GPIO4/5. Код написан в среде Arduino IDE.
Помогите пожалуйста, кто знает как это сделать))
Что делает скетч: Скетч позволяет включать/выключать 2 реле по MQTT и с выключателей-кнопок. Имеет 3 режима: Off - выключено реле (отправл. 0 по MQTT), On - включено реле (отправл. 1 по MQTT), auto - в этом режиме идёт проверка датчика освещённости и реакция датчика движения, если в обоих случаях true - то включается реле (отправл. 2 по MQTT).
Работает это так: Есть 2 кнопка, при коротком нажатии любой из них происходит переключение режима на конкретное реле. Тем самым это не удобно, т.к. при нажатии на кнопку включается реле, и что бы выключить нужно ещё дважды нажать на эту кнопку.
Что хочу от скетча: Переделать так, что бы при обычных коротких нажатиях любой из кнопки просто включалось/выключалось реле, а при зажатии кнопки 1 (к примеру) более 2-х секунд включался режим auto(режим 3), а отключался простым коротким нажатием в режим Off(режим 0).
Кнопки подключены к GPIO12/14, Релюшки к GPIO4/5. Код написан в среде Arduino IDE.
Помогите пожалуйста, кто знает как это сделать))
Код:
#include <ESP8266WiFi.h> // Библиотека ESP8266
#include <PubSubClient.h> // Библиотека MQTT
const char* ssid = "ROUTER_SSID"; // Название сети роутера
const char* password = "Password"; // Пароль от роутера
const char* mqtt_server = "192.168.1.70"; // ip брокера mqtt
#define RELAY_1 5 // Реле №1
#define BUTTON_1 12 // Кнопка №1
#define relays_topic1 "home/data/ESP01/Relay1" // Публикуемый топик
#define RELAY_2 4 // Реле №2
#define BUTTON_2 14 // Кнопка №2
#define relays_topic2 "home/data/ESP01/Relay2" // Публикуемый топик
WiFiClient espClient; // Инициализация WiFi клиента
PubSubClient client(espClient); // Инициализация MQTT клиента
long last_mls = millis(); // функция времени в милисекундах
long last_mls2 = millis(); // функция времени для датчика движения PIR
long last_mls3 = millis(); // функция времени для отправки топиков
long last_mls4 = millis(); // функция времени для датчика света
boolean Status1 = true; // объявляем Status1 реле в 0, инверсия...
boolean btnPress1 = false; // объявляем что кнопка №1 не нажата "0"
boolean lastbtnStat1 = false; // временная переменная для хранения статуса1
boolean Status2 = true; // объявляем Status2 реле в 0, инверсия...
boolean btnPress2 = false; // объявляем что кнопка №2 не нажата "0"
boolean lastbtnStat2 = false; // временная переменная для хранения статуса2
int regim1 = 0; // Режимы по умолчанию при включении
int regim2 = 0;
int ligtsvet = 0; // Переменная для фоторезистора, светло или темно | 1 или 0
int pirPin = 13; // 13 - pin для подключения датчика движения
int val = 0; // Переменная для хранения состояния датчика движения
int ligt; // Переменная освещенности для фоторезистора
void setup() {
pinMode(pirPin, INPUT); // PIR датчик как ВХОД
pinMode(RELAY_1, OUTPUT); // Реле №1 как ВЫХОД
pinMode(BUTTON_1, INPUT); // Кнопка №1 как ВХОД
digitalWrite(RELAY_1, Status1); // устанавливаем на выходе статус1 реле
pinMode(RELAY_2, OUTPUT); // Реле №2 как ВЫХОД
pinMode(BUTTON_2, INPUT); // Кнопка №2 как ВХОД
digitalWrite(RELAY_2, Status2); // устанавливаем на выходе статус2 реле
Serial.begin(115200); // инициализация монитора порта
client.setServer(mqtt_server, 1883); // подключаемся к MQTT
client.setCallback(callback); // функция получения топиков с брокера
delay(100); // ждем 100 милисекунд
WiFi.begin(ssid, password); // подключаемся к WiFi
delay(15000); // ждем 15 секунд
client.connect("ESP01RelayClient"); // конектимся с брокером как клиент
client.subscribe("home/data/ESP01/#"); // подписываемся на все топики
}
void pir() { // Функция для датчика движения
val = digitalRead(pirPin); // считываем состояние датчика
if (val == HIGH) {
if (millis() - last_mls2 > 500 && ligtsvet == 0) { // Если значен. датчика движения и фоторезистор...
last_mls2 = millis();
if (regim1 == 2) {
Status1 = false;
digitalWrite(RELAY_1, Status1);
Serial.println("Motion1");
}
if (regim2 == 2) {
Status2 = false;
digitalWrite(RELAY_2, Status2);
Serial.println("Motion2");
}
}
} else {
if (millis() - last_mls2 > 15000) {
last_mls2 = millis();
if (regim1 == 2) {
Status1 = true;
digitalWrite(RELAY_1, Status1);
Serial.println("no Motion1");
}
if (regim2 == 2) {
Status2 = true;
digitalWrite(RELAY_2, Status2);
Serial.println("no Motion2");
}
}
}
}
void svet() { // функция чтения с датчика света
ligt = analogRead(A0);
Serial.print("Svet: ");
Serial.println(ligt);
if (ligt < 100) // Если свет меньше указанного значения...
{ //то ligtsvet равен 0
ligtsvet = 0;
} else //если нет то 1
{
ligtsvet = 1;
}
}
void callback(char* topic, byte* payload, unsigned int length) //читаем топики
{
Serial.print(topic);
Serial.print(" ");
String strTopic = String(topic);
String strPayload = String((char*)payload);
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
if (strTopic == "home/data/ESP01/Relay1") {
if ((char)payload[0] == '0') {
Status1 = true;
regim1 = 0;
}
else if ((char)payload[0] == '1') {
Status1 = false;
regim1 = 1;
} else {
regim1 = 2;
}
}
if (strTopic == "home/data/ESP01/Relay2") {
if ((char)payload[0] == '0') {
Status2 = true;
regim2 = 0;
}
else if ((char)payload[0] == '1') {
Status2 = false;
regim2 = 1;
} else {
regim2 = 2;
}
}
}
void button1() { // Функция для кнопки №1
btnPress1 = digitalRead(BUTTON_1);
Status1 = digitalRead(RELAY_1);
if (btnPress1 && !lastbtnStat1) {
delay(30); // защита от дребезга
btnPress1 = digitalRead(BUTTON_1);
if (btnPress1) { // Если кнопка нажата, то...
regim1++; // переключаем на слежующий режим
if (regim1 > 2) { // если действующий режим > второго, то...
regim1 = 0; // возвращаемся на нулевой режим
}
}
}
if (regim1 == 0) {
Status1 = true;
digitalWrite(RELAY_1, Status1);
}
if (regim1 == 1) {
Status1 = false;
digitalWrite(RELAY_1, Status1);
}
if (regim1 == 2) {
pir();
}
lastbtnStat1 = btnPress1;
}
void button2() { // Функция для кнопки №2
btnPress2 = digitalRead(BUTTON_2);
Status2 = digitalRead(RELAY_2);
if (btnPress2 && !lastbtnStat2) {
delay(30); // защита от дребезга
btnPress2 = digitalRead(BUTTON_2);
if (btnPress2) { // Если кнопка нажата, то...
regim2++; // переключаем на слежующий режим
if (regim2 > 2) { // если действующий режим > второго, то...
regim2 = 0; // возвращаемся на нулевой режим
}
}
}
if (regim2 == 0) {
Status2 = true;
digitalWrite(RELAY_2, Status2);
}
if (regim2 == 1) {
Status2 = false;
digitalWrite(RELAY_2, Status2);
}
if (regim2 == 2) {
pir();
}
lastbtnStat2 = btnPress2;
}
void reconnect_server() // функция проверки подключения
{
if (WiFi.status() != WL_CONNECTED) // если нет подключения с сетью...
{
WiFi.begin(ssid, password);
Serial.println("");
Serial.println("WiFi connect..."); // выводим в монитор порта что пытаемся подкл.
} else {
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
if (!client.connected() && WiFi.status() == WL_CONNECTED) { // если к сети подключились но к MQTT нет
client.connect("ESP01RelayClient"); // Подключаемся к клиенту
client.subscribe(relays_topic1); // подписываемся на топик
Serial.println("Mosquitto connect..."); // выводим в монитор порта что пытаемся подкл.
}
}
void MQTT() // Публикуем топик с состоянием режима
{
if (millis() - last_mls3 > 2000) // Периодичность публикации топика раз в 2 сек.
{
last_mls3 = millis();
client.publish(relays_topic1, String(regim1).c_str());
client.publish(relays_topic2, String(regim2).c_str());
}
}
void loop() {
client.loop();
MQTT();
button1();
button2();
if (millis() - last_mls > 300000) { // Проверка подключений раз в 300 сек. (5 минут)
last_mls = millis();
reconnect_server();
}
if (millis() - last_mls4 > 500) { // Проверка подключений раз в 0,5 сек
last_mls4 = millis();
svet();
}
}