Arduino/ESP32 can't connect to to MQTT broker - c++

I'm working on getting my ESP32 board (also Arduino R3 & Nano) to connect to a HiveMQ broker, but it will not connect. I've tried various ports, different brokers, disabling ad blocking on my network, etc., but nothing seems to make a difference.
#include <Arduino.h>
#include <ArduinoJson.h>
#include <WiFi.h>
#include <PubSubClient.h>
void MQTT_callback(char* topic, byte* message, unsigned int length);
void setup() {
Serial.begin(115200);
while (!Serial);
delay(250);
Serial.println("setup beginning");
Serial.print("Connecting to WiFi...");
WiFi.begin("...", "...");
for (int i=0; i<30 && WiFi.status() != WL_CONNECTED; ++i) {
Serial.print(".");
delay(250);
}
if (WiFi.status() != WL_CONNECTED) {
Serial.println(" failed");
Serial.println("Oh no, no Wifi!? You're back in 1980! That's horrible...");
return;
} else {
Serial.println(" connected!");
}
WiFiClient espClient;
PubSubClient client(espClient);
const char* MQTT_URL = "somereallylongstring.s2.eu.hivemq.cloud";
const int MQTT_PORT = 8883;
const char* MQTT_uid = "...";
const char* MQTT_pwd = "...";
const String MQTT_client = "esp32-client-" + WiFi.macAddress();
client.setServer(MQTT_URL, MQTT_PORT);
client.setCallback(MQTT_callback);
if (!client.connected()) {
Serial.println("Connecting to MQTT broker with client '" + MQTT_client + "'...");
for (int i=0; i<10 && !client.connected(); ++i) {
if (client.connect(MQTT_client.c_str(), MQTT_uid, MQTT_pwd)) {
Serial.println("Connected to MQTT broker");
} else {
Serial.print("Connection to MQTT broker failed: ");
#define C(x) case (x): Serial.println(#x); break;
switch (client.state()) {
C(MQTT_CONNECTION_TIMEOUT)
C(MQTT_CONNECTION_LOST)
C(MQTT_CONNECT_FAILED)
C(MQTT_DISCONNECTED)
C(MQTT_CONNECTED)
C(MQTT_CONNECT_BAD_PROTOCOL)
C(MQTT_CONNECT_BAD_CLIENT_ID)
C(MQTT_CONNECT_UNAVAILABLE)
C(MQTT_CONNECT_BAD_CREDENTIALS)
C(MQTT_CONNECT_UNAUTHORIZED)
}
#undef C
}
}
}
if (client.connected()) {
const char* topic = "/sensors/sean/salt_tank";
StaticJsonDocument<MQTT_MAX_PACKET_SIZE> doc;
doc["ts"] = "2023-01-15 20:24:00";
doc["temp"] = 82.1;
doc["tds"] = 821;
doc["ph"] = 7.6;
String output;
serializeJson(doc, output);
Serial.println("Publishing message to " + String(topic) + output);
client.publish(topic, output.c_str());
}
Serial.println("setup complete!");
}
void loop() {
}
void MQTT_callback(char* topic, byte* message, unsigned int length) {
String msg = "";
for (int i=0; i<length; ++i)
msg += (char)message[i];
Serial.println("Message arrived on topic " + String(topic) + ":");
Serial.println(msg);
}
Here's the output:
22:11:00.629 > setup beginning
22:11:00.631 > Connecting to WiFi........ connected!
22:11:02.001 > Connecting to MQTT broker with client 'esp32-client-08:3A:F2:B8:8B:CC'...
22:11:17.512 > Connection to MQTT broker failed: MQTT_CONNECTION_TIMEOUT
22:11:32.670 > Connection to MQTT broker failed: MQTT_CONNECTION_TIMEOUT
I don't know if this makes a difference, but I'm using an ARM MacBook. I don't know if the difference in libraries could be causing an issue or not. Thanks!

Related

Is it possible to make a sip call over gprs with a SIM800 module?

