• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Решено MajorDomo и ESP8266

Snezhana

New member
Ребята помогите решить задачу.
Плата ESP8266 управляет тремя реле через MajorDomo
Вот скетч:
Код:
// Блок [Подключение библиотек] ************************************************
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// END Блок [Подключение библиотек] ********************************************

// Блок [Подключение к сети WI-FI] *********************************************
const char* ssid = "ssid";                // Имя WI-FI сети
const char* password = "password";        // Пароль WI-FI сети
const char* mqtt_server = "192.168.200.251";      // IP адрес MQTT сервер
// END Блок [Подключение к сети WI-FI] *****************************************

#define RELE_1 14                               // Реле №1
#define RELE_2 12                               // Реле №2
#define RELE_3 13                               // Реле №3
#define BUTTON_1 16                               // Кнопочный выключатель №1
#define BUTTON_2 5                                // Кнопочный выключатель №2
#define BUTTON_3 4                                // Кнопочный выключатель №3
#define relays_topic1 "ESP01/RELE_1"              // Топик реле №1
#define relays_topic2 "ESP01/RELE_2"              // Топик реле №2
#define relays_topic3 "ESP01/RELE_3"            // Топик реле №3



WiFiClient espClient;
PubSubClient client(espClient);

long last_mls = millis();
char msg[50];
boolean rState1 = false;
boolean rState2 = false;
boolean rState3 = false;
boolean btnPress1 = false;
boolean btnPress2 = false;
boolean btnPress3 = false;
boolean lastbtnStat1 = false;
boolean lastbtnStat2 = false;
boolean lastbtnStat3 = false;

void setup() {
  pinMode(RELE_1, OUTPUT);
  pinMode(RELE_2, OUTPUT);
  pinMode(RELE_3, OUTPUT);
  pinMode(BUTTON_1, INPUT);
  pinMode(BUTTON_2, INPUT);
  pinMode(BUTTON_3, INPUT);
  digitalWrite(RELE_1, rState1);
  digitalWrite(RELE_2, rState2);
  digitalWrite(RELE_3, rState3);
  Serial.begin(115200);
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  delay(100);
  WiFi.begin(ssid, password);
  delay(6000);
  client.connect("ESP8266Client");
  client.subscribe(relays_topic1);
  client.subscribe(relays_topic2);
  client.subscribe(relays_topic3);

  lastbtnStat1 = digitalRead(BUTTON_1);
  lastbtnStat2 = digitalRead(BUTTON_2);
  lastbtnStat3 = digitalRead(BUTTON_3);
}

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.print("IP address: ");
    Serial.println(WiFi.localIP());
    Serial.print("");
  }

  if(!client.connected() && WiFi.status() == WL_CONNECTED){
    if (client.connect("ESP8266Client")) {
      Serial.println("Mosquitto connect...");
  client.subscribe(relays_topic1);
  client.subscribe(relays_topic2);
  client.subscribe(relays_topic3);
    } else {
      Serial.print("failed connect Mosquitto, rc=");
      Serial.print(client.state());
      Serial.println("");
    }
  }
}
// Блок [обратная связь] ****************************************************
void callback(char* topic, byte* payload, unsigned int length) {
    Serial.print("Message arrived [");
    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);
  }
  Serial.println();
// Блок [Управление Реле 1 из MajorDomo] ************************************
if (strTopic == "ESP01/RELE_1") {
    if ((char)payload[0] == '1') {
        rState1 = true;
        digitalWrite(RELE_1, rState1);
    }
    else {
        rState1 = false;
        digitalWrite(RELE_1, rState1);
    }
}
// END Блок [Управление Реле 1 из MajorDomo] ********************************

// Блок [Управление Реле 2 из MajorDomo] ************************************
if (strTopic == "ESP01/RELE_2") {
    if ((char)payload[0] == '1') {
        rState2 = true;
        digitalWrite(RELE_2, rState2);
    }
    else {
        rState2 = false;
        digitalWrite(RELE_2, rState2);
    }
}
// Блок [Управление Реле 2 из MajorDomo] ************************************

// Блок [Управление Реле 3 из MajorDomo] ************************************
if (strTopic == "ESP01/RELE_3") {
    if ((char)payload[0] == '1') {
        rState3 = true;
        digitalWrite(RELE_3, rState3);
    }
    else {
        rState3 = false;
        digitalWrite(RELE_3, rState3);
    }
}
// Блок [Управление Реле 3 из MajorDomo] ************************************
}
// END Блок [обратная связь] ************************************************

// Блок [Управление Реле 1 с кнопки] ****************************************
void button_1(){
  btnPress1 = digitalRead(BUTTON_1);

  if (btnPress1 && !lastbtnStat1){
    delay(300); // защита от дребезга (300 мсек.)
    btnPress1 = digitalRead(BUTTON_1);

    if(btnPress1){
      rState1 = !rState1;
      digitalWrite(RELE_1, rState1);
      client.publish(relays_topic1, String(rState1).c_str(), true); // Публикуем состояние реле 1 на MQTT
    }
  }
  lastbtnStat1 = btnPress1;
}
// END Блок [Управление Реле 1 с кнопки] ************************************

// Блок [Управление Реле 2 с кнопки] ****************************************
void button_2(){
  btnPress2 = digitalRead(BUTTON_2);

  if (btnPress2 && !lastbtnStat2){
    delay(300); // защита от дребезга (300 мсек.)
    btnPress2 = digitalRead(BUTTON_2);

    if(btnPress2){
      rState2 = !rState2;
      digitalWrite(RELE_2, rState2);
      client.publish(relays_topic2, String(rState2).c_str(), true); // Публикуем состояние реле 2 на MQTT
    }
  }
  lastbtnStat2 = btnPress2;
}
// END Блок [Управление Реле 2 с кнопки] ************************************

// Блок [Управление Реле 3 с кнопки] ****************************************
void button_3(){
  btnPress3 = digitalRead(BUTTON_3);

  if (btnPress3 && !lastbtnStat3){
    delay(300); // защита от дребезга (300 мсек.)
    btnPress3 = digitalRead(BUTTON_3);

    if(btnPress3){
      rState3 = !rState3;
      digitalWrite(RELE_3, rState3);
      client.publish(relays_topic3, String(rState3).c_str(), true); // Публикуем состояние реле 3 на MQTT
    }
  }
  lastbtnStat3 = btnPress3;
}
// END Блок [Управление Реле 3 с кнопки] ************************************


void loop(){

client.loop();

// Блок [Проверка подключения] **********************************************
if (millis() - last_mls > 60000) { // Проеверка подключения к сети (раз в 60 сек.)
    last_mls = millis();
    reconnect_server();
}
// END Блок [Проверка подключения] ******************************************

  button_1(); // Функция кнопки №1 и публикация статуса реле 1 на MQTT
  button_2(); // Функция кнопки №2 и публикация статуса реле 2 на MQTT
  button_3(); // Функция кнопки №3 и публикация статуса реле 3 на MQTT
}
Топик ESP01/RELE_1 Включает и выключает Реле 1
Топик ESP01/RELE_2 Включает и выключает Реле 2
Топик ESP01/RELE_2 Включает и выключает Реле 2
установлена она на лестнице но иногда кратковременно пропадает электричество и при включении плата по умолчанию отключает все реле.

А нужно чтобы она принимала те значения которые были установлены в MajorDomo
 
Последнее редактирование:

Snezhana

New member
Сделайте unsubscribe а после этого - subscribe. Брокер пришлет данные "новому" подписчику.
Можно пожалуйста подробнее если вам не сложно, напишите пожалуйста как это встроить в мой скетч
 
Последнее редактирование:

=AK=

New member
Код:
void loop(){
  static long last_millis;
  if (millis() - last_millis > 1000) {   // every second
    last_millis  = millis();
    client.unsubscribe(relays_topic1);
    client.subscribe(relays_topic1);
    client.unsubscribe(relays_topic2);
    client.subscribe(relays_topic2);
    client.unsubscribe(relays_topic3);
    client.subscribe(relays_topic3);
  }
}
 

