• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

ESP32 + MQTT(SSL) + Relay

emaus

New member
Всем привет.
Есть ESP32-Wroom-32 и скетч в котором реализовано сбор данных с датчиков и переключение реле по протоколу MQTT с использованием SSL сертификатов. Сбор данных с датчиков происходит хорошо(проблем нет), но вот не получается дергать реле, скорей всего что-то не так с callback.
Скетч прилагаю, может кто знает что в нем не так.
ЗЫ: Скет собран из нескольких :)
Код:
#include <WiFi.h>
#include "src/dependencies/WiFiClientSecure/WiFiClientSecure.h" //using older WiFiClientSecure
#include <PubSubClient.h>
#include "uptime_formatter.h"
#include "DHT.h"
//#include <time.h>
//#include "secrets.h"

#ifndef SECRET
const char ssid[] = "ssid";
const char pass[] = "pass";

#define HOSTNAME "mqtt_test"

const char *MQTT_HOST = "host";
const int   MQTT_PORT = port;
const char *MQTT_USER = "user"; // leave blank if no credentials used
const char *MQTT_PASS = "pass"; // leave blank if no credentials used

const char* local_root_ca = \
"-----BEGIN CERTIFICATE-----\n" \

"-----END CERTIFICATE-----\n";

#endif

void callback(char* topic, byte* payload, unsigned int length);
//void callback(const char* topic, byte* payload, unsigned int length);

//Relay
const int switchPin0 = 0;
const int switchPin1 = 2;
const int switchPin2 = 4;
const int switchPin3 = 15;

//Sensors
#define DHTPIN1 27    // Pin sur lequel est branché le DHT In sensor
#define DHTPIN2 26    // Pin sur lequel est branché le DHT Out sensor

// Dé-commentez la ligne qui correspond à votre capteur
//#define DHTTYPE DHT11       // DHT 11
#define DHTTYPE1 DHT22         // DHT 22  (AM2302)
#define DHTTYPE2 DHT22         // DHT 22  (AM2302)

//Création des objets
DHT dht1(DHTPIN1, DHTTYPE1);
DHT dht2(DHTPIN2, DHTTYPE1);

//Topic ralay
char const* switchTopic1 = "/greenhouse/in/relay1/linmoto1/";
char const* switchTopic2 = "/greenhouse/in/relay1/linmoto2/";
char const* switchTopic3 = "/greenhouse/in/relay1/pump1/";
char const* switchTopic4 = "/greenhouse/in/relay1/pump2/";

//Topic sensors
#define temperature_sensor1_topic "/greenhouse/in/sensor1/temp/"  //Topic température
#define humidity_sensor1_topic "/greenhouse/in/sensor1/hum/"        //Topic humidité
#define temperature_sensor2_topic "/greenhouse/out/sensor2/temp/"  //Topic température
#define humidity_sensor2_topic "/greenhouse/out/sensor2/hum/"        //Topic humidité

//Topic ESP32 sys RSSI and uptime
#define esp32_rssi "/greenhouse/sys/rssi/"
#define esp32_uptime "/greenhouse/sys/uptime/"

WiFiClientSecure net;
PubSubClient client(net);

time_t now;
unsigned long lastMillis = 0;

void mqtt_connect(){
    while (!client.connected()) {
    //Serial.print("Time:");
    //Serial.print(ctime(&now));
    Serial.print("MQTT connecting");
    if (client.connect(HOSTNAME, MQTT_USER, MQTT_PASS)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, status code =");
      Serial.print(client.state());
      Serial.println("try again in 5 seconds");
      /* Wait 5 seconds before retrying */
      delay(5000);
    }
  }
 
}

void receivedCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Received [");
Serial.print(topic);
Serial.print("]: ");
for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
}

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

  //initialize the switch as an output and set to LOW (off)
  pinMode(switchPin0, OUTPUT); // Relay Switch 1
  digitalWrite(switchPin0, LOW);

  pinMode(switchPin1, OUTPUT); // Relay Switch 2
  digitalWrite(switchPin1, LOW);

  pinMode(switchPin2, OUTPUT); // Relay Switch 3
  digitalWrite(switchPin2, LOW);

  pinMode(switchPin3, OUTPUT); // Relay Switch 4
  digitalWrite(switchPin3, LOW);
 
  //Sensors
  dht1.begin();
  dht2.begin();

  Serial.print("Attempting to connect to SSID: ");
  Serial.println(ssid);
  WiFi.setHostname(HOSTNAME);
  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED){
    Serial.print(".");
    delay(1000);
  }
  Serial.println();
  Serial.print("Connected to ");
  Serial.println(ssid);

  /*
  Serial.print("Setting time using SNTP");
  configTime(+3 * 3600, 0, "0.ru.pool.ntp.org", "1.ru.pool.ntp.org");
  now = time(nullptr);
  while (now < 1510592825) {
    delay(500);
    Serial.print(".");
    now = time(nullptr);
  }
  Serial.println("");
  struct tm timeinfo;
  gmtime_r(&now, &timeinfo);
  Serial.print("Current time: ");
  Serial.print(asctime(&timeinfo));
*/
  net.setCACert(local_root_ca);
  client.setServer(MQTT_HOST, MQTT_PORT);
  client.setCallback(receivedCallback);
  mqtt_connect();
}

