Chapter 21 ESP32 Development MQTT Client ESP-IDF

Learning goals and objectives

  1. Master the principle and working process of MQTT
  2. Master MQTT programming of ESP32

MQTT principle and working process explanation

MQTT ( Message Queuing Telemetry Transport) is a messaging protocol based on the publish/subscribe paradigm under the ISO standard (ISO/IEC PRF 20922). It works on the  TCP/IP protocol suite and is a publish/subscribe message protocol designed for remote devices with low hardware performance and poor network conditions . For this, it needs a message middleware  (server).

Through the MQTT protocol, dozens of MQTT server-side programs have been extended, and related messages can be sent to MQTT through system languages ​​such as PHP, JAVA, Python, C, and C#.

In addition, many domestic enterprises widely use MQTT as the protocol for pushing messages between Android mobile client and server. MQTT has the characteristics of open source code and low power consumption . In the field of the Internet of Things, the communication between sensors and servers, the collection of information, and MQTT can all be considered as one of the solutions. In the future, MQTT will enter all aspects of our lives.

Therefore, if IoT devices want to connect to the Internet, MQTT is the best choice .

MQTT features

The MQTT protocol is a protocol designed for the communication of remote sensors and control devices with limited computing power and working in low-bandwidth, unreliable networks. It has the following main characteristics:

  1. Use the publish/subscribe message model to provide one-to-many message publishing and decouple applications;
  2. Message transmission masked to payload content;
  3. provide network connectivity using TCP/IP;
  4. There are three message publishing qualities of service:
  • "At most once", message publishing relies entirely on the underlying TCP/IP network. Message loss or duplication can occur. This level can be used in the case of environmental sensor data, it doesn't matter if one read record is lost, because there will be a second transmission soon.
  • "At least once" ensures that messages arrive, but message duplication may occur.
  • "Only Once" ensures that the message arrives once. This level can be used in cases where duplicate or lost messages can lead to incorrect results in billing systems.

Small transfers with little overhead (fixed-length headers are 2 bytes), and protocol switching is minimized to reduce network traffic;

This is why it is said in the introduction that it is very suitable for the Internet of Things field. It is necessary to know that the computing power and bandwidth of embedded devices are relatively weak, and it is more suitable to use this protocol to transmit messages.

Method to realize  

Implementing the MQTT protocol requires communication between the client and the server. During the communication process, there are three identities in the MQTT protocol: publisher (Publish), broker (Broker) (server), and subscriber (Subscribe). The publisher and subscriber of the message are both clients, the message broker is the server , and the message publisher can be a subscriber at the same time .

The message transmitted by MQTT is divided into two parts: topic (Topic) and payload (payload):

Topic can be understood as the type of message. After the subscriber subscribes (Subscribe), he will receive the message content (payload) of the topic;

The payload, which can be understood as the content of the message, refers to the specific content to be used by the subscriber.

  • The main job of the MQTT server is data distribution, and there is no data storage function.
  • You can subscribe to topics published by yourself, and the server is a postback test.
  • MQTT makes the logic clearer, what needs to be subscribed.
  • The standardized process liberates a whole set of complex processes of private protocol formulation, implementation, debugging, and testing.

Win7 builds a local MQTT server ( refer to the original text )

There are currently three mainstream Brokers:

  1. Mosquitto:https://mosquitto.org/
  2. VerneMQ :https://vernemq.com/
  3. EMQTT: http://emqtt.io/   Here, we use to build EMQTT .

 

 

Download the MQTT server zip package

Stable version: emqttd-2.3.11 released on 2018/07/23

 

 

unzip to computer

I am here to unzip it to the E drive.

 

 

open terminal

 

 

Enter the directory to run the MQTT service

If the execution is successful, the following window will pop up. If it is unsuccessful, close cmd and try again .

 

 

Test the MQTT server

Open the browser -> enter http://127.0.0.1:18083  -> username: admin-> password: public-> enter the following interface

 

 

 

Connect to the MQTT server.

This software is not very easy to use, can't connect, turn it off and connect again. Using 127.0.0.1 also works.

connected two

Subscribe -> Publish, you can send data.

 

MQTT software design of ESP32

MQTT detailed process logic of ESP32

 

 

 

MQTT interface introduction

