Вопрос по MQTT

lisishe
Offline
Зарегистрирован: 20.06.2017

Вопрос можети нубский, но чёт не могу сообразить ( нуб нубом) как в функции void loop() получить значение топика чтобы логику писать в нём а не в нутри void callback а в void loop(), а то во всех примерах разбор подпискии идёт в нутри void callback

void loop() {

  client.loop();
  
vikl_1.update();

  // Get the updated value :
  int stat_vikl_1 = vikl_1.read();
  int value2 = 0; // тут должно быть значение топика на который подписались
  
  if ( stat_vikl_1 == LOW || value2 == LOW ) {
    digitalWrite(RELAY_1, HIGH );
  } 
  else {
    digitalWrite(RELAY_1, LOW );
  }
}

// пример функции

void callback(char* topic, byte* payload, unsigned int length) {

  if ((char)subscribe[0] == '1') {
    rState1 = true;
    digitalWrite(RELAY_1, rState1);   // Turn the LED on (Note that LOW is the voltage level
      } else {
    rState1 = false;
    digitalWrite(RELAY_1, rState1);  // Turn the LED off by making the voltage HIGH
  }  
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Остальной скетч секретный? Кто этот колбэк вызывает, когда и зачем нам догадываться нужно?

lisishe
Offline
Зарегистрирован: 20.06.2017

скетча рабочего ещё нет, только наброски

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Bounce2.h>

//-----------------------------
const char* ssid = "11111";
const char* pass = "22222";
IPAddress server (192,168,1,120);
int mqtt_port = 1883;
const char* mqtt_user = "33333";
const char* mqtt_pass = "444444";

#define RELAY_1 5
#define BUTTON_1 4
#define BUTTON_2 14 // проходной переключатель
//#define humidity_topic "sensors/humidity_1"
#define relays_topic "dom/koridor/relay1/status"
#define relays_regim "dom/koridor/relay1/regim"

WiFiClient wclient;
PubSubClient client(wclient, server);

boolean rState1 = false;
boolean btnPress = false;
boolean regim = false;
boolean lastbtnStat = false;
boolean lastbtnStat2 = false;

Bounce vikl_1 = Bounce(); 

void setup() {
  pinMode(RELAY_1, OUTPUT);     // инициализация пинов реле и выключателей
  pinMode(BUTTON_1, INPUT);
  //pinMode(BUTTON_2, INPUT);
  vikl_1.attach(BUTTON_1);
  vikl_1.interval(5); // interval in ms
  
  digitalWrite(RELAY_1, rState1);
  Serial.begin(115200);   

  //client.setCallback(callback);
  //delay(100);
  //WiFi.begin(ssid, password);
  //delay(6000);
  //client.connect("ESP8266Client");
 
  connect_wifi();                     // подключение к сети и брокеру

  client.subscribe(relays_topic);
  client.subscribe(relays_regim);
  
  // lastbtnStat2 = digitalRead(BUTTON_2);
}


void loop() {

  client.loop();
  
vikl_1.update();

  // Get the updated value :
  int stat_vikl_1 = vikl_1.read();
  int value2 = 0;
  
  if ( stat_vikl_1 == LOW || value2 == LOW ) {
    digitalWrite(RELAY_1, HIGH );
  } 
  else {
    digitalWrite(RELAY_1, LOW );
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
    if ((char)subscribe[0] == '1') {
    rState1 = true;
    digitalWrite(RELAY_1, rState1);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is acive low on the ESP-01)
  } else {
    rState1 = false;
    digitalWrite(RELAY_1, rState1);  // Turn the LED off by making the voltage HIGH
  }  
}

void connect_MQTT() {
  // Loop until we're reconnected
 if (WiFi.status() == WL_CONNECTED) {
    if (!client.connected()) {
      Serial.println("Connecting to MQTT server");
      if (client.connect(MQTT::Connect("arduinoClient")
      .set_auth(mqtt_user, mqtt_pass))) {
        Serial.println("Подключились к MQTT серверу");
      } else {
        Serial.println("Не удаётся подключится к MQTT серверу");   
      }
    }
  }
}

void connect_wifi() {

  if (WiFi.status() != WL_CONNECTED) {
    Serial.print("Подключение к WiFi-");
    Serial.print(ssid);
    Serial.println("...");
    WiFi.begin(ssid, pass);

    if (WiFi.waitForConnectResult() != WL_CONNECTED)
       
    Serial.println("WiFi подключён");
    connect_MQTT();
    
     }
     else
     {
       Serial.println("Не удалось подключится к WiFi");
     }
 
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, в таком виде (с закомментированной строкой 41) callback не вызывается вовсе.

lisishe
Offline
Зарегистрирован: 20.06.2017

вот в этм и пытаюсь разобраться, где и как правльно это сделать. В примерах этот класс обьявляется в функции подключения к брокеру (мне это не нравится) и там же стразу идёт логика  обработки полученных сообщений, вот и хочу разобраться как правильно и как работает. ну и наверняка просто туп не понимаю элементарных вещей)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А в чём Ваша проблема? Для чего Вам нужно получать всё в функции loop? Чем Вам callback не угодила.

Сделать-то это можно, но я не понимаю зачем и потому не вижу "граблей".

b707
Offline
Зарегистрирован: 26.05.2017

lisishe пишет:

вот в этм и пытаюсь разобраться, где и как правльно это сделать. В примерах этот класс обьявляется в функции подключения к брокеру (мне это не нравится) и там же стразу идёт логика  обработки полученных сообщений,

простите, а чем вам это не нравится? Смысл callback - чтобы вы в своей программе могли выполнять какие-то операции во время таймаутов сетевых соединений. Если вам это не надо - можете вообще этим не пользоваться

UPD - посмотрел либу - был неправ. Смысл callback - вернуть вам топик и прочую инфу. Без вызова callback вы ее, похоже, просто не получите. Если вам не нравится обрабатывать ее тут же - тогда просто запоминайте ее, а обрабатывайте потом. Но непонятно, зачем так делать

lisishe
Offline
Зарегистрирован: 20.06.2017

ну не хотелось бы писать логику в теле функции) (как я понял основной код в ардуино вызывается и работает в loop, вот это и хотелось получить и сомения в доступности переменных одной функции в теле другой) как-то на мой взглдя не правильно совать логику по функциям). пойду дальше осмысливать значение этой функции (callback) и разибраться со свойствами класса.        п.с. я не программист)

b707
Offline
Зарегистрирован: 26.05.2017

lisishe пишет:

ну не хотелось бы писать логику в теле функции) (как я понял основной код в ардуино вызывается и работает в loop, вот это и хотелось получить и сомения в доступности переменных одной функции в теле другой) как-то на мой взглдя не правильно совать логику по функциям). пойду дальше осмысливать значение этой функции (callback) и разибраться со свойствами класса.        п.с. я не программист)

 Желание поместить все в loop() - это типичная ошибка новичка. "Совать логику по функциям" - это не только не ошибка, это как раз более правильный и разумный стиль программирования. В программе, в которой в loop вы видите только вызовы десятка функций и больше ничего - разбираться значительно проще, чем в типичном коде новичка, где все запихано в бесконечный loop().

А сомнения в доступности переменных одной функции в теле другой - это верное сомнение, но для этого существуют глобальные переменные.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

lisishe пишет:

 как-то на мой взглдя не правильно совать логику по функциям

Это как раз правильно.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Вообще-то все банально просто

void Handler() {} // это у нас обработчик.
bool event = 0; // это у нас событие
void callback(bool _event, void (*_Handler)() ) {
  if (_event) _Handler();
}

void setup() {
}

void loop() {
  // вариант 1
  if (event) Handler();
  // вариант 2 с callback
  callback(event, Handler);
}

Остальное это просто варианты и ничего больше.

b707
Offline
Зарегистрирован: 26.05.2017

код какой-то нелогичный. Или это только теоретический пример? Callback получает и ивент и хендлер "снаружи", а внутри всего лишь соединяет их друг с другом? А смысл?

Вот так было бы полезнее:

void callback(int  _event) {
  if (_event == 0) _Handler0();
  else if (_event == 1) _Handler1();
  else if (_event == 2) _Handler2();
....
else if (_event == 100) _Handler100();
}

void setup() {
}

void loop() {
  
  callback(event);
}

или через case

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Я же сказал: остальное - варианты. А как ивенты , данные для определение иветнов и хендлеров попадают в калбек функцию не важно. Ведь могут попасть как глобальные переменные, а может засунуты в условие функции. Я чаще использую классы. В классах возможна инкапсуляция данных и куча различных методов в одной куче. Чего одиночная фунция лишена.

b707
Offline
Зарегистрирован: 26.05.2017

qwone пишет:

В классах возможна инкапсуляция данных и куча различных методов в одной куче. Чего одиночная фунция лишена.

хм... зато метод класса в виде хендлера так просто по ссылке не передать. Очень извращаться придется... Проще всего, если это вызов метода для конкретного экземпляра - тогда обернуть его в обычную "одинокую функцию" и передавать по ссылке без всякого ООП :)

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

lisishe пишет:

пойду дальше осмысливать значение этой функции (callback) и разибраться со свойствами класса.        п.с. я не программист)

шо там разбираться? - она делает

23   if ((char)subscribe[0] == '1') {
24     rState1 = true;
25     digitalWrite(RELAY_1, rState1);   // Turn the LED on (Note that LOW is the voltage level
26       else {
27     rState1 = false;
28     digitalWrite(RELAY_1, rState1);  // Turn the LED off by making the voltage HIGH
29   

п.с. я не программист - какого класса? О_О

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Вот я не пойму , зачем передавать метод класса в качестве хендлера. Это же глупо. То что передавать можно, так это ответ Клопауцию , зачем в библиотеке 2 файла .h и .сpp.  Так вот для этого.  Если классы и их методы, то это прерогатива разработчика класса. А вот хенлеры это дело пользователя. Опять же есть классы, а есть объекты по классам. Это функции сами по себе . Сама себе и "класс", сама себе и "метод класса", сама себе и "объект класса". Так что проще через обычные функции. Я и это пробовал. В Qt  есть специальные функции для коннектов методов и слотов предствителей классов. Я ими не пользуюсь, так как много текста будет.

b707
Offline
Зарегистрирован: 26.05.2017

qwone пишет:

В Qt  есть специальные функции для коннектов методов и слотов предствителей классов. Я ими не пользуюсь, так как много текста будет.

оффтоп конечно, но можно в 2-3х предложениях - что не так с сигналами и слотами в Qt? Я когда-то пробовал писать в Qt - и для меня как раз сигналы и слоты показались наиболее удобным и простым механизмом... в отличии в целом от написания графического интерфейса. который я не понимаю и не люблю :)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

С Qt скорее всего организовано так, как я пишу это ручками. Создается или внешний, или внутрений обработчик в одном представителе, который дергает переменную в другом. Вот только это все очень замаскировано дополнительной функцией или графическим интерфейсом среды разработки. Вот только я пришел к этому самостоятельно, просто следуя по ходу развития программирования вообще и в частности в Си. А вот на счет графического интерфейса, так все там просто и сложно.  Просто, если вы поймете концепцию делегирования вместо множественного наследования и придумаете кучу английских слов для обозначения  переменных и методов.

OOM
Offline
Зарегистрирован: 07.01.2017

Подскажите что значит подписаться (SUBSCRIBE) и отписаться (UNSUBSCRIBE) на топик

sadman41
Offline
Зарегистрирован: 19.10.2016

1) Брокер начнет слать клиенту обновления топика
2) Брокер перестанет слать обновления.

sergei_a88@bk.ru
Offline
Зарегистрирован: 22.09.2019
#include <SPI.h>                 // Библиотека SPI шины
#include <Ethernet.h>            // Ethernet библиотека
#include <PubSubClient.h>        // Библиотека MQTT


int LAMP0, LAMP1, LAMP2, LAMP3, LAMP4, LAMP5, LAMP6, LAMP7, LAMP8, LAMP9, LAMP10, LAMP11, LAMP12;

int relay1 = 40;
int relay2 = 41;
int relay3 = 42;
int relay4 = 43;

byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
byte serverArduino[] = { 192, 168, 7, 150 };
byte ip[]     = { 192, 168, 7, 250 };

void callback(char* topic, byte* payload, unsigned int length)
{
  int r,hl;
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");

  char receivedChar = (char)payload[0];
  Serial.print(receivedChar);
  if(receivedChar=='0')
    hl = LOW;
    else
    hl = HIGH; 
       if(String(topic)=="PowerPanel/relay1")
    r = relay1;
  else if(String(topic)=="PowerPanel/relay2")
    r = relay2;
   else if(String(topic)=="PowerPanel/relay3")
    r = relay3;
   else if(String(topic)=="PowerPanel/relay4")
   digitalWrite(relay4, HIGH);   // зажигаем светодиод
   delay(500);              // ждем секунду
   digitalWrite(relay4, LOW);    // выключаем светодиод
   delay(500);              // ждем секунду
    
  digitalWrite(r, hl);
  Serial.println();
}

EthernetClient ethClient;
PubSubClient client(serverArduino, 1883, callback, ethClient);

void reconnect()
{
// Loop until we're reconnected
  while (!client.connected())
{
    Serial.println("Attempting MQTT connection...");
// Attempt to connect
    if (client.connect("arduinoPowerPanel"))
        {
        Serial.println("connected");
        }
        else
        {
          Serial.print("failed, rc=");
          Serial.print(client.state());
          Serial.println(" try again in 5 seconds");
          delay(5000);
        }
    }
}

