ESP32的MQTT使用

一、ESP32的MQTT函数介绍

1、esp_mqtt_client_handle_t esp_mqtt_client_init(const esp_mqtt_client_config_t *config)

函数描述:根据配置创建MQTT客户端句柄

参数esp_mqtt_client_config_t的结构体如下

typedef struct {
    mqtt_event_callback_t event_handle; / *!<处理MQTT事件作为传统模式的回调* /
    esp_event_loop_handle_t event_loop_handle; / *! user_context`` * /中接收该上下文
    int task_prio; / *!

返回值:MQTT句柄 错误的时候返回NULL

使用举例:

    esp_mqtt_client_config_t mqtt_cfg = {
        .host = "192.168.43.95", //MQTT 地址
		.port = 1883,    //MQTT端口
		.username = "admin",//用户名字
		.password = "public",//密码
    };

    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);

2、sp_err_t esp_mqtt_client_start(esp_mqtt_client_handle_t client)

函数描述:启动MQTT客户端

参数:创建的MQTT句柄

返回值:ESP_OK表示成功ESP_ERR_无效_ARG错误初始化ESP_FERT其他错误

3、esp_err_t esp_mqtt_client_stop(esp_mqtt_client_handle_t client)

函数描述:停止MQTT客户端

参数:创建的MQTT句柄

4、int esp_mqtt_client_subscribe(esp_mqtt_client_handle_t client, const char *topic, int qos)

函数描述:订阅主题

参数:A、esp_mqtt_client_handle_t client     创建的MQTT句柄

         B、char *topic  订阅的主题

         C、Qos级别 0 、1、 2

返回值:成功时订阅消息返回Message_id- 失败返回-1

5、int esp_mqtt_client_unsubscribe(esp_mqtt_client_handle_t client, const char *topic)

函数描述:取消订阅的主题

参数:A、esp_mqtt_client_handle_t client     创建的MQTT句柄

         B、B、char *topic  订阅的主题

返回值:成功时订阅消息返回Message_id- 失败返回-1

6、int esp_mqtt_client_publish(esp_mqtt_client_handle_t client, const char *topic, const char *data, int len, int qos, int retain)

函数描述:往代理发布消息

参数:A、esp_mqtt_client_handle_t client     创建的MQTT句柄

          B、char *topic  发布的主题

         C、 const char *data  发布的数据

        D、int len    数据长度,如果设置为0,则从发布的数据长度

        E、Qos级别

       F、retain  当我们使用MQTT客户端发布消息(PUBLISH)时,如果将RETAIN标志位设置为true,那么MQTT服务器会将最近收到的一条RETAIN标志位为true的消息保存在服务器端

7、esp_err_t esp_mqtt_client_register_event(esp_mqtt_client_handle_t client, esp_mqtt_event_id_t event, esp_event_handler_t event_handler, void* event_handler_arg)

函数描述:注册MQTT事件

参数:A、esp_mqtt_client_handle_t client     创建的MQTT句柄

         B、esp_mqtt_event_id_t event     注册任何事件id的处理程序

       C、esp_event_handler_t event_handler  回调函数

       D、void* event_handler_arg  处理程序上下文

 

二、实验内容

1、初始化wifi,并连接wifi

2、初始化MQTT,连接成功发布、订阅主题

 

1、初始化wifi,并连接wifi

static EventGroupHandle_t wifi_event_group;

/* The event group allows multiple bits for each event,
   but we only care about one event - are we connected
   to the AP with an IP? */