MQTT is based on TCP. Espressif has sorted out how to encapsulate it. There are relatively few interfaces left for us to use in the application layer. Xin source code and standard documents, we will analyze the layer of Espressif encapsulation later, we will not introduce it here, only explain the application layer. The so-called process + interface is invincible.

MQTT configuration information esp_mqtt_client_config_t;

Parametric prototype

esp_mqtt_client_config_t

Parameter function

MQTT configuration information

parameter

typedef struct {undefined

mqtt_event_callback_t event_handle; /*callback*/

const char *host; /*!< MQTT server domain name (ipv4 as string)*/

const char *uri; /*!< MQTT server domain name */

uint32_t port; /*!< MQTT server port*/

const char *client_id; /*The name of MQTT Client is ESP32_plus MAC by default 3hex*/

const char *username; /*MQTT username*/

const char *password; /*MQTT password*/

const char *lwt_topic; /*!< LWT topic, default is empty*/

const char *lwt_msg; /*!< LWT information, default is empty*/

int lwt_qos; /*!< LWT message quality*/

int lwt_retain; /*!< LWT retain message flag*/

int lwt_msg_len; /*!< LWT message length*/

int disable_clean_session; /*!< mqtt clean session, default is true */

int keepalive; /*MQTT heartbeat, default 120 seconds */

bool disable_auto_reconnect; /*Error, reconnect after disconnection, true does not connect*/

void *user_context; /*User information */

int task_prio; /*!< MQTT task priority, the default is 5, can be modified in make menuconfig*/

int task_stack; /*!< MQTT task stack size, default 6144 bytes, can be modified in make menuconfig*/

int buffer_size; /*!< MQTT send and receive buffer, default 1024 */

const char *cert_pem; /*Pointer to the certificate data in PEM format for server verification (using SSL), the default value is empty, no need to verify the server*/

const char *client_cert_pem; /* Pointer to certificate data in PEM format for SSL mutual authentication, the default value is empty, if mutual authentication is not required, it is not required. If not empty, the "Client Secret" must also be provided. */

const char *client_key_pem; /* Pointer to private key data in PEM format for SSL mutual authentication, the default value is empty, if mutual authentication is not required, it is not required. If not empty, "client-cert-pem" must also be provided. */

esp_mqtt_transport_t transport; /*Override URI transport*/

} esp_mqtt_client_config_t;

 

MQTT Client initialization function: esp_mqtt_client_init();

function prototype

esp_mqtt_client_handle_t esp_mqtt_client_init

(

const esp_mqtt_client_config_t *config

)

function

MQTT Client initialization function

parameter

[in] config: MQTT configuration parameters, described above

return value

MQTT Client handle

 

MQTT Client start function: esp_mqtt_client_start();

function prototype

esp_err_t esp_mqtt_client_start

(esp_mqtt_client_handle_t client);

function

MQTT Client startup function

parameter

[in] client: MQTT Client handle

return value

ESP_OK: success

other : failed

 

MQTT Client stop function: esp_mqtt_client_stop();

function prototype

esp_err_t esp_mqtt_client_stop(esp_mqtt_client_handle_t client);

function

MQTT Client stop function

parameter

[in] client: MQTT Client handle

return value

ESP_OK: success

other : failed

 

MQTT Client subscription topic function: esp_mqtt_client_subscribe();

function prototype

esp_err_t esp_mqtt_client_subscribe

(

esp_mqtt_client_handle_t client,

const char *topic,

int qos

)

function

MQTT Client subscription function

parameter

[in] client: MQTT Client handle

[in] topic: MQTT topic

[in] qos: quality of service

return value

ESP_OK: success

other : failed

 

MQTT Client unsubscribe topic function: esp_mqtt_client_unsubscribe();

function prototype

esp_err_t esp_mqtt_client_unsubscribe

(

esp_mqtt_client_handle_t client,

const char *topic

)

function

MQTT Client unsubscribe topic function

parameter

[in] client: MQTT Client handle

[in] topic: MQTT topic

return value

ESP_OK: success

other : failed

 

MQTT Client publish topic function: esp_mqtt_client_publish();

function prototype

int esp_mqtt_client_publish

(

esp_mqtt_client_handle_t client,

const char *topic,

const char *data,

int len,

int qos,

int retain

)

function

MQTT Client publish topic function

parameter

[in] client: MQTT Client handle

[in] topic: MQTT topic