void setup()
{
  Ethernet.begin(mac, ip);          // Инициализируем mac, ip
  Serial.begin(9600);
  Serial.println(F("Relay Test!"));    /* Тестовое сообщ. при откр. Монитора порта.
                                          Так же обёртываем сообщения
                                          в макрос F() для экономии ОЗУ */
  pinMode (22, INPUT_PULLUP);
  pinMode (24, INPUT_PULLUP);
  pinMode (26, INPUT_PULLUP);
  pinMode (28, INPUT_PULLUP);
  pinMode (30, INPUT_PULLUP);
  pinMode (31, INPUT_PULLUP);
  pinMode (32, INPUT_PULLUP);
  pinMode (33, INPUT_PULLUP);
  pinMode (34, INPUT_PULLUP);  
  pinMode (35, INPUT_PULLUP);
  pinMode (36, INPUT_PULLUP);
  pinMode (37, INPUT_PULLUP);  
  pinMode (38, INPUT_PULLUP);     
 
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);



 
  if (client.connect("arduinoPowerPanel"))
   {
    Serial.print("online");
    client.publish("PowerPanel/relay1", "1");
    client.subscribe("PowerPanel/relay1");
    client.publish("PowerPanel/relay2", "1");
    client.subscribe("PowerPanel/relay2");
    client.publish("PowerPanel/relay3", "1");
    client.subscribe("PowerPanel/relay3");
    client.publish("PowerPanel/relay4", "1");
    client.subscribe("PowerPanel/relay4");
   }
}


void loop()
{
   if (!client.connected())
      {
       reconnect();
      }
  client.loop();
  
  LAMP0 = !digitalRead (22); 
  if (LAMP0 == 0) {
          Serial.print(" LAMP0 - "); Serial.println(0);
          client.publish("home/data/status/Relay/0", "0");
          }else if (LAMP0 == 1) {
          Serial.print(" LAMP0 - "); Serial.println(1);
          client.publish("home/data/status/Relay/0", "1");
          }
         delay(100);
 LAMP1 = !digitalRead (24); 
  if (LAMP1 == 0) {
          Serial.print(" LAMP1 - "); Serial.println(0);
          client.publish("home/data/status/Relay/1", "0");
          }else if (LAMP1 == 1) {
          Serial.print(" LAMP1 - "); Serial.println(1);
          client.publish("home/data/status/Relay/1", "1");
          }
          delay(100);
 LAMP2 = !digitalRead (26); 
  if (LAMP2 == 0) {
          (" LAMP2 - "); Serial.println(0);
          client.publish("home/data/status/Relay/2", "0");
          }else if (LAMP2 == 1) {
          Serial.print(" LAMP2 - "); Serial.println(1);
          client.publish("home/data/status/Relay/2", "1");
          }
          delay(100);
 LAMP3 = !digitalRead (28); 
  if (LAMP3 == 0) {
          ///Serial.print(" LAMP3 - "); Serial.println(0);
          client.publish("home/data/status/Relay/3", "0");
          }else if (LAMP3 == 1) {
          ///Serial.print(" LAMP3 - "); Serial.println(1);
          client.publish("home/data/status/Relay/3", "1");
          }
          delay(100);
 
  LAMP4 = !digitalRead (30); 
  if (LAMP4 == 0) {
          ///Serial.print(" LAMP4 - "); Serial.println(0);
          client.publish("home/data/status/Relay/4", "0");
          }else if (LAMP4 == 1) {
          ///Serial.print(" LAMP4 - "); Serial.println(1);
          client.publish("home/data/status/Relay/4", "1");
          }
          delay(100);
 LAMP5 = !digitalRead (31); 
  if (LAMP5 == 0) {
          ///Serial.print(" LAMP5 - "); Serial.println(0);
          client.publish("home/data/status/Relay/5", "0");
          }else if (LAMP5 == 1) {
          ///Serial.print(" LAMP5 - "); Serial.println(1);
          client.publish("home/data/status/Relay/5", "1");
          }
          delay(100);
 LAMP6 = !digitalRead (32); 
  if (LAMP6 == 0) {
          ///Serial.print(" LAMP6 - "); Serial.println(0);
          client.publish("home/data/status/Relay/6", "0");
          }else if (LAMP6 == 1) {
          ///Serial.print(" LAMP6 - "); Serial.println(1);
          client.publish("home/data/status/Relay/6", "1");
          }
         delay(100);
  LAMP7 = !digitalRead (33); 
  if (LAMP7 == 0) {
          ///Serial.print(" LAMP7 - "); Serial.println(0);
          client.publish("home/data/status/Relay/7", "0");
          }else if (LAMP7 == 1) {
          ///Serial.print(" LAMP7 - "); Serial.println(1);
          client.publish("home/data/status/Relay/7", "1");
          }
         delay(100);
  LAMP8 = !digitalRead (34); 
  if (LAMP8 == 0) {
          ///Serial.print(" LAMP8 - "); Serial.println(0);
          client.publish("home/data/status/Relay/8", "0");
          }else if (LAMP8 == 1) {
          ///Serial.print(" LAMP8 - "); Serial.println(1);
          client.publish("home/data/status/Relay/8", "1");
          }
          delay(100);
  LAMP9 = !digitalRead (35); 
  if (LAMP9 == 0) {
          ///Serial.print(" LAMP9 - "); Serial.println(0);
          client.publish("home/data/status/Relay/9", "0");
          }else if (LAMP9 == 1) {
          ///Serial.print(" LAMP9 - "); Serial.println(1);
          client.publish("home/data/status/Relay/9", "1");
          }
          delay(100);
  LAMP10 = !digitalRead (36); 
  if (LAMP10 == 0) {
          ///Serial.print(" LAMP10 - "); Serial.println(0);
          client.publish("home/data/status/Relay/10", "0");
          }else if (LAMP10 == 1) {
          ///Serial.print(" LAMP10 - "); Serial.println(1);
          client.publish("home/data/status/Relay/10", "1");
          }
          delay(100);
  LAMP11 = !digitalRead (37); 
  if (LAMP11 == 0) {
          ///Serial.print(" LAMP11 - "); Serial.println(0);
          client.publish("home/data/status/Relay/11", "0");
          }else if (LAMP11 == 1) {
          ///Serial.print(" LAMP11 - "); Serial.println(1);
          client.publish("home/data/status/Relay/11", "1");
          }
         delay(100);
   LAMP12 = !digitalRead (38); 
 if (LAMP12 == 0) {
          ///Serial.print(" LAMP12 - "); Serial.println(0);
          client.publish("home/data/status/Relay/12", "0");
          }else if (LAMP12 == 1) {
          ///Serial.print(" LAMP12 - "); Serial.println(1);
          client.publish("home/data/status/Relay/12", "1");
          }
        delay(100);
} 

Доброго времени суток !

Я далеко не программист, прошу не судить строго!

Стояла задача считать значения логической единицы с пина и передать по MQTT в MJDOM.

Задачу выполнил вроде все работает.

Также необходимо по MQTT включать РЕЛЕ тут вроде все получилось, но возникла вот такая проблема при обкатке, спустя час два работы arduino перестает включать реле, но при этом логические единица и ноль (от первой задачи) в мониторе порта отображаются корректно и MJDOM. Перезагружаем arduino и все вновь на какое то время работает.

 

 

 

 

 

anarch
Offline
Зарегистрирован: 10.09.2017

Что то мне подсказывает, что из Callback убрать нужно delay.

Да и этот момент char receivedChar = (char)payload[0]; я бы заменил как в мануале на:

 byte* p = (byte*)malloc(length);
 memcpy(p,payload,length);
 client.publish("outTopic", p, length);
 free(p);

Ну и на закуску проверить не обрывается соединение где нибудь.

sergei_a88@bk.ru
Offline
Зарегистрирован: 22.09.2019

"Что то мне подсказывает, что из Callback убрать нужно delay"

Вынести в отдельную операцию (функцию), так получается что? От него нужно что бы реле кратко временно выключилось и выключилось.

"Ну и на закуску проверить не обрывается соединение где нибудь."

Ну я так понимаю если первая часть которая работает по MQTT значит cоединение есть. Тут я так понял именно проблема с callback

то что написали пошел пробовать  

anarch
Offline
Зарегистрирован: 10.09.2017

Да и вообще в callback я бы сделал проверку из какого топика прилетело, а затем, что прилетело, ну и дернуть реле. 

sergei_a88@bk.ru
Offline
Зарегистрирован: 22.09.2019

Не удобно просить ну так как я уже на это убил 7 дней, все же попрошу можете помочь допилить. а то про проверку написали я уже в ступаре ...

Просто я так понял где используют конструкцию типа:

void callback(char* topic, byte* payload, unsigned int length) {
  byte* p = (byte*)malloc(length);
  memcpy(p,payload,length);
  client.publish("outTopic", p, length);
  free(p);
   if(String(pub.topic()) =="PowerPanel/relay1")
   {
    digitalWrite(relay1,HIGH);
   }
   }
