本文主要是介绍ESP32使用MQTT_TCP连接阿里云,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
ESP32-IDF中MQTT函数的介绍
-
esp_mqtt_client_handle_t esp_mqtt_client_init(const esp_mqtt_client_config_t *config)
函数功能:mqtt 客户端初始化
函数形参: mqtt 客户端的配置
函数返回值:正确则返回根据配置创建的 mqtt 客户端句柄;异常则返回 NULL。其中函数形参 esp_mqtt_client_config_t 的结构体定义如下:
typedef struct {mqtt_event_callback_t event_handle; / *!<处理MQTT事件作为传统模式的回调* /esp_event_loop_handle_t event_loop_handle; / *!<MQTT事件循环库的句柄* /const char * host; / *!<MQTT服务器域(IP地址或者域名)(ipv4 as string)* /const char * uri; / *!<完整的MQTT代理URI 需包含IP地址+端口号 * /uint32_t port; / *!<MQTT服务器端口* /const char * client_id; / *!<默认客户端ID是``ESP32_%CHIPID%``其中%CHIPID%是十六进制格式的MAC地址的最后3个字节* /const char * username; / *!<MQTT用户名* /const char *密码; / *!<MQTT密码* /const char * lwt_topic; / *!<LWT(遗嘱和遗嘱)消息主题(默认为NULL)* /const char * lwt_msg; / *!<LWT消息(默认为NULL)* /int lwt_qos; / *!<LWT消息qos * /int lwt_retain; / *!<LWT保留消息标志* /int lwt_msg_len; / *!<LWT消息长度* /int disable_clean_session; / *!<mqtt clean session,默认clean_session为true * /int keepalive; / *!<mqtt keepalive,默认为120秒* /bool disable_auto_reconnect; / *!<此mqtt客户端将重新连接到服务器(当出错/断开连接时)。设置disable_auto_reconnect = true以禁用* /void * user_context; / *!<将用户上下文传递给此选项,然后可以在``event-> user_context`` * /中接收该上下文int task_prio; / *!<MQTT任务优先级,默认为5,可以在``make menuconfig``中更改* /int task_stack; / *!<MQTT任务堆栈大小,默认为6144字节,可以在``make menuconfig``中更改* /int buffer_size; / *!<MQTT发送/接收缓冲区的大小,默认为1024 * /const char * cert_pem; / *!<用于服务器验证的PEM格式的证书数据指针(使用SSL),默认为NULL,不需要验证服务器* /const char * client_cert_pem; / *!<指向用于SSL相互身份验证的PEM格式的证书数据的指针,默认为NULL,如果不需要相互身份验证,则不需要。如果它不是NULL,则还必须提供`client_key_pem`。 * /const char * client_key_pem; / *!<指向用于SSL相互身份验证的PEM格式的私钥数据的指针,默认为NULL,如果不需要相互身份验证,则不需要。如果它不是NULL,则还必须提供`client_cert_pem`。 * /esp_mqtt_transport_t transport; / *!<覆盖URI传输* /int refresh_connection_after_ms; / *!<刷新此值后的连接(以毫秒为单位)* /
esp_mqtt_client_config_t;
-
esp_err_t esp_mqtt_client_start(esp_mqtt_client_handle_t client)
函数功能:mqtt 客户端启动
函数形参:创建的 mqtt 客户端句柄
函数返回值:ESP_OK表示成功 ESP_ERR表示无效 ESP_ARG表示没有初始化 ESP_FERT表示其他错误 -
esp_err_t esp_mqtt_client_stop(esp_mqtt_client_handle_t client)
函数功能:mqtt 客户端停止
函数形参:创建的 mqtt 客户端句柄
函数返回值:ESP_OK表示成功 ESP_FAIL表示失败 -
int esp_mqtt_client_subscribe(esp_mqtt_client_handle_t client, const char *topic, int qos)
函数功能:订阅主题
函数形参:
- esp_mqtt_client_handle_t 创建的 mqtt 客户端句柄
- char *topic 订阅的主题
- int qos Qos级别:0,1,2(阿里云只支持QOS0和QOS1)
函数返回值:成功返回订阅消息返回Message_id;失败返回-1
- int esp_mqtt_client_unsubscribe(esp_mqtt_client_handle_t client, const char *topic)
函数功能:取消订阅主题
函数形参:
- esp_mqtt_client_handle_t 创建的 mqtt 客户端句柄
- char *topic 取消订阅的主题
函数返回值:成功返回取消订阅消息返回Message_id;失败返回-1
- esp_mqtt_client_publish(esp_mqtt_client_handle_t client, const char *topic, const char *data, int len, int qos, int retain)
函数功能:mqtt 客户端往代理(broker)发布消息
函数形参:
- esp_mqtt_client_handle_t 创建的 mqtt 客户端句柄
- char *topic 发布消息的主题
- const char *data 发布消息的内容
- int len 发布消息内容的长度
- int qos QOSx信号质量
- int retain 当我们使用MQTT客户端发布消息(PUBLISH)时,如果将RETAIN标志位设置为true,那么MQTT服务器会将最近收到的一条RETAIN标志位为true的消息保存在服务器端,只要订阅该主题的新设备上线没就能收到该消息。
函数返回值:成功返回发布消息返回Message_id;失败返回-1
- 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 事件
函数形参:
- esp_mqtt_client_handle_t 创建的 mqtt 客户端句柄
- esp_mqtt_event_id_t event 注册任何事件id的处理程序
- esp_event_handler_t event_handler mqtt 事件回调函数
- void* event_handler_arg 处理程序上下文
实验内容
在工程是基于 ESP-IDF的 MQTT_TCP 例程上修改
-
配置WIFI的SSID和密码,使得开发板能够正常连接无线网,配置正确的密码后,点击保存.
-
初始化 mqtt 客户端的连接配置
配置阿里云 mqtt 的连接地址,并使用签名鉴权的方式认证登录
TIPS: 在配置mqtt代理的地址时,请配置在 host 变量中,如果使用uri,请使用完整的ip+端口号的字符串格式才能正常连接。 -
订阅并发布消息
static const char *TAG = "MQTT_EXAMPLE";
esp_mqtt_client_handle_t client;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");/* 发布一条主题为“fc_boardstatus” 的消息 */msg_id = esp_mqtt_client_publish(client, "fc_boardstatus", "data_3", 0, 1, 0);ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);/* 订阅主题为“fc_ctrlcmd” 的消息 */msg_id = esp_mqtt_client_subscribe(client, "fc_ctrlcmd", 0);ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);//msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);//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:ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");break;case MQTT_EVENT_SUBSCRIBED:ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "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:ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);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);break;case MQTT_EVENT_ERROR: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)
{esp_mqtt_client_config_t mqtt_cfg = {.host = "xxxxxxx.mqtt.aliyuncs.com", //CONFIG_BROKER_URL,//根据实际填写.port = 1883,.username = "Signature|oooooooooo|xxxxxxx", //根据实际填写.password = "?????????????",//根据实际填写.client_id = "GID_test@@@test0003",//根据实际填写};
#if CONFIG_BROKER_URL_FROM_STDINchar line[128];if (strcmp(mqtt_cfg.uri, "FROM_STDIN") == 0) {int count = 0;printf("Please enter url of mqtt broker\n");while (count < 128) {int c = fgetc(stdin);if (c == '\n') {line[count] = '\0';break;} else if (c > 0 && c < 127) {line[count] = c;++count;}vTaskDelay(10 / portTICK_PERIOD_MS);}mqtt_cfg.uri = line;printf("Broker url: %s\n", line);} else {ESP_LOGE(TAG, "Configuration mismatch: wrong broker url");abort();}
#endif /* CONFIG_BROKER_URL_FROM_STDIN */client = esp_mqtt_client_init(&mqtt_cfg);esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);esp_mqtt_client_start(client);
}void app_main(void)
{int msg_id;ESP_LOGI(TAG, "[APP] Startup..");ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());esp_log_level_set("*", ESP_LOG_INFO);esp_log_level_set("MQTT_CLIENT", ESP_LOG_VERBOSE);esp_log_level_set("MQTT_EXAMPLE", ESP_LOG_VERBOSE);esp_log_level_set("TRANSPORT_TCP", ESP_LOG_VERBOSE);esp_log_level_set("TRANSPORT_SSL", ESP_LOG_VERBOSE);esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE);esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE);ESP_ERROR_CHECK(nvs_flash_init());ESP_ERROR_CHECK(esp_netif_init());ESP_ERROR_CHECK(esp_event_loop_create_default());/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.* Read "Establishing Wi-Fi or Ethernet Connection" section in* examples/protocols/README.md for more information about this function.*/ESP_ERROR_CHECK(example_connect());//使用通过连接函数连接互联网mqtt_app_start();for (;;){/* 每隔10s 发布一次 主题为 “fc_boardstatus“ 的消息 */msg_id = esp_mqtt_client_publish(client, "fc_boardstatus", "data_3", 7, 0, 0);ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);vTaskDelay(10000 / portTICK_PERIOD_MS);}
}
实验结果
通过日志查看,及客户端订阅,能够正常订阅和发布。
纯手写文章,转载请注明出处,谢谢!
如有任何错误,欢迎留言指正!
这篇关于ESP32使用MQTT_TCP连接阿里云的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!