[in] data: data

[in] len: length, =0 means data length

return value

message id

 

MQTT Client logout function: esp_mqtt_client_publish();

function prototype

esp_err_t esp_mqtt_client_destroy(esp_mqtt_client_handle_t client);

function

MQTT Client unsubscribe topic function

parameter

[in] client: MQTT Client handle

return value

ESP_OK: success

other : failed

 

 

 

Writing MQTT source code based on TCP

MQTT initialization

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

static void mqtt_app_start(void)

{undefined

    esp_mqtt_client_config_t mqtt_cfg = {undefined

        .host = "192.168.2.104", //MQTT server IP

        .event_handle = mqtt_event_handler, //MQTT事件

        .port=1883, //port

        .username = "admin", //username

        .password = "public", //password

        // .user_context = (void *)your_context

    };

    client = esp_mqtt_client_init(&mqtt_cfg);

    esp_mqtt_client_start(client);

    //Wait for mqtt to connect

    xEventGroupWaitBits(mqtt_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);

}

 

MQTT callback

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)

{undefined

    esp_mqtt_client_handle_t client = event->client;

    int msg_id;

    // your_context_t *context = event->context;

    switch (event->event_id) {undefined

        case MQTT_EVENT_CONNECTED://MQTT connect event

            ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");

            xEventGroupSetBits(mqtt_event_group, CONNECTED_BIT);

            // send subscription

            msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);

            ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

            break;

        case MQTT_EVENT_DISCONNECTED://MQTT disconnect event

            ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");

            //mqtt connect event

            xEventGroupClearBits(mqtt_event_group, CONNECTED_BIT);

            break;

        case MQTT_EVENT_SUBSCRIBED://MQTT send subscription event

            ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);

            msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "Subscribe successfully", 0, 0, 0);

            ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);

            break;

        case MQTT_EVENT_UNSUBSCRIBED://MQTT unsubscribe event

            ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);

            break;

        case MQTT_EVENT_PUBLISHED://MQTT publish event

            ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);

            break;

        case MQTT_EVENT_DATA://MQTT accepts data events

            ESP_LOGI(TAG, "MQTT_EVENT_DATA");

            printf("TOPIC=%.*s\r\n", event->topic_len, event->topic); //topic

            printf("DATA=%.*s\r\n", event->data_len, event->data);      //内容

            break;

        case MQTT_EVENT_ERROR://MQTT error event

            ESP_LOGI(TAG, "MQTT_EVENT_ERROR");

            xEventGroupClearBits(mqtt_event_group, CONNECTED_BIT);

            break;

    }

    return ESP_OK;

}

 

Publish the topic regularly

1

2

3

4

5

6

7

while (1) {undefined

        //publish topic

        //PC subscribed and will receive this message

        esp_mqtt_client_publish(client, "/topic/qos0", "Hello MQTT ,I am HongXu", 0, 0, 0);

        vTaskDelay(1000 / portTICK_PERIOD_MS);

 

    }

 

  •  

Test effect

test process

  • Start the MQTT server, the steps above.
  • Modify the WiFi account and password.
  • Modify MQTT configuration information

  • make menuconfig -> make all -> make flash ->make mmonitor
  • The PC MQTT assistant connects to the server.

 

 

 

Show results

The server has two MQTT clients, which are assistants for the ESP32 development board and the PC.

Subscribe and publish, can communicate with each other

  •  

MQTT summary

  • The MQTT source code here is a TCP-based MQTT solution.
  • Espressif SDK, esp-idf-V3.1.2 comes with MQTT library, so I updated the SDK and compilation chain .
  • The source code structure of MQTT is the same as the WiFi state machine, which is the method of initialization + callback.
  • MQTT summary is: within reach

         The topics I publish can be received by anyone who subscribes, including myself.

         Topic published by others, as long as I subscribe, I can receive it.

  • Do you think the tutorial is too complicated? The main reason is that there are more MQTT local servers. In the supplementary tutorial, Espressif's MQTT cloud server will be used. The process will then be simpler.
  • Source address: https://github.com/HX-IoT/ESP32-Developer-Guide

Tags: Chapter 21 ESP32 Development MQTT Client ESP-IDF

ESP32 development ESP32 Development Guide ESP32 development

Related: Chapter 21 ESP32 Development MQTT Client ESP-IDF