Ошибка 

'pub' was not declared in this scope

все что я пересмотрел везде используется Wifi а в моем случаи его нет вот и в ступаре я ... (((

Спасибо!

anarch
Offline
Зарегистрирован: 10.09.2017
void reconnect()
{
    // Loop until we're reconnected
    while (!client.connected())
    {
        Serial.print("Attempting MQTT connection...");
        // Attempt to connect
        if (client.connect("arduinoClient"))
        {
            Serial.println("connected");
            client.publish("PowerPanel/relay1", "1");
            client.subscribe("PowerPanel/relay1");
            client.publish("PowerPanel/relay2", "1");
            client.subscribe("PowerPanel/relay2");
            client.publish("PowerPanel/relay3", "1");
            client.subscribe("PowerPanel/relay3");
            client.publish("PowerPanel/relay4", "1");
            client.subscribe("PowerPanel/relay4");
        }
        else
        {
            Serial.print("failed, rc=");
            Serial.print(client.state());
            Serial.println(" try again in 5 seconds");
            // Wait 5 seconds before retrying
            delay(5000);
        }
    }
}

void callback(char *topic, byte *payload, unsigned int length)
{
    Serial.print("Message arrived [");
    Serial.print(topic);
    Serial.print("] ");
    if (strcmp(topic, "PowerPanel/relay1"))
    {
        if ((char)payload[0] == '1')
            digitalWrite(relay1, HIGH);
        else
            digitalWrite(relay1, LOW);
    }
    else if (strcmp(topic, "PowerPanel/relay2"))
    {
        if ((char)payload[0] == '1')
            digitalWrite(relay2, HIGH);
        else
            digitalWrite(relay2, LOW);
    }
    Serial.println();
}

Возможно из за того что вы не в reconect подписываетесь на топики.

Так что то же стоит перенести из setup().

Ну и остальное перепроверяйте и пробуйте.

sergei_a88@bk.ru
Offline
Зарегистрирован: 22.09.2019

Спасибо пошел пробовать что получится интересно ))) Спасибо ! а как насчет того что бы вне callback сделать влючение и выключение реле

sergei_a88@bk.ru
Offline
Зарегистрирован: 22.09.2019

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

relay1 на 40 пине

PowerPanel/relay1 1

отправляешь в топик и включается 41 пин, хотя relay1 на 40

PowerPanel/relay2 1

включается 40 пин .... 

как такое может быть все пересмотрел на два раза ...

Вижу тока то что в порт не прилетает 0 или 1 сообщение ... только надпись топика

sadman41
Offline
Зарегистрирован: 19.10.2016

Наводящий вопрос - что произойдёт в этом условии, если topic эквивалентен "PowerPanel/relay1":   if (strcmp(topic, "PowerPanel/relay1")) ?

sergei_a88@bk.ru
Offline
Зарегистрирован: 22.09.2019

я так понимаю если наводящий вопрос задан тот тут ошибка в структуре выполняемой операции... должно быть

else if (strcmp(topic, "PowerPanel/relay1")) 

а выше общий if

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Реле у тебя управляюца нулем, видимо. 

sergei_a88@bk.ru
Offline
Зарегистрирован: 22.09.2019
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
 
Да нет вроде 
DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Хорошо. По- другому спрошу.  Каким уровнем включается реле? 

sergei_a88@bk.ru
Offline
Зарегистрирован: 22.09.2019

В текущий момент времени реле едут только у меня сейчас я тыстовый вариант на макете собираю включаю вместо реле светодиоды. Вот то что сейчас по коду у меня ткните где мог накосячить в нем...

Сейчас проблема в том что включая relay1 включается relay2 

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

 

 

#include <SPI.h>                 // Библиотека SPI шины
#include <Ethernet.h>            // Ethernet библиотека
#include <PubSubClient.h>        // Библиотека MQTT

int LAMP0, LAMP1, LAMP2, LAMP3, LAMP4, LAMP5, LAMP6, LAMP7, LAMP8, LAMP9, LAMP10, LAMP11, LAMP12;
int relay1 = 40;
int relay2 = 41;
int relay3 = 42;
int relay4 = 43;

byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
byte serverArduino[] = { 192, 168, 7, 150 };
byte ip[]     = { 192, 168, 7, 250 };

void callback(char* topic, byte* payload, unsigned int length);
EthernetClient ethClient;
PubSubClient client(serverArduino, 1883, callback, ethClient);

