ESP32-C3入门教程 网络篇⑦——MQTT 应用示例
Posted 小康师兄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ESP32-C3入门教程 网络篇⑦——MQTT 应用示例相关的知识,希望对你有一定的参考价值。
文章目录
一、前言
本文基于VS Code IDE进行编程、编译、下载、运行等操作
基础知识点请查阅:ESP32-C3入门教程 基础篇①——基于VS Code构建Hello World
二、MQTT简介
MQTT 是轻量级的发布/订阅消息协议
ESP-MQTT 是 MQTT 协议客户端的实现
基于TCP/SSL/WebSocket/WebSocket Secure等MQTT实现
三、快速运行
- 示例项目中,选择
protocols
—>mqtt
->tcp
menuconfig
配置ESP32C3-Specific
—>Rec 0
- 芯片选择
ESP32-C3(Built-in USB JTAG)
- 快速运行
ESP-IDF Build, Flash and Monitor
(左下角)
四、运行效果
- 修改WiFi AP的
SSID
和password
- 基于
mqtt.eclipseprojects.io
这个mqtt服务器进行测试 - MQTTBox订阅topic
"/小康师兄/topic/start"
和"/小康师兄/topic/end"
- ESP32-C3订阅topic
"/小康师兄/topic/wait"
- ESP32-C3往topic
"/小康师兄/topic/start"
发送数据"小康师兄start"
- MQTTBox往topic
"/小康师兄/topic/wait"
发送数据"小康师兄end"
- ESP32-C3接收到topic
"/小康师兄/topic/wait"
的数据"小康师兄end"
- 则往topic
"/小康师兄/topic/end"
发送数据"小康师兄end"
- 并取消订阅topic
"/小康师兄/topic/wait"
- 则往topic
五、程序流程
5.1 主程序
nvs_flash_init
,初始化默认 NVS 分区esp_netif_init
,初始化底层TCP/IP堆栈esp_event_loop_create_default
,创建默认事件循环example_connect
,连接到指定WiFiesp_mqtt_client_init
,MQTT初始化esp_mqtt_client_register_event
,MQTT事件回调函数esp_mqtt_client_start
,MQTT启动
5.2 回调函数
MQTT_EVENT_CONNECTED
,MQTT连接成功esp_mqtt_client_publish
,往topic"/小康师兄/topic/start"
发送数据"小康师兄start"
esp_mqtt_client_subscribe
,订阅topic"/小康师兄/topic/wait"
MQTT_EVENT_DATA
,MQTT接收到数据- 判断topic是不是
"/小康师兄/topic/wait"
,判断data是不是"小康师兄end"
,如果全是,则:esp_mqtt_client_publish
,往topic"/小康师兄/topic/end"
发送数据"小康师兄end"
esp_mqtt_client_unsubscribe
,取消订阅topic"/小康师兄/topic/wait"
- 判断topic是不是
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:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
msg_id = esp_mqtt_client_publish(client, "/小康师兄/topic/start", "小康师兄start", 0, 1, 0);
ESP_LOGI(TAG, "publish successful, msg_id=%d", msg_id);
msg_id = esp_mqtt_client_subscribe(client, "/小康师兄/topic/wait", 0);
ESP_LOGI(TAG, "subscribe successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d, topic=%.*s", event->msg_id, event->topic_len, event->topic);
break;
case MQTT_EVENT_UNSUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d, topic=%.*s", event->msg_id, event->topic_len, event->topic);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d, topic=%.*s", event->msg_id, event->topic_len, event->topic);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
printf("TOPIC=%.*s\\r\\n", event->topic_len, event->topic);
printf("DATA=%.*s\\r\\n", event->data_len, event->data);
if(strstr(event->topic, "/小康师兄/topic/wait")!=0 &&
strstr(event->data, "小康师兄end")!=0){
msg_id = esp_mqtt_client_publish(client, "/小康师兄/topic/end", "小康师兄end", 0, 0, 0);
ESP_LOGI(TAG, "publish successful, msg_id=%d", msg_id);
msg_id = esp_mqtt_client_unsubscribe(client, "/小康师兄/topic/wait");
ESP_LOGI(TAG, "unsubscribe successful, msg_id=%d", msg_id);
}
break;
case MQTT_EVENT_ERROR:
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
}
break;
default:
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
break;
}
return ESP_OK;
}
六、关键函数
6.1 MQTT初始化
esp_mqtt_client_config_t
:mqtt配置参数
/**
* MQTT client configuration structure
*/
typedef struct {
mqtt_event_callback_t event_handle; /*!< handle for MQTT events as a callback in legacy mode */
esp_event_loop_handle_t event_loop_handle; /*!< handle for MQTT event loop library */
const char *host; /*!< MQTT server domain (ipv4 as string) */
const char *uri; /*!< Complete MQTT broker URI */
uint32_t port; /*!< MQTT server port */
const char *client_id; /*!< default client id is ``ESP32_%CHIPID%`` where %CHIPID% are last 3 bytes of MAC address in hex format */
const char *username; /*!< MQTT username */
const char *password; /*!< MQTT password */
const char *lwt_topic; /*!< LWT (Last Will and Testament) message topic (NULL by default) */
const char *lwt_msg; /*!< LWT message (NULL by default) */
int lwt_qos; /*!< LWT message qos */
int lwt_retain; /*!< LWT retained message flag */
int lwt_msg_len; /*!< LWT message length */
int disable_clean_session; /*!< mqtt clean session, default clean_session is true */
int keepalive; /*!< mqtt keepalive, default is 120 seconds */
bool disable_auto_reconnect; /*!< this mqtt client will reconnect to server (when errors/disconnect). Set disable_auto_reconnect=true to disable */
void *user_context; /*!< pass user context to this option, then can receive that context in ``event->user_context`` */
int task_prio; /*!< MQTT task priority, default is 5, can be changed in ``make menuconfig`` */
int task_stack; /*!< MQTT task stack size, default is 6144 bytes, can be changed in ``make menuconfig`` */
int buffer_size; /*!< size of MQTT send/receive buffer, default is 1024 (only receive buffer size if ``out_buffer_size`` defined) */
const char *cert_pem; /*!< Pointer to certificate data in PEM or DER format for server verify (with SSL), default is NULL, not required to verify the server. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in cert_len. */
size_t cert_len; /*!< Length of the buffer pointed to by cert_pem. May be 0 for null-terminated pem */
const char *client_cert_pem; /*!< Pointer to certificate data in PEM or DER format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_key_pem` has to be provided. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in client_cert_len. */
size_t client_cert_len; /*!< Length of the buffer pointed to by client_cert_pem. May be 0 for null-terminated pem */
const char *client_key_pem; /*!< Pointer to private key data in PEM or DER format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_cert_pem` has to be provided. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in client_key_len */
size_t client_key_len; /*!< Length of the buffer pointed to by client_key_pem. May be 0 for null-terminated pem */
esp_mqtt_transport_t transport; /*!< overrides URI transport */
int refresh_connection_after_ms; /*!< Refresh connection after this value (in milliseconds) */
const struct psk_key_hint* psk_hint_key; /*!< Pointer to PSK struct defined in esp_tls.h to enable PSK authentication (as alternative to certificate verification). If not NULL and server/client certificates are NULL, PSK is enabled */
bool use_global_ca_store; /*!< Use a global ca_store for all the connections in which this bool is set. */
int reconnect_timeout_ms; /*!< Reconnect to the broker after this value in miliseconds if auto reconnect is not disabled (defaults to 10s) */
const char **alpn_protos; /*!< NULL-terminated list of supported application protocols to be used for ALPN */
const char *clientkey_password; /*!< Client key decryption password string */
int clientkey_password_len; /*!< String length of the password pointed to by clientkey_password */
esp_mqtt_protocol_ver_t protocol_ver; /*!< MQTT protocol version used for connection, defaults to value from menuconfig*/
int out_buffer_size; /*!< size of MQTT output buffer. If not defined, both output and input buffers have the same size defined as ``buffer_size`` */
bool skip_cert_common_name_check; /*!< Skip any validation of server certificate CN field, this reduces the security of TLS and makes the mqtt client susceptible to MITM attacks */
bool use_secure_element; /*!< enable secure element for enabling SSL connection */
void *ds_data; /*!< carrier of handle for digital signature parameters */
int network_timeout_ms; /*!< Abort network operation if it is not completed after this value, in milliseconds (defaults to 10s) */
bool disable_keepalive; /*!< Set disable_keepalive=true to turn off keep-alive mechanism, false by default (keepalive is active by default). Note: setting the config value `keepalive` to `0` doesn't disable keepalive feature, but uses a default keepalive period */
} esp_mqtt_client_config_t;
esp_mqtt_client_handle_t esp_mqtt_client_init(const esp_mqtt_client_config_t *config)
6.2 MQTT事件的回调函数
client
:mqtt实例event
:mqtt事件idevent_handler
:回调函数event_handler_arg
:回调参数
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)
6.3 MQTT启动
使用已创建的MQTT实例启动MQTT。
client
:mqtt实例
esp_err_t esp_mqtt_client_start(esp_mqtt_client_handle_t client)
6.4 MQTT订阅
client
:mqtt实例topic
:需要订阅的标题qos
:quality of service,即 “质量服务”- 0,At most once,至多一次;
- 1,At least once,至少一次;
- 2,Exactly once,确保只有一次
int esp_mqtt_client_subscribe(esp_mqtt_client_handle_t client, const char *topic, int qos)
6.5 MQTT取消订阅
client
:mqtt实例topic
:需要取消订阅的标题
int esp_mqtt_client_unsubscribe(esp_mqtt_client_handle_t client, const char *topic)
6.6 MQTT发布
client
:mqtt实例topic
:标题data
:数据len
:数据长度retain
:保留标志qos
:quality of service,即 “质量服务”- 0,At most once,至多一次;
- 1,At least once,至少一次;
- 2,Exactly once,确保只有一次
int esp_mqtt_client_publish(esp_mqtt_client_handle_t client, const char *topic, const char *data, int len, int qos, int retain)
七、参考
ESP-MQTT - ESP32-C3 - —ESP-IDF 编程指南 latest 文档
觉得好,就一键三连呗(点赞+收藏+关注)
以上是关于ESP32-C3入门教程 网络篇⑦——MQTT 应用示例的主要内容,如果未能解决你的问题,请参考以下文章
ESP32-C3入门教程 网络篇⑤——TCP Socket Client 客户端应用示例
ESP 保姆级教程玩转巴法云篇② ——MQTT设备云,MQTT协议下的数据通信