const int CONNECTED_BIT = BIT0;
//wifi 事件
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
    switch (event->event_id) {
        case SYSTEM_EVENT_STA_START:
            esp_wifi_connect();
            break;
        case SYSTEM_EVENT_STA_GOT_IP:
        	//Mqtt_init();
            xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
            break;
        case SYSTEM_EVENT_STA_DISCONNECTED:
            /* This is a workaround as ESP32 WiFi libs don't currently
               auto-reassociate. */
            esp_wifi_connect();
            xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
            break;
        default:
            break;
    }
    return ESP_OK;
}
//初始化wifi
void app_wifi_initialise(void)
{
    tcpip_adapter_init();
    wifi_event_group = xEventGroupCreate();
    ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
    wifi_config_t wifi_config = {
        .sta = {
            .ssid = "tplingk",
            .password = "12345678",
        },
    };
    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());
}
//等待wifi成功连接
void app_wifi_wait_connected()
{
    xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
}

上面就是初始化wifi ,并且连接wifi.在wifi连接成功里面设置事件标志

2、初始化MQTT,连接成功发布、订阅主题

static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
{
    esp_mqtt_client_handle_t client = event->client;
    int msg_id;
    // your_context_t *context = event->context;
    switch (event->event_id) {
        case MQTT_EVENT_CONNECTED://连接MQTT成功
            ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
            msg_id = esp_mqtt_client_publish(client, "/World", "data_3", 0, 1, 0);
            ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);

            msg_id = esp_mqtt_client_subscribe(client, "/topic0", 0);
            ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

            msg_id = esp_mqtt_client_subscribe(client, "/topic1", 1);
            ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
            msg_id = esp_mqtt_client_subscribe(client, "/topic1", 2);
            ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
            //msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
            //ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
            break;
        case MQTT_EVENT_DISCONNECTED://断开MQTT
            ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
            break;

        case MQTT_EVENT_SUBSCRIBED://订阅成功
        	printf("_---------订阅--------\n");
            ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
            msg_id = esp_mqtt_client_publish(client, "/World", "data", 0, 0, 0);
            ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
            break;
        case MQTT_EVENT_UNSUBSCRIBED://取消订阅
            ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_PUBLISHED://发布成功
        	printf("_--------发布----------\n");
            ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_DATA://数据接收
            ESP_LOGI(TAG, "MQTT_EVENT_DATA");
            printf("主题长度:%d 数据长度:%d\n",event->topic_len,event->data_len);

            printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
            printf("DATA=%.*s\r\n", event->data_len, event->data);
            break;
        case MQTT_EVENT_ERROR://MQTT错误
            ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
            break;
        default:
            ESP_LOGI(TAG, "Other event id:%d", event->event_id);
            break;
    }
    return ESP_OK;
}

static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) {
    ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
    mqtt_event_handler_cb(event_data);
}

static void mqtt_app_start(void)
{
    printf("\n______________等待wifi连接____________\n");
    app_wifi_wait_connected();
    vTaskDelay(5000 / portTICK_PERIOD_MS);
    printf("\n______________wifi连接成功____________\n");
    esp_mqtt_client_config_t mqtt_cfg = {
        .host = "192.168.43.95",//MQTT 地址
		.port = 1883,   //MQTT端口
		.username = "admin",//用户名
		.password = "public",//密码
    };

    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);//初始化MQTT
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);//注册事件
    esp_mqtt_client_start(client);//启动mQTT
    while(1){

    	vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

在连接成功MQTT之后,发布一个消息,订阅三个消息如下

            msg_id = esp_mqtt_client_publish(client, "/World", "data_3", 0, 1, 0);

            msg_id = esp_mqtt_client_subscribe(client, "/topic0", 0);

            msg_id = esp_mqtt_client_subscribe(client, "/topic1", 1);
            msg_id = esp_mqtt_client_subscribe(client, "/topic1", 2);
 

三、实验结果

连接的是本地搭建的MQTT服务器emqttd,网上很多教程。

连接成功之后就可以在里面看到,ESP32_050F44就是连接成功的设备

ESP32的MQTT使用_第1张图片

 

发布和订阅的主题

ESP32的MQTT使用_第2张图片

ESP32的MQTT使用_第3张图片

 

发布和订阅消息

ESP32的MQTT使用_第4张图片

ESP32的MQTT使用_第5张图片

串口打印的数据

ESP32的MQTT使用_第6张图片

 

你可能感兴趣的:(ESP32)