void callback(char *topic, byte *payload, unsigned int length)
{
    Serial.print("Message arrived [");
    Serial.print(topic);
    Serial.print("] ");
    if (strcmp(topic, "PowerPanel/relay1"))
    {
        if ((char)payload[0] == '1')
            digitalWrite(relay1, HIGH);
        else
            digitalWrite(relay1, LOW);
    }
    else if (strcmp(topic, "PowerPanel/relay2"))
    {
        if ((char)payload[0] == '1')
            digitalWrite(relay2, HIGH);
        else
            digitalWrite(relay2, LOW);
    }
    Serial.println();
}
  

void reconnect()
{
    // Loop until we're reconnected
    while (!client.connected())
    {
        Serial.print("Attempting MQTT connection...");
        // Attempt to connect
        if (client.connect("arduinoClient"))
        {
            Serial.println("connected");
            client.publish("PowerPanel/relay1", "1");
            client.subscribe("PowerPanel/relay1");
            client.publish("PowerPanel/relay2", "1");
            client.subscribe("PowerPanel/relay2");
            client.publish("PowerPanel/relay3", "1");
            client.subscribe("PowerPanel/relay3");
            client.publish("PowerPanel/relay4", "1");
            client.subscribe("PowerPanel/relay4");
        }
        else
        {
            Serial.print("failed, rc=");
            Serial.print(client.state());
            Serial.println(" try again in 5 seconds");
            // Wait 5 seconds before retrying
            delay(5000);
        }
    }
}


void setup()
{
  Ethernet.begin(mac, ip);          // Инициализируем mac, ip
  Serial.begin(9600);
  Serial.println(F("Relay Test!"));    /* Тестовое сообщ. при откр. Монитора порта.
                                          Так же обёртываем сообщения
                                          в макрос F() для экономии ОЗУ */
  pinMode (22, INPUT_PULLUP);
  pinMode (24, INPUT_PULLUP);
  pinMode (26, INPUT_PULLUP);
  pinMode (28, INPUT_PULLUP);
  pinMode (30, INPUT_PULLUP);
  pinMode (31, INPUT_PULLUP);
  pinMode (32, INPUT_PULLUP);
  pinMode (33, INPUT_PULLUP);
  pinMode (34, INPUT_PULLUP);  
  pinMode (35, INPUT_PULLUP);
  pinMode (36, INPUT_PULLUP);
  pinMode (37, INPUT_PULLUP);  
  pinMode (38, INPUT_PULLUP);     
 
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);

}


