네트워크/MQTT

[MQTT] 4. MQTT Arduino

IT 기술자 2025. 2. 7. 11:00

main.cpp

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <ESPmDNS.h>

const char* ssid = "[ssid]";
const char* password = "[ssid password]";

const char* ServerIp = "[mqtt server ip]";
const char* clientId = "[client id]";
const char* mqttUsername = "[mqtt username]";
const char* mqttPassword = "[mqtt password]";

#define TOPIC    "[topic]"

const char* ca_cert = "[ca.crt 파일 텍스트]";

const char* server_key = "[server.key 파일 텍스트]";

const char* server_crt = "[server.crt 파일 텍스트]";

/* create an instance of WiFiClientSecure */
WiFiClientSecure espClient;
PubSubClient client(espClient);

long lastMsg = 0;
char msg[20];
int counter = 0;

void receivedCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message received: ");
  Serial.println(topic);

  Serial.print("payload: ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

void mqttconnect() {
  /* Loop until reconnected */
  while (!client.connected()) {
    Serial.print("MQTT connecting ...");
    /* connect now */
    if (client.connect(clientId, mqttUsername, mqttPassword)) {
      Serial.println("connected");
      /* subscribe topic */
      client.subscribe(TOPIC);
    } 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 setup() {
  Serial.begin(115200);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  /*setup MDNS for ESP32 */
  if (!MDNS.begin("esp32")) {
      Serial.println("Error setting up MDNS responder!");
      while(1) {
          delay(1000);
      }
  }
  /* get the IP address of server by MDNS name */
  Serial.println("mDNS responder started");
  Serial.print("IP address of server: ");
  Serial.println(ServerIp);
  /* set SSL/TLS certificate */
  espClient.setCACert(ca_cert);
  espClient.setPrivateKey(server_key);
  espClient.setCertificate(server_crt);
  /* configure the MQTT server with IPaddress and port */
  client.setServer(ServerIp, 8883);
  /* this receivedCallback function will be invoked
  when client received subscribed topic */
  client.setCallback(receivedCallback);

}
void loop() {
  /* if client was disconnected then try to reconnect again */
  if (!client.connected()) {
    mqttconnect();
  }
  /* this function will listen for incomming
  subscribed topic-process-invoke receivedCallback */
  client.loop();
  /* we increase counter every 3 secs
  we count until 3 secs reached to avoid blocking program if using delay()*/
  long now = millis();
  if (now - lastMsg > 3000) {
    lastMsg = now;
    if (counter < 100) {
      counter++;
      snprintf (msg, 20, "%d", counter);
      /* publish the message */
      client.publish(TOPIC, msg);
    }else {
      counter = 0;
    }
  }
}

 

platformio.ini

lib_deps =
  PubSubClient

 

main.cpp 예제

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <ESPmDNS.h>

const char* ssid = "[ssid]";
const char* password = "[ssid password]";

const char* ServerIp = "192.168.99.225";
const char* clientId = "ESP32Client";
const char* mqttUsername = "korea_company";
const char* mqttPassword = "korea_company";

#define TOPIC    "test/topic"

const char* ca_cert = \
"-----BEGIN CERTIFICATE-----\n" \
"MIID0TCCArmgAwIBAgIUBlblEbEWRo3Y+3C9QdKEnj9DtTEwDQYJKoZIhvcNAQEL\n" \
"BQAweDELMAkGA1UEBhMCS1IxDjAMBgNVBAgMBXNlb3VsMQ0wCwYDVQQKDARraXRz\n" \
"MQwwCgYDVQQLDANsYWIxETAPBgNVBAMMCGRic2VydmVyMSkwJwYJKoZIhvcNAQkB\n" \
"FhpqYWVjaGVvbC5wYXJrQGtvcmVhaXRzLmNvbTAeFw0yMjA4MjYwMTA2MTJaFw0y\n" \
"NzA4MjYwMTA2MTJaMHgxCzAJBgNVBAYTAktSMQ4wDAYDVQQIDAVzZW91bDENMAsG\n" \
"A1UECgwEa2l0czEMMAoGA1UECwwDbGFiMREwDwYDVQQDDAhkYnNlcnZlcjEpMCcG\n" \
"CSqGSIb3DQEJARYaamFlY2hlb2wucGFya0Brb3JlYWl0cy5jb20wggEiMA0GCSqG\n" \
"SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7h0B3j/oHcBEnNbT2E3cuM5zGm5kRZTBq\n" \
"3Rq+CpMO99NAKnqWZNx1M8wm5Rxs5yO0mBJRfbEYQSB0y+n0ig7TcgWRaQfzhoQH\n" \
"k82q3foSctIu7M13Wuwc8oCUprXVSz667nF0sZ9/kzGdCX9AZHm2VlPq/Er89PUJ\n" \
"JscblwxoyXE01H/yXN9WYZHzV7lk14LhLL/SHGADNybRNBUDWTJaTtY5vbqLKvK7\n" \
"+uMCmd/qfP6qXnSXRYQDtkV6ga9j6r93SzV5OjrPGS5x4BCpdH/rldAUVOMABQQa\n" \
"386EuU0Xi+11XbMx6u92fy4c+X3wx45Tetoxy4rysaf1S/9XgUGNAgMBAAGjUzBR\n" \
"MB0GA1UdDgQWBBQEbiAQ0snbzq5w0++YvbyfrwrrkTAfBgNVHSMEGDAWgBQEbiAQ\n" \
"0snbzq5w0++YvbyfrwrrkTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA\n" \
"A4IBAQA/M4hBx0Vz+R8JKr+pnvjaeXW2A/HhqXXZCwJjNV4Jr98xUpSLkMXWrOBk\n" \
"7tFGRwlrdmoOBGDwNyR59xqD8AjHYLnQ9T1gcXdko7QhGW2daeqle23wuZqWOSS0\n" \
"43rsJQ5eoyNe/p2ziigrlih2O+He6TrftnJC3YvULF/hLORtsTIqUWszzub3Ss+W\n" \
"8JaapDKx/JSqgqbz8o+udJOThqkcfdIuLvvxCGioV0lyse24wdrD8pI5upXmOPcv\n" \
"/ORHO04MLWp2h9FnFf1gaXIL1Mmc6VaP1y+52MckT9vWBTqnhV/PCsmWx3VRHhp2\n" \
"VWAmHsOkf9k23/Y8BU7axtB/8lc6\n" \
"-----END CERTIFICATE-----\n";

const char* server_key = \
"-----BEGIN PRIVATE KEY-----\n" \
"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCIeCb1gGWnj8ug\n" \
"e0g+nQkbgttA3wuN06zIFy0pKwNZ0/FrYkEpcEtiPRhNS3NxZSIOaSM4yN/xaTR+\n" \
"IBgRn835NHlbhp/P5B8BXX3lh6luVTSm63Z1fmj/aH+P932a8QBzjpKQD16GJfZT\n" \
"sRXBwfDWRtuoB8sVy313qBrqFTjcfaA3UwTQ7Rzhgo/BjByRmKHwkLG0xw/0JDNK\n" \
"EFi6U20zzD0O2CjsgDbxOq6Q4ZkZroc2Utsc1vt3RdZEG6ePDl2t6D3DpBQoREtC\n" \
"aX2ggTITcfybMEce7f0NQ2w8e+hwp0rai2QZlGhnP9yWuK5nQjYX5Pwq1mLCsOMW\n" \
"Ozkg0fHdAgMBAAECggEABx4vOARZqP72ybjMaJmjuTfezDgl/+B/xVLyI9DOxK9p\n" \
"iuaNzAXDpMzXeOabz5kNCO/iaqqNhaetWXu+jaLGaT5bqxKvQLZfCKDx+VgVVgAj\n" \
"NiaXX+L3QoUWjDGGL1/tHFneGp32meweeDiHEDtXnrGE8PNxHAKoWWae+sEfHV7r\n" \
"jGhY+GAvDA4QCG9EUJyq0RSKyXiy6qo5axzGTHrS6Mp17QaWgAkPHUtSsOLL2yAV\n" \
"0YjDzZbKcx5dpWbwvHxaEqMOFmIo2SCcwUw0/OWYZchQ9S6Ee5awaEWUSp9FVT3a\n" \
"UV6oTpY6kGkwmGWBxaGTZP0HvCbvPOkEYcD4uYmdEQKBgQC/3rZ9nfJqqBKUe2uV\n" \
"VwXxtAyv/X0vQRpvht8Etk0HNm3wKJ7oywtdF7+zelxgld+9tNkQCxUJhjz21ecM\n" \
"mh+ZlGQ4+6DJqK88MRt8Cpgahai8FBWhA6l0g7wbu3ZY0blUsLSwsuvfJqSyd1OF\n" \
"bD2h49ooCDu2rjuxQJ8lvJTOsQKBgQC2FRqeP8sDsGoAl2syGrBjdBPUB9+iBl0h\n" \
"0gtYhxO4AbjKkb6JryqouzW+gNl0zxQpAMR0QvkxoBcQUKKmHwi/y1GZdyrCsoyf\n" \
"ooX8Qq4vn0HnbMzS2LteZQUI7fKZEzRReksbe5aIMYPamXYvd5Mr7g+uDr69sPHL\n" \
"FLLTag4Y7QKBgQCnvL5xhzm8wH6tzFA7WL7blXpaCRP90b6YraIe7njcy1rFT93M\n" \
"ymV+1xpCf8But9fIc2goPGgB0ZdOe6XoQH1LuIz9vA3O/mdkCdJrWJ+s4BiphC18\n" \
"fEUSlXBIFlTaRU7umST+LQ1EIvZtByC/Ted7tkSsJrZ9eEi7JzF6viihoQKBgA7z\n" \
"OqVFraCW6o0z4YxSnqr7y+j74IPIK/tr6JyTMq5IDeksAE4DwOfrvyTuJWyu2APp\n" \
"2TeGjDlj4KDpTgF/yNMemYuVOkCUMnGlAYVN4ElutRWQXFzviKredoReLS4eYoxS\n" \
"Ezqlch2qmx3mvcp18fKIcGclNMoUbjXzdB9htNidAoGAYf/X4CZrab05O5fHzXD2\n" \
"JXcgWe2aIt3jR0pf/LyOHFjhiyHpw4vfcEwNcsu7MmHq6ifUr0Q/sM1zDUa3uFjb\n" \
"WoSDGIkcfDJ9sZ1CL+lhaCcCaevlIuoLn9vVPfrMss5LGGk/Q3/oco7zfgeWtIOg\n" \
"VLAL3aop4nLey84XBPNxhj4=\n" \
"-----END PRIVATE KEY-----\n";

const char* server_crt = \
"-----BEGIN CERTIFICATE-----\n" \
"MIIDfTCCAmUCFAGMGehiEEUnQsHsJMEkWyausJtGMA0GCSqGSIb3DQEBCwUAMHgx\n" \
"CzAJBgNVBAYTAktSMQ4wDAYDVQQIDAVzZW91bDENMAsGA1UECgwEa2l0czEMMAoG\n" \
"A1UECwwDbGFiMREwDwYDVQQDDAhkYnNlcnZlcjEpMCcGCSqGSIb3DQEJARYaamFl\n" \
"Y2hlb2wucGFya0Brb3JlYWl0cy5jb20wHhcNMjIwODI2MDEwNjUyWhcNMjIwOTI1\n" \
"MDEwNjUyWjB+MQswCQYDVQQGEwJLUjEOMAwGA1UECAwFc2VvdWwxDTALBgNVBAoM\n" \
"BGtpdHMxDDAKBgNVBAsMA2xhYjEXMBUGA1UEAwwOMTkyLjE2OC45OS4yMjUxKTAn\n" \
"BgkqhkiG9w0BCQEWGmphZWNoZW9sLnBhcmtAa29yZWFpdHMuY29tMIIBIjANBgkq\n" \
"hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiHgm9YBlp4/LoHtIPp0JG4LbQN8LjdOs\n" \
"yBctKSsDWdPxa2JBKXBLYj0YTUtzcWUiDmkjOMjf8Wk0fiAYEZ/N+TR5W4afz+Qf\n" \
"AV195YepblU0put2dX5o/2h/j/d9mvEAc46SkA9ehiX2U7EVwcHw1kbbqAfLFct9\n" \
"d6ga6hU43H2gN1ME0O0c4YKPwYwckZih8JCxtMcP9CQzShBYulNtM8w9Dtgo7IA2\n" \
"8TqukOGZGa6HNlLbHNb7d0XWRBunjw5dreg9w6QUKERLQml9oIEyE3H8mzBHHu39\n" \
"DUNsPHvocKdK2otkGZRoZz/clriuZ0I2F+T8KtZiwrDjFjs5INHx3QIDAQABMA0G\n" \
"CSqGSIb3DQEBCwUAA4IBAQBfs8kd4LHRGQMj+Ji1JixFrP+rVBgY4jypLv/YuP+L\n" \
"Sgn8NWbglMVcVhmxlfvg5ULEIcZleV5D+iE08leajaAggLOrVY7qIVUtOVE3r/Qp\n" \
"dVNyRdk3l8MygACXQLVy+hXehiNFSBkRi5qj2zaQJMHV5FDUkOBt2fvwSRwVpyob\n" \
"bn3X2Tm+AbsSmNL49wc2EyKqCrCT45dZrzYCjd13WyiSkP4OrAGakeIipHLdNUhP\n" \
"72KrsemVw35vBfnUOWjAzQtpcc5RlNFfTnY+/p0i2mNm50cab7rtEkZAD6CAmegb\n" \
"wDfsdzKgBglfSzYIUfQXExDw/N2L788byyBPuy3nFQo8\n" \
"-----END CERTIFICATE-----\n";

/* create an instance of WiFiClientSecure */
WiFiClientSecure espClient;
PubSubClient client(espClient);

long lastMsg = 0;
char msg[20];
int counter = 0;

void receivedCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message received: ");
  Serial.println(topic);

  Serial.print("payload: ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

void mqttconnect() {
  /* Loop until reconnected */
  while (!client.connected()) {
    Serial.print("MQTT connecting ...");
    /* connect now */
    if (client.connect(clientId, mqttUsername, mqttPassword)) {
      Serial.println("connected");
      /* subscribe topic */
      client.subscribe(TOPIC);
    } 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 setup() {
  Serial.begin(115200);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  /*setup MDNS for ESP32 */
  if (!MDNS.begin("esp32")) {
      Serial.println("Error setting up MDNS responder!");
      while(1) {
          delay(1000);
      }
  }
  /* get the IP address of server by MDNS name */
  Serial.println("mDNS responder started");
  Serial.print("IP address of server: ");
  Serial.println(ServerIp);
  /* set SSL/TLS certificate */
  espClient.setCACert(ca_cert);
  espClient.setPrivateKey(server_key);
  espClient.setCertificate(server_crt);
  /* configure the MQTT server with IPaddress and port */
  client.setServer(ServerIp, 8883);
  /* this receivedCallback function will be invoked
  when client received subscribed topic */
  client.setCallback(receivedCallback);

}
void loop() {
  /* if client was disconnected then try to reconnect again */
  if (!client.connected()) {
    mqttconnect();
  }
  /* this function will listen for incomming
  subscribed topic-process-invoke receivedCallback */
  client.loop();
  /* we increase counter every 3 secs
  we count until 3 secs reached to avoid blocking program if using delay()*/
  long now = millis();
  if (now - lastMsg > 3000) {
    lastMsg = now;
    if (counter < 100) {
      counter++;
      snprintf (msg, 20, "%d", counter);
      /* publish the message */
      client.publish(TOPIC, msg);
    }else {
      counter = 0;
    }
  }
}

 

참고 : http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html

 

Demo 30: How to use Arduino ESP32 MQTTS with MQTTS Mosquitto broker (TLS/SSL)

This is a place where I can share my knowledge of: IoT, machine learning self learning and other interetsing topics.

www.iotsharing.com