Snezhana

New member
=AK=,
Код:
void loop(){
  static long last_millis;
  if (millis() - last_millis > 1000) {   // every second
    last_millis  = millis();
    client.unsubscribe(relays_topic1);
    client.subscribe(relays_topic1);
    client.unsubscribe(relays_topic2);
    client.subscribe(relays_topic2);
    client.unsubscribe(relays_topic3);
    client.subscribe(relays_topic3);
  }
}
Ваш вариант к сожалению не работает
 

Сергей_Ф

Moderator
Команда форума
Snezhana, это был не вариант, а пример как сделать. В том виде как он есть, он работать не может.
Вам нужно сделать так в Вашем скетче. Скорее всего в строках 57-59 или (может быть и) 83-85.
 
Последнее редактирование:
  • Like
Реакции: =AK=

Сергей_Ф

Moderator
Команда форума
@Snezhana это Ваш скетч? Или Вы его откуда-то взяли?
В чём ещё Вам нужна помощь? Вам уже все сказали как сделать или сделать за Вас?
У меня и проверить не на чем как и что работает. Это же Ваш скетч и Ваш MojorDomo.
Повторю ещё раз, в вашем скетче строки 57-59 надо заменить на
  • client.unsubscribe(relays_topic1);
  • client.subscribe(relays_topic1);
  • client.unsubscribe(relays_topic2);
  • client.subscribe(relays_topic2);
  • client.unsubscribe(relays_topic3);
  • client.subscribe(relays_topic3);
Возможно, это надо сделать и в строках 83-85.
 

Snezhana

New member
@Snezhana это Ваш скетч? Или Вы его откуда-то взяли?
В чём ещё Вам нужна помощь? Вам уже все сказали как сделать или сделать за Вас?
У меня и проверить не на чем как и что работает. Это же Ваш скетч и Ваш MojorDomo.
Повторю ещё раз, в вашем скетче строки 57-59 надо заменить на

Возможно, это надо сделать и в строках 83-85.
Сейчас попробую
 

=AK=

New member
Повторю ещё раз, в вашем скетче строки 57-59 надо заменить на

Возможно, это надо сделать и в строках 83-85.
Я подразумевал, что этот кусок кода вставляeтся в главной loop, то есть, после 200-й строки. Специально показал в начале своего кода void loop(){ - это как раз 200-я строка.
 

Сергей_Ф

Moderator
Команда форума
@=AK= а зачем раз в секунду отписываться и подписываться заново? Проблема ведь только при пропадании питания и последующем старте.
 

=AK=

New member
Девушка просила "надо чтобы MajorDomo периодически сообщал о состояниях топиков или плата делала запрос". Вот я и написал для примера с периодом 1 сек. А оптимально это или нет - пусть сама думает.
 

telobezumnoe

New member
@Snezhana не пользовался этой библиотекой, но для того что бы при переподключении mqtt сервер вновь отправлял последние данные нужно их помечать как "retained"
 

telobezumnoe

New member
@Snezhana это зависит от клиента который публикует данные в mqtt брокер. я пользовался библиотекой от imroy . там при публикации это выглядит примерно так
Код:
client.publish(MQTT::Publish("holl/temp", String(t))
                               .set_retain(1));
так же у вас с мажордомо туда публикуются данные, как их сделать retained надо смотреть в их примерах
 
Последнее редактирование:

Snezhana

New member
@Snezhana это зависит от клиента который публикует данные в mqtt брокер. я пользовался библиотекой от imroy . там при публикации это выглядит примерно так
Код:
client.publish(MQTT::Publish("holl/temp", String(t))
                               .set_retain(1));
так же у вас с мажордомо туда публикуются данные, как их сделать retained надо смотреть в их примерах
Спасибо вам за ответ я нашла галочку retain в MajorDomo поставила и теперь все работает.
Теперь когда ESP8266 включаешь в сеть она принимает состояние которое установлено в MajorDomo ура! Кому нужно картинку приложила.
 

Вложения

Сверху Снизу