void loop()
{
   if (!client.connected())
      {
       reconnect();
      }
  client.loop();
 
  LAMP0 = !digitalRead (22); 
  if (LAMP0 == 0) {
          Serial.print(" LAMP0 - "); Serial.println(0);
          client.publish("home/data/status/Relay/0", "0");
          }else if (LAMP0 == 1) {
          Serial.print(" LAMP0 - "); Serial.println(1);
          client.publish("home/data/status/Relay/0", "1");
          }
         delay(100);
 LAMP1 = !digitalRead (24); 
  if (LAMP1 == 0) {
          Serial.print(" LAMP1 - "); Serial.println(0);
          client.publish("home/data/status/Relay/1", "0");
          }else if (LAMP1 == 1) {
          Serial.print(" LAMP1 - "); Serial.println(1);
          client.publish("home/data/status/Relay/1", "1");
          }
          delay(100);
 LAMP2 = !digitalRead (26); 
  if (LAMP2 == 0) {
          (" LAMP2 - "); Serial.println(0);
          client.publish("home/data/status/Relay/2", "0");
          }else if (LAMP2 == 1) {
          Serial.print(" LAMP2 - "); Serial.println(1);
          client.publish("home/data/status/Relay/2", "1");
          }
          delay(100);
 LAMP3 = !digitalRead (28); 
  if (LAMP3 == 0) {
          ///Serial.print(" LAMP3 - "); Serial.println(0);
          client.publish("home/data/status/Relay/3", "0");
          }else if (LAMP3 == 1) {
          ///Serial.print(" LAMP3 - "); Serial.println(1);
          client.publish("home/data/status/Relay/3", "1");
          }
          delay(100);
 
  LAMP4 = !digitalRead (30); 
  if (LAMP4 == 0) {
          ///Serial.print(" LAMP4 - "); Serial.println(0);
          client.publish("home/data/status/Relay/4", "0");
          }else if (LAMP4 == 1) {
          ///Serial.print(" LAMP4 - "); Serial.println(1);
          client.publish("home/data/status/Relay/4", "1");
          }
          delay(100);
 LAMP5 = !digitalRead (31); 
  if (LAMP5 == 0) {
          ///Serial.print(" LAMP5 - "); Serial.println(0);
          client.publish("home/data/status/Relay/5", "0");
          }else if (LAMP5 == 1) {
          ///Serial.print(" LAMP5 - "); Serial.println(1);
          client.publish("home/data/status/Relay/5", "1");
          }
          delay(100);
 LAMP6 = !digitalRead (32); 
  if (LAMP6 == 0) {
          ///Serial.print(" LAMP6 - "); Serial.println(0);
          client.publish("home/data/status/Relay/6", "0");
          }else if (LAMP6 == 1) {
          ///Serial.print(" LAMP6 - "); Serial.println(1);
          client.publish("home/data/status/Relay/6", "1");
          }
         delay(100);
  LAMP7 = !digitalRead (33); 
  if (LAMP7 == 0) {
          ///Serial.print(" LAMP7 - "); Serial.println(0);
          client.publish("home/data/status/Relay/7", "0");
          }else if (LAMP7 == 1) {
          ///Serial.print(" LAMP7 - "); Serial.println(1);
          client.publish("home/data/status/Relay/7", "1");
          }
         delay(100);
  LAMP8 = !digitalRead (34); 
  if (LAMP8 == 0) {
          ///Serial.print(" LAMP8 - "); Serial.println(0);
          client.publish("home/data/status/Relay/8", "0");
          }else if (LAMP8 == 1) {
          ///Serial.print(" LAMP8 - "); Serial.println(1);
          client.publish("home/data/status/Relay/8", "1");
          }
          delay(100);
  LAMP9 = !digitalRead (35); 
  if (LAMP9 == 0) {
          ///Serial.print(" LAMP9 - "); Serial.println(0);
          client.publish("home/data/status/Relay/9", "0");
          }else if (LAMP9 == 1) {
          ///Serial.print(" LAMP9 - "); Serial.println(1);
          client.publish("home/data/status/Relay/9", "1");
          }
          delay(100);
  LAMP10 = !digitalRead (36); 
  if (LAMP10 == 0) {
          ///Serial.print(" LAMP10 - "); Serial.println(0);
          client.publish("home/data/status/Relay/10", "0");
          }else if (LAMP10 == 1) {
          ///Serial.print(" LAMP10 - "); Serial.println(1);
          client.publish("home/data/status/Relay/10", "1");
          }
          delay(100);
  LAMP11 = !digitalRead (37); 
  if (LAMP11 == 0) {
          ///Serial.print(" LAMP11 - "); Serial.println(0);
          client.publish("home/data/status/Relay/11", "0");
          }else if (LAMP11 == 1) {
          ///Serial.print(" LAMP11 - "); Serial.println(1);
          client.publish("home/data/status/Relay/11", "1");
          }
         delay(100);
   LAMP12 = !digitalRead (38); 
 if (LAMP12 == 0) {
          ///Serial.print(" LAMP12 - "); Serial.println(0);
          client.publish("home/data/status/Relay/12", "0");
          }else if (LAMP12 == 1) {
          ///Serial.print(" LAMP12 - "); Serial.println(1);
          client.publish("home/data/status/Relay/12", "1");
          }
        delay(100);
} 

 

anarch
Offline
Зарегистрирован: 10.09.2017

sadman41 пишет:

Наводящий вопрос - что произойдёт в этом условии, если topic эквивалентен "PowerPanel/relay1":   if (strcmp(topic, "PowerPanel/relay1")) ?

Точняк! Мой косяк ))

if (!strcmp(topic, "PowerPanel/relay1"))

 

sergei_a88@bk.ru
Offline
Зарегистрирован: 22.09.2019

А почему тут инвертировать strcmp нужно ?

 

и как в не сделать вкл/выкл что бы в callback не использовать delay

anarch
Offline
Зарегистрирован: 10.09.2017

Ну про strcmp можно в гугле спросить.

Да и про то как без delay можно там же найти. "Мигаем светодиодом без delay"

sergei_a88@bk.ru
Offline
Зарегистрирован: 22.09.2019

Пошел на просторы GOOGLE большое спасибо !!!! Не ожидал что на форуме быстро решение найдется... будем тестить скетч дальше на стабильность !!!

 

СПАСИБО !

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sergei_a88@bk.ru пишет:

А почему тут инвертировать strcmp нужно ?

Инвертировать не нужно. Нужно знать, что она возвращает.

sergei_a88@bk.ru
Offline
Зарегистрирован: 22.09.2019

Ясно уже более менее на просторах гугла нашел ответ....