I have an Asterisk server on cloud and I want ESP32 devices to register as SIP clients and make a VoIP call over GPRS via SIM800 module. AT commands of SIM800 module allows me to make a GPRS connection and I can send http request and send MQTT messages. However, I couldn't find a way to connect to VoIP server, if possible.
My current code establises MQTT connection over GPRS and make calls over GSM but cannot connect to Asterisk:
// ESP32 Configuration
#define TINY_GSM_MODEM_SIM800
#define SerialMon Serial
#define SerialAT Serial2
#define TINY_GSM_DEBUG SerialMon
#define GSM_AUTOBAUD_MIN 9600 /
#define GSM_AUTOBAUD_MAX 38400
#define TINY_GSM_USE_GPRS true
#define PhoneNumber "xxxxxxxxxxxxxxx"
#define rcSwitchInterruptPin 35
#define ENABLE_SIM800C 22
#define BUTTON_PIN 33
#define SOS_BUTTON_ID0 4236140
#define SOS_BUTTON_ID1 4236132
#define SOS_BUTTON_PIN 27
// GPRS internet settings, specific to your SIM card
const char apn[] = "internet";
const char gprsUser[] = "";
const char gprsPass[] = "";
// MQTT settings
const char *broker = "broker.emqx.io";
const int mqttPort = 1883;
const char * clientID = "esp32-client";
const char * mqttUser = "acido";
const char * mqttPassword = "12345678";
#include <TinyGsmClient.h>
#include <PubSubClient.h>
#include <SPI.h>
#include <Wire.h>
#include <PubSubClient.h>
#include <elapsedMillis.h>
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
PubSubClient mqtt(client);
uint32_t lastReconnectAttempt = 0;
void mqttCallback(char *, byte *, unsigned int);
boolean mqttConnect();
void DRE_switch();
elapsedSeconds serialLogSeconds;
unsigned int serialLog_Interval = 3;
elapsedSeconds sinyalBekletme;
unsigned int sinyalBekletme_Interval = 3;
elapsedSeconds sosDelay;
unsigned int sosDelay_Interval = 3;
elapsedSeconds kapiacikDelay;
unsigned int kapiacikDelay_Interval = 3;
elapsedSeconds kapiKapaliDelay;
unsigned int kapiKapaliDelay_Interval = 3;
elapsedSeconds gazDelay;
unsigned int gazDelay_Interval = 3;
elapsedSeconds pirDelay;
unsigned int pirDelay_Interval = 3;
elapsedSeconds dumanDelay;
unsigned int dumanDelay_Interval = 3;
void setup()
{
mqtt.setKeepAlive(60);
// Set console baud rate
SerialMon.begin(9600);
while (!SerialMon)
delay(10);
// !!!!!!!!!!!
mySwitch.enableReceive(35);
pinMode(BUTTON_PIN, INPUT_PULLDOWN);
pinMode(ENABLE_SIM800C, OUTPUT);
digitalWrite(ENABLE_SIM800C, HIGH);
delay(3000);
digitalWrite(ENABLE_SIM800C, LOW);
// !!!!!!!!!!!
TinyGsmAutoBaud(SerialAT, GSM_AUTOBAUD_MIN, GSM_AUTOBAUD_MAX);
delay(6000);
// Restart takes quite some time
// To skip it, call init() instead of restart()
// if (!modem.restart()) {
if (!modem.init()) {
DBG("Failed to restart modem, delaying 10s and retrying");
// restart autobaud in case GSM just rebooted
TinyGsmAutoBaud(SerialAT, GSM_AUTOBAUD_MIN, GSM_AUTOBAUD_MAX);
return;
}
String modemInfo = modem.getModemInfo();
SerialMon.print("setup: Modem Info: ");
SerialMon.println(modemInfo);
SerialMon.print("setup: Waiting for network...");
if (!modem.waitForNetwork())
{
SerialMon.println("setup: fail, wait 5 seconds");
delay(5000);
return;
}
SerialMon.println("setup: success");
if (modem.isNetworkConnected())
SerialMon.println("setup: Network connected");
#if TINY_GSM_USE_GPRS
// GPRS connection parameters are usually set after network registration
SerialMon.print(F("setup: Connecting to apn: "));
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass))
{
SerialMon.println("setup: GPRS Connecting fail, wait 5 seconds");
delay(5000);
return;
}
SerialMon.println("setup: GPRS success");
if (modem.isGprsConnected())
{
SerialMon.println("setup: GPRS connected");
}
#endif
// MQTT Broker setup
mqtt.setServer(broker, mqttPort);
mqtt.setCallback(mqttCallback);
}
void loop()
{
bool result;
// check if we're connected to network
if (!modem.isNetworkConnected())
{
SerialMon.println("loop: modem disconnected");
if (!modem.waitForNetwork(180000L, true))
{
SerialMon.println("loop: modem fail, wait 10 sec");
delay(10000);
return;
}
if (modem.isNetworkConnected())
{
SerialMon.println("loop: Modem re-connected");
}
// And make sure GPRS/EPS is still connected
if (!modem.isGprsConnected())
{
SerialMon.println("loop: GPRS disconnected!");
SerialMon.print(F("loop: Connecting to apn:"));
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass))
{
SerialMon.println("loop: GPRS fail, wait 10 sec");
delay(10000);
return;
}
if (modem.isGprsConnected())
{
SerialMon.println("loop: GPRS reconnected");
}
}
}
// check if we're connected to MQTT
if (!mqtt.connected())
{
SerialMon.println("loop: === mqtt not connected ===");
// Reconnect every 10 seconds
uint32_t t = millis();
if (t - lastReconnectAttempt > 10000L)
{
lastReconnectAttempt = t;
if (mqttConnect())
{
lastReconnectAttempt = 0;
}
}
return;
}
if (digitalRead(BUTTON_PIN) == HIGH)
{
Serial.println("BUTONA BASILDI");
result = modem.callNumber(PhoneNumber);
DBG("Call:", result ? "OK" : "fail");
}
// Check RF signals and publish to MQTT
if (mySwitch.available())
{
int num = mySwitch.getReceivedValue();
Serial.print("Num: ");
Serial.print(num);
Serial.print(" Protocol: ");
Serial.println(mySwitch.getReceivedProtocol());
if (sosDelay >= sosDelay_Interval)
{
if (num == 4236132) // SOS
{
Serial.println("SOS Butonuna Basıldı.");
DRE_switch();
mqtt.publish("CMR/ESP32s/SENSOR/SOS", "SOS"); // Publish message.
result = modem.callNumber(PhoneNumber);
DBG("Call:", result ? "OK" : "fail");
}
else
{
mqtt.publish("CMR/ESP32s/SENSOR/SOS", "0"); // Publish message.
}
sosDelay = 0;
}
if (pirDelay >= pirDelay_Interval)
{
if (num == 8330345)
{
DRE_switch();
Serial.println("HAREKET ALGILANDI.");
mqtt.publish("CMR/ESP32s/SENSOR/PIR", "HAREKET ALGILANDI"); // Publish message.
}
else
{
mqtt.publish("CMR/ESP32s/SENSOR/PIR", "0"); // Publish message
}
pirDelay = 0;
}
if (kapiacikDelay >= kapiacikDelay_Interval)
{
if (num == 5729285) // Kapi acilinca gelen sinyal
{
DRE_switch();
Serial.println("KAPI AÇILDI.");
mqtt.publish("CMR/ESP32s/SENSOR/KAPIACIK", "1"); // Publish message.
}
else
{
mqtt.publish("CMR/ESP32s/SENSOR/KAPIACIK", "0"); // Publish message
}
kapiacikDelay = 0;
}
if (kapiKapaliDelay >= kapiKapaliDelay_Interval)
{
if (num == 5729294) // Kapi kapaninca gelen sinyal
{
DRE_switch();
Serial.println("KAPI KAPANDI.");
mqtt.publish("CMR/ESP32s/SENSOR/KAPIKAPALI", "1"); // Publish message.
}
else
{
mqtt.publish("CMR/ESP32s/SENSOR/KAPIKAPALI", "0"); // Publish message
}
kapiKapaliDelay = 0;
}
if (gazDelay >= gazDelay_Interval)
{
if (num == 12607491)
{
DRE_switch();
Serial.println("Gas Algılandı.");
mqtt.publish("CMR/ESP32s/SENSOR/GAS", "GAS ALGILANDI"); // Publish message.
}
else
{
mqtt.publish("CMR/ESP32s/SENSOR/GAS", "0"); // Publish message
}
gazDelay = 0;
}
if (dumanDelay >= dumanDelay_Interval)
{
if (num == 79974)
{
DRE_switch();
Serial.println("Duman Algılandı .");
mqtt.publish("CMR/ESP32s/SENSOR/DUMAN", "DUMAN ALGILANDI"); // Publish message.
}
else
{
mqtt.publish("CMR/ESP32s/SENSOR/DUMAN", "0"); // Publish message
}
dumanDelay = 0;
}
} // end if mySwitch.available
modem.maintain();
mqtt.loop(); // Handling MQTT on the background.
} // end of loop
boolean mqttConnect()
{
// Connect to MQTT Broker
SerialMon.print("mqttConnect: MQTT trying to connect: ");
SerialMon.print(broker);
// Connect to MQTT Broker with password protected
boolean status = mqtt.connect(clientID, mqttUser, mqttPassword);
// boolean status = mqtt.connect(clientID); // without password
if (status == false)
{
SerialMon.println("mqttConnect: MQTT Connection Fail");
return false;
}
SerialMon.println("mqttConnect: *** MQTT CONNECTED *** ");
mqtt.publish("topic/akes", "Client connection started");
mqtt.subscribe("topic/akes"); // subscribe to topic
return mqtt.connected();
}
void mqttCallback(char *topic, byte *payload, unsigned int len)
{
// Handle message arrived
SerialMon.print("mqttCallback: Message arrived [");
SerialMon.print(topic);
SerialMon.print("]: ");
SerialMon.write(payload, len);
SerialMon.println();
}
void DRE_switch()
{
// Disable Reset Enable function for RF module
mySwitch.disableReceive();
mySwitch.resetAvailable();
mySwitch.enableReceive(rcSwitchInterruptPin);
}

How can I parse mqtt message payload and have it control pins on client esp8266-01

I have been trying to learn how to get a subscribed message to respond to the message content but information is sparse for the arduino framework.
Many attempts have failed,,no clue how to debug this without a decoder board.
using mosquito broker on windows 10 as local server. Sketch will log on to wifi and mqtt and pub and sub OK. callback does not parse "PAYLOAD". I am having trouble understanding callback syntax, please advise.
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <string.h>
#include <stdio.h>
// WiFi
const char *ssid = ""; // Enter your WiFi name
const char *password = ""; // Enter WiFi password
// MQTT Broker
const char *mqtt_broker = "192.168.1.2";
const char *topic = "alert";
const char *mqtt_username = "";
const char *mqtt_password = ";
const int mqtt_port = "";
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
pinMode(2, OUTPUT);
// Set software serial baud to 115200;
Serial.begin(9600);
// connecting to a WiFi network
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
//connecting to a mqtt broker
client.setServer(mqtt_broker, mqtt_port);
client.setCallback(callback);
while (!client.connected()) {
String client_id = "esp8266-";
client_id += String(WiFi.macAddress());
Serial.printf("The client %s connects to the local mqtt broker\n", client_id.c_str());
if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
Serial.println("Local mqtt broker connected");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
// publish and subscribe
client.publish(topic, "Hello World");
client.subscribe(topic);
}
void callback(char *topic, byte *payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
Serial.println("-----------------------");
if (payload[0] == 49) // Message "1" in ASCII (turn outputs ON)
{
digitalWrite(2, LOW); // LED is active-low, so this turns it on
} else if (payload[0] == 48) // Message "0" in ASCII (turn outputs OFF)
{
digitalWrite(2, HIGH); // LED is active-low, so this turns it off
} else {
Serial.println("no input");
}
}
void loop() {
client.loop();
}
Output--
Connecting to WiFi..
8:46:46.600 -> Connected to the WiFi network
8:46:46.632 -> The client esp8266-58:BF:25:D9:B9:40 connects to the local mqtt broker
8:46:46.696 -> Local mqtt broker connected

Why Wemos D1 not respond after working for a while

I’m trying to build a feeder machine on a pig farm by using the Infrared photoelectric switch Sensor E18-D80NK to control relay then send notifications to line and mqtt broker when it’s working. I have been testing for 2 days, it’s working normal, but third day, it’s not responding then I just press reset so it’s working again.
I’m wondering it may cause by board cause it happen only one of four boards that I tasted or may be my code cause I was confused why output to line send “connected” so many times it’s should sent only one time when connected to wifi, so I’m not sure pls help.
Question
Why board not responding after working normal for a while.
Why out output to line send "connected" more than one cause I put in void setup()
Pictures
Last line output since working
All code
extra library line notification library
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <TridentTD_LineNotify.h>
const char* ssid = "Artnaseaw-2.4G";
const char* password = "0812667120";
const char* mqttUser = "****";
const char* mqttPassword = "****";
const char* mqttServer = "******";
const int mqttPort = *****;
const char* linetoken = "********";
long lastMsg = 0;
String DataString;
int lastL=0;
WiFiClient espClient;
PubSubClient client(espClient);
const int ACTION = D8;
const int SENSOR = D2;
const char* host = "maker.ifttt.com";
const char *privateKey = "******";
const char *event = "*****";
String value1, value2;
String postData = "";
String MachineID="A01";
void setup() {
Serial.begin(115200);
pinMode(SENSOR, INPUT_PULLUP);
pinMode(ACTION, OUTPUT);
digitalWrite(SENSOR, LOW);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
if (client.connect("test", mqttUser, mqttPassword )) {
Serial.println("connected");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
client.subscribe("command");
LINE.setToken(linetoken);
LINE.notify("Connected");
Serial.println("line send connected");
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
Serial.println("-----------------------");
}
void loop() {
client.loop();
delay(5000);
int sensorValue = digitalRead(SENSOR);
long now = millis();
if (now - lastMsg > 60000)
{
lastMsg = now;
int sensorValue = digitalRead(SENSOR);
if (sensorValue == LOW){
Serial.println(" === Obstacle detected");
Serial.print(" realy OFF ");
digitalWrite(ACTION,LOW);
} else {
LINE.notify("send data to line ---working");
Serial.println(" === All Clear");
Serial.println(" relay ON ");
digitalWrite(ACTION,HIGH);
sendMessageToIFTTT();
sendSensorToMQTT();
}
}
}
void sendSensorToMQTT(){
char msg[100];
int count = 1;
DataString = "e18,location=test detest="+String(count);
DataString.toCharArray(msg, 100);
Serial.print("Publish message: ");
Serial.println(msg);
client.publish("e18", msg);
}
void sendMessageToIFTTT(){
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
String url = "/trigger/";
url += event;
url += "/with/key/";
url += privateKey;
value1 = "Worked";
value2 = "1";
genJSonObject();
Serial.print("Requesting URL: ");
Serial.println(url);
Serial.println(postData);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n");
client.println("Content-Type: application/json");
client.print("Content-Length: ");
client.println(postData.length());
client.println();
client.println(postData);
client.println("Connection: close\r\n\r\n");
while (client.connected())
{
if (client.available())
{
String line = client.readStringUntil('\r');
Serial.print(line);
} else {
// No data yet, wait a bit
delay(50);
};
}
}
void genJSonObject()
{
postData = "{";
postData.concat("\"value1\":\"");
postData.concat(value1);
postData.concat("\",");
postData.concat("\"value2\":\"");
postData.concat(value2);
postData.concat("\"}");
}
Try to connect to another mqtt broker and see if it connects more than once in there too. If it happens the problem might be in the sketch. Otherwise, the cause may be with the IFTTT service.

mqtt error code RC = -1 connecting while esp32 to aws

I am going to establish a mqtt connection to aws. DHT senstor reading must be sent from esp32 to aws. How can I fix the error RC = -1 when connecting esp32 to aws. I receive this error in serial monitor :
Attempting MQTT connection...failed, rc=-1 try again in 5 seconds
What can be the reaon?
My code is as follows:
#include "SPIFFS.h"
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <DHT.h> // library for getting data from DHT
// Enter your WiFi ssid and password
const char* ssid = "TP-Link_DBCA"; //Provide your SSID
const char* password = "44388027"; // Provide Password
const char* mqtt_server = "a3k7086cinb3bt-ats.iot.us-west-2.amazonaws.com"; // Relace with your MQTT END point
const int mqtt_port = 8883;
String Read_rootca;
String Read_cert;
String Read_privatekey;
#define BUFFER_LEN 256
long lastMsg = 0;
char msg[BUFFER_LEN];
int Value = 0;
byte mac[6];
char mac_Id[18];
int count = 1;
WiFiClientSecure espClient;
PubSubClient client(espClient);
#define DHTPIN 4 //pin where the DHT22 is connected
DHT dht(DHTPIN, DHT11);
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP32-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("ei_out", "hello world");
// ... and resubscribe
client.subscribe("ei_in");
} 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() {
Serial.begin(115200);
dht.begin();
// initialize digital pin LED_BUILTIN as an output.
pinMode(2, OUTPUT);
setup_wifi();
delay(1000);
//=============================================================
if (!SPIFFS.begin(true)) {
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
//=======================================
//Root CA File Reading.
File file2 = SPIFFS.open("/AmazonRootCA1.pem", "r");
if (!file2) {
Serial.println("Failed to open file for reading");
return;
}
Serial.println("Root CA File Content:");
while (file2.available()) {
Read_rootca = file2.readString();
Serial.println(Read_rootca);
}
//=============================================
// Cert file reading
File file4 = SPIFFS.open("/certificate.pem.crt.txt", "r");
if (!file4) {
Serial.println("Failed to open file for reading");
return;
}
Serial.println("Cert File Content:");
while (file4.available()) {
Read_cert = file4.readString();
Serial.println(Read_cert);
}
//=================================================
//Privatekey file reading
File file6 = SPIFFS.open("/private.pem.key", "r");
if (!file6) {
Serial.println("Failed to open file for reading");
return;
}
Serial.println("privateKey File Content:");
while (file6.available()) {
Read_privatekey = file6.readString();
Serial.println(Read_privatekey);
}
//=====================================================
char* pRead_rootca;
pRead_rootca = (char *)malloc(sizeof(char) * (Read_rootca.length() + 1));
strcpy(pRead_rootca, Read_rootca.c_str());
char* pRead_cert;
pRead_cert = (char *)malloc(sizeof(char) * (Read_cert.length() + 1));
strcpy(pRead_cert, Read_cert.c_str());
char* pRead_privatekey;
pRead_privatekey = (char *)malloc(sizeof(char) * (Read_privatekey.length() + 1));
strcpy(pRead_privatekey, Read_privatekey.c_str());
Serial.println("================================================================================================");
Serial.println("Certificates that passing to espClient Method");
Serial.println();
Serial.println("Root CA:");
Serial.write(pRead_rootca);
Serial.println("================================================================================================");
Serial.println();
Serial.println("Cert:");
Serial.write(pRead_cert);
Serial.println("================================================================================================");
Serial.println();
Serial.println("privateKey:");
Serial.write(pRead_privatekey);
Serial.println("================================================================================================");
espClient.setCACert(pRead_rootca);
espClient.setCertificate(pRead_cert);
espClient.setPrivateKey(pRead_privatekey);
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
//====================================================================================================================
WiFi.macAddress(mac);
snprintf(mac_Id, sizeof(mac_Id), "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
Serial.print(mac_Id);
//=====================================================================================================================
delay(2000);
}
void loop() {
float h = 80; // Reading Temperature form DHT sensor
float t = 22.5; // Reading Humidity form DHT sensor
float tF = (t * 1.8) + 32;
if (isnan(h) || isnan(t))
{
Serial.println("Failed to read from DHT sensor!");
return;
}
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
//=============================================================================================
String macIdStr = mac_Id;
String Temprature = String(t);
String Humidity = String(h);
snprintf (msg, BUFFER_LEN, "{\"mac_Id\" : \"%s\", \"Temprature\" : %s, \"Humidity\" : \"%s\"}", macIdStr.c_str(), Temprature.c_str(), Humidity.c_str());
Serial.print("Publish message: ");
Serial.print(count);
Serial.println(msg);
client.publish("temp/", msg);
count = count + 1;
//================================================================================================
}
digitalWrite(2, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(2, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}```

MQTT client not subscribing to a given topic (or callback not working as intended)

I'm going nuts trying to guess why my Arduino Nano33 is not being able to receive mqtt messages. Or may be it receives them but the callback function is not working as I intend (since the callback is the only way I have to see if a message was received).
I can publish messages without problem. Any clues on what can be wrong in my code? (I have zero experience with C++ so it could be some stupid mistake).
I'm copying the entire code in case the issue is somewhere else, but I guess the key functions to look at are callback and setup.
#include <WiFiNINA.h>
#include <PubSubClient.h>
#include <Arduino_LSM6DS3.h>
#include "credentials.h"
const char* ssid = SSID_WIFI;
const char* password = PW_WIFI;
const char* mqttServer = MQTT_SERVER;
const int mqttPort = MQTT_PORT;
const char* mqttUsername = MQTT_USRNM;
const char* mqttPassword = MQTT_PW;
char pubTopic[] = "sensors/imu1/values";
char subTopic[] = "sensors/imu1/mode";
WiFiSSLClient wifiClient; //SSL
PubSubClient client(wifiClient);
void setup_wifi()
//Connect to wifi network
{
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
//char* payload_chr;
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
//payload_chr[i] = (char)payload[i];
Serial.print((char)payload[i]);
}
Serial.println();
//String message = payload_chr;
//Serial.print(message);
}
void reconnect()
{
// Loop until we're reconnected
while (!client.connected())
{
Serial.print("Attempting MQTT connection...");
String clientId = "Nano33-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str(), mqttUsername, mqttPassword))
{
Serial.println("connected");
// ... and resubscribe
client.subscribe(subTopic);
} 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()
{
Serial.begin(9600);
setup_wifi();
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}
Serial.println("IMU initialized!");
}
void publish_imu_values(float x_acc, float y_acc, float z_acc,
float x_gyr, float y_gyr, float z_gyr){
//Publish imu readings in InfluxDB Line Protocol format
String temp_str;
char mensaje[100];
temp_str = "imu x_acc=";
temp_str += String(x_acc);
temp_str += ",y_acc=";
temp_str += String(y_acc);
temp_str += ",z_acc=";
temp_str += String(z_acc);
temp_str += ",x_gyr=";
temp_str += String(x_gyr);
temp_str += ",y_gyr=";
temp_str += String(y_gyr);
temp_str += ",z_gyr=";
temp_str += String(z_gyr);
temp_str.toCharArray(mensaje, temp_str.length() + 1);
client.publish(pubTopic, mensaje);
}
void loop()
{
if (!client.connected())
{
reconnect();
}
float x_acc, y_acc, z_acc;
float x_gyr, y_gyr, z_gyr;
if (IMU.accelerationAvailable() && IMU.gyroscopeAvailable()) {
IMU.readAcceleration(x_acc, y_acc, z_acc);
IMU.readGyroscope(x_gyr, y_gyr, z_gyr);
publish_imu_values(x_acc, y_acc, z_acc, x_gyr, y_gyr, z_gyr);
}
delay(1000);
}
You need a client.loop(); line in your loop() main function. Without that line, you MQTT code never gets executed.