// Relay 4
void callback(char* topic, byte* payload, unsigned int length) {
  //convert topic to string to make it easier to work with
  String topicStr = topic;
  //EJ: Note:  the "topic" value gets overwritten everytime it receives confirmation (callback) message from MQTT

  //Print out some debugging info
  Serial.println("Callback update.");
  Serial.print("Topic: ");
  Serial.println(topicStr);

   if (topicStr == "/greenhouse/in/relay1/linmoto1/")
    {

     //turn the switch on if the payload is '1' and publish to the MQTT server a confirmation message
     if(payload[0] == '1'){
       digitalWrite(switchPin0, HIGH);
       client.publish("/greenhouse/in/relay1/linmoto1/confirm/", "1");
       }

      //turn the switch off if the payload is '0' and publish to the MQTT server a confirmation message
     else if (payload[0] == '0'){
       digitalWrite(switchPin0, LOW);
       client.publish("/greenhouse/in/relay1/linmoto1/confirm/", "0");
       }
     }

     // EJ: copy and paste this whole else-if block, should you need to control more switches
     else if (topicStr == "/greenhouse/in/relay1/linmoto2/")
     {
     //turn the switch on if the payload is '1' and publish to the MQTT server a confirmation message
     if(payload[0] == '1'){
       digitalWrite(switchPin1, HIGH);
       client.publish("/greenhouse/in/relay1/linmoto2/confirm/", "1");
       }

      //turn the switch off if the payload is '0' and publish to the MQTT server a confirmation message
     else if (payload[0] == '0'){
       digitalWrite(switchPin1, LOW);
       client.publish("/greenhouse/in/relay1/linmoto2/confirm/", "0");
       }
     }
     else if (topicStr == "/greenhouse/in/relay1/pump1/")
     {
     //turn the switch on if the payload is '1' and publish to the MQTT server a confirmation message
     if(payload[0] == '1'){
       digitalWrite(switchPin2, HIGH);
       client.publish("/greenhouse/in/relay1/pump1/confirm/", "1");
       }

      //turn the switch off if the payload is '0' and publish to the MQTT server a confirmation message
     else if (payload[0] == '0'){
       digitalWrite(switchPin2, LOW);
       client.publish("/greenhouse/in/relay1/pump1/confirm/", "0");
       }
     }
     else if (topicStr == "/greenhouse/in/relay1/pump2/")
     {
     //turn the switch on if the payload is '1' and publish to the MQTT server a confirmation message
     if(payload[0] == '1'){
       digitalWrite(switchPin3, HIGH);
       client.publish("/greenhouse/in/relay1/pump2/confirm/", "1");
       }

      //turn the switch off if the payload is '0' and publish to the MQTT server a confirmation message
     else if (payload[0] == '0'){
       digitalWrite(switchPin3, LOW);
       client.publish("/greenhouse/in/relay1/pump2/confirm/", "0");
       }
     }
}

void loop(){
  now = time(nullptr);
  //Lecture de l'humidité ambiante
   float h1 = dht1.readHumidity();
   float h2 = dht2.readHumidity();
   // Lecture de la température en Celcius
   float t1 = dht1.readTemperature();
   float t2 = dht2.readTemperature();
   
  if (WiFi.status() != WL_CONNECTED){
    Serial.print("Checking wifi");
    while (WiFi.waitForConnectResult() != WL_CONNECTED)
    {
      WiFi.begin(ssid, pass);
      Serial.print(".");
      delay(10);
    }
    Serial.println("connected");
  }
  else{
    if (!client.connected())
    {
      mqtt_connect();
    }
    else
    {
      client.loop();
    }
  }

  if (millis() - lastMillis > 5000) {
    lastMillis = millis();
    client.publish(temperature_sensor1_topic, String(t1).c_str(), true);   //Publie la température sur le topic temperature_topic
    client.publish(humidity_sensor1_topic, String(h1).c_str(), true);      //Et l'humidité
    client.publish(temperature_sensor2_topic, String(t2).c_str(), true);   //Publie la température sur le topic temperature_topic
    client.publish(humidity_sensor2_topic, String(h2).c_str(), true);      //Et l'humidité
    client.publish(esp32_uptime, String("up " + uptime_formatter::getUptime()).c_str(), true); //systeam uptime
    client.publish(esp32_rssi, String(WiFi.RSSI()).c_str(), true); //systeam rssi
  }
}
 

Алексей.

Active member
Вы сообщаете клиенту какую функцию вызывать client.setCallback(receivedCallback); при поручении сообщения,
а подписку на сообщения не выполняете, client.subscribe("inTopic");
клиент, соединившись с брокером не сообщает на какие топики он подписан.
 

emaus

New member
Вы сообщаете клиенту какую функцию вызывать client.setCallback(receivedCallback); при поручении сообщения,
а подписку на сообщения не выполняете, client.subscribe("inTopic");
клиент, соединившись с брокером не сообщает на какие топики он подписан.
Спасибо, все заработало :)
 

kamfur

New member
Вы сообщаете клиенту какую функцию вызывать client.setCallback(receivedCallback); при поручении сообщения,
а подписку на сообщения не выполняете, client.subscribe("inTopic");
клиент, соединившись с брокером не сообщает на какие топики он подписан.
Спасибо мне тоже очень помогло, 2 недели бился, но не знаю как работать с классами библиотек. СПС
 
Сверху Снизу