Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Secure MQTT connection to broker with ESP32 and internal IDF mqtt client library
#include "Arduino.h"
#include <WiFi.h>
#include "esp_log.h"
#include "esp_system.h"
#include "esp_event.h"
#include "mqtt_client.h"
#define SECURE_MQTT // Comment this line if you are not using MQTT over SSL
#ifdef SECURE_MQTT
#include "esp_tls.h"
// Let's Encrypt CA certificate. Change with the one you need
static const unsigned char DSTroot_CA[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
)EOF";
#endif // SECURE_MQTT
esp_mqtt_client_config_t mqtt_cfg;
esp_mqtt_client_handle_t client;
const char* WIFI_SSID = "Your_SSID";
const char* WIFI_PASSWD = "Your_password";
const char* MQTT_HOST = "Your_broker_address";
#ifdef SECURE_MQTT
const uint32_t MQTT_PORT = 8883;
#else
const uint32_t MQTT_PORT = 1883;
#endif // SECURE_MQTT
const char* MQTT_USER = "Username_in_broker";
const char* MQTT_PASSWD = "password";
static esp_err_t mqtt_event_handler (esp_mqtt_event_handle_t event) {
if (event->event_id == MQTT_EVENT_CONNECTED) {
ESP_LOGI ("TEST", "MQTT msgid= %d event: %d. MQTT_EVENT_CONNECTED", event->msg_id, event->event_id);
esp_mqtt_client_subscribe (client, "test/hello", 0);
esp_mqtt_client_publish (client, "test/status", "1", 1, 0, false);
}
else if (event->event_id == MQTT_EVENT_DISCONNECTED) {
ESP_LOGI ("TEST", "MQTT event: %d. MQTT_EVENT_DISCONNECTED", event->event_id);
//esp_mqtt_client_reconnect (event->client); //not needed if autoconnect is enabled
} else if (event->event_id == MQTT_EVENT_SUBSCRIBED) {
ESP_LOGI ("TEST", "MQTT msgid= %d event: %d. MQTT_EVENT_SUBSCRIBED", event->msg_id, event->event_id);
} else if (event->event_id == MQTT_EVENT_UNSUBSCRIBED) {
ESP_LOGI ("TEST", "MQTT msgid= %d event: %d. MQTT_EVENT_UNSUBSCRIBED", event->msg_id, event->event_id);
} else if (event->event_id == MQTT_EVENT_PUBLISHED) {
ESP_LOGI ("TEST", "MQTT event: %d. MQTT_EVENT_PUBLISHED", event->event_id);
} else if (event->event_id == MQTT_EVENT_DATA) {
ESP_LOGI ("TEST", "MQTT msgid= %d event: %d. MQTT_EVENT_DATA", event->msg_id, event->event_id);
ESP_LOGI ("TEST", "Topic length %d. Data length %d", event->topic_len, event->data_len);
ESP_LOGI ("TEST","Incoming data: %.*s %.*s\n", event->topic_len, event->topic, event->data_len, event->data);
} else if (event->event_id == MQTT_EVENT_BEFORE_CONNECT) {
ESP_LOGI ("TEST", "MQTT event: %d. MQTT_EVENT_BEFORE_CONNECT", event->event_id);
}
return ESP_OK;
}
void setup () {
mqtt_cfg.host = MQTT_HOST;
mqtt_cfg.port = MQTT_PORT;
mqtt_cfg.username = MQTT_USER;
mqtt_cfg.password = MQTT_PASSWD;
mqtt_cfg.keepalive = 15;
#ifdef SECURE_MQTT
mqtt_cfg.transport = MQTT_TRANSPORT_OVER_SSL;
#else
mqtt_cfg.transport = MQTT_TRANSPORT_OVER_TCP;
#endif // SECURE_MQTT
mqtt_cfg.event_handle = mqtt_event_handler;
mqtt_cfg.lwt_topic = "test/status";
mqtt_cfg.lwt_msg = "0";
mqtt_cfg.lwt_msg_len = 1;
Serial.begin (115200);
WiFi.mode (WIFI_MODE_STA);
WiFi.begin (WIFI_SSID, WIFI_PASSWD);
while (!WiFi.isConnected ()) {
Serial.print ('.');
delay (100);
}
Serial.println ();
#ifdef SECURE_MQTT
esp_err_t err = esp_tls_set_global_ca_store (DSTroot_CA, sizeof (DSTroot_CA));
ESP_LOGI ("TEST","CA store set. Error = %d %s", err, esp_err_to_name(err));
#endif // SECURE_MQTT
client = esp_mqtt_client_init (&mqtt_cfg);
//esp_mqtt_client_register_event (client, ESP_EVENT_ANY_ID, mqtt_event_handler, client); // not implemented in current Arduino core
err = esp_mqtt_client_start (client);
ESP_LOGI ("TEST", "Client connect. Error = %d %s", err, esp_err_to_name (err));
}
void loop () {
esp_mqtt_client_publish (client, "test/bye", "data", 4, 0, false);
delay (2000);
}
@gmag11
Copy link
Author

gmag11 commented Nov 21, 2019

This is basic code to use IDF functions to connect to MQTT over SSL with ESP32 in Arduino compatible IDE (Platform.io, Visual Micro, etc). I will be adding more functions here: event management, topics subscription, publishing, last will.

@gmag11
Copy link
Author

gmag11 commented Nov 26, 2019

Added last will, subscription, publishing and unsecure connection as an (not recommended) option

@storoz26
Copy link

storoz26 commented Sep 22, 2020

Perfecto el post, todo funciona muy bien

En estos momentos por node red estoy intentando encender un led utilizando la tarjeta esp32

La verdad no he sido capaz de encender un led de la esp32 utilizando una suscripción por broker
Como podria hacerlo?

muchas gracias

@RetroLabs
Copy link

RetroLabs commented Mar 18, 2021

Added last will, subscription, publishing and unsecure connection as an (not recommended) option

Where is the line of code for subscribing?

@poky
Copy link

poky commented Mar 29, 2021

Added last will, subscription, publishing and unsecure connection as an (not recommended) option

Where is the line of code for subscribing?

Line 56?

esp_mqtt_client_subscribe (client, "test/hello", 0);

@gmag11
Copy link
Author

gmag11 commented Apr 1, 2021

Exactly. It is done just after connected event.

@gjt211
Copy link

gjt211 commented Apr 3, 2021

Hi, I just copy-pasted this into a new blank sketch and it doesn't compile for me. It looks like there is meant to be a return value for the mqtt_event_handler but there is not one there.

Documents/Arduino/esp32test/esp32test.ino: In function 'esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t)':
esp32test:76:1: error: no return statement in function returning non-void [-Werror=return-type]
 }
 ^

Any ideas where I should start looking? I am guessing it is working for others so it must be something on my system. (MacOS, Arduino 1.8.10)

@poky
Copy link

poky commented Apr 3, 2021

Hi, I just copy-pasted this into a new blank sketch and it doesn't compile for me. It looks like there is meant to be a return value for the mqtt_event_handler but there is not one there.

Documents/Arduino/esp32test/esp32test.ino: In function 'esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t)':
esp32test:76:1: error: no return statement in function returning non-void [-Werror=return-type]
 }
 ^

Any ideas where I should start looking? I am guessing it is working for others so it must be something on my system. (MacOS, Arduino 1.8.10)

Compiled and ran fine on my Mac with Arduino 1.8.13 and esp 1.0.6

@poky
Copy link

poky commented Apr 3, 2021

Hi, I just copy-pasted this into a new blank sketch and it doesn't compile for me. It looks like there is meant to be a return value for the mqtt_event_handler but there is not one there.

Documents/Arduino/esp32test/esp32test.ino: In function 'esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t)':
esp32test:76:1: error: no return statement in function returning non-void [-Werror=return-type]
 }
 ^

Any ideas where I should start looking? I am guessing it is working for others so it must be something on my system. (MacOS, Arduino 1.8.10)

Or you could add

return ESP_OK;

in the end of that statement

@gmag11
Copy link
Author

gmag11 commented Apr 5, 2021

Hi, I just copy-pasted this into a new blank sketch and it doesn't compile for me. It looks like there is meant to be a return value for the mqtt_event_handler but there is not one there.

Documents/Arduino/esp32test/esp32test.ino: In function 'esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t)':
esp32test:76:1: error: no return statement in function returning non-void [-Werror=return-type]
 }
 ^

Any ideas where I should start looking? I am guessing it is working for others so it must be something on my system. (MacOS, Arduino 1.8.10)

Hi. You are right. There is a missing return statement there. I'll add it soon. Meanwhile as @poky suggest here you may add return ESP_OK; at the end of that function.

@gjt211
Copy link

gjt211 commented Apr 5, 2021

Thanks poky and gmag11, The return statement did fix the problem.
Great work, and thanks for providing this. Highly appreciated.

@poky
Copy link

poky commented Apr 6, 2021

Thanks poky and gmag11, The return statement did fix the problem.
Great work, and thanks for providing this. Highly appreciated.

Glad it works for you!

Just a friendly reminder, that you should not put any "hard work" especially IO tasks in this block or function call from it.

} else  if (event->event_id == MQTT_EVENT_DATA) {
		ESP_LOGI ("TEST", "MQTT msgid= %d event: %d. MQTT_EVENT_DATA", event->msg_id, event->event_id);
		ESP_LOGI ("TEST", "Topic length %d. Data length %d", event->topic_len, event->data_len);
		ESP_LOGI ("TEST","Incoming data: %.*s %.*s\n", event->topic_len, event->topic, event->data_len, event->data);

}

I was having a headache try to debug the random crash issue when too many data received at once, the best way to handle it is to put a flag, and that the outer function catches it to do the rest of work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment