【ESP32-C3-DevKitM-1】ESP32-C3连接MQTT服务器
<p style="text-align:justify"> </p><p style="text-indent:21.0000pt; text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="Calibri">MQTT</font><font face="宋体">是一种发布和订阅式的消息协议,它是基于</font><font face="Calibri">TCP/IP</font><font face="宋体">协议上的。它所具备的特点就是轻量、简单、开放和易于实现。它其实是一个消息中间商,设备发布主题,设备再订阅主图,只要订阅和发布的</font><font face="Calibri">TOPIC</font><font face="宋体">一致,我就把消息传过去。可以一对多。使用</font><font face="Calibri">ESP32-C3</font><font face="宋体">来测试一下</font><font face="Calibri">MQTT</font><font face="宋体">协议。</font></span></span></span></span></p>
<p style="text-indent:21.0000pt; text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">使用的硬件:</font><font face="Calibri">ESP32-C3</font></span></span></span></span></p>
<p style="text-indent:21.0000pt; text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">客户端:</font><font face="Calibri">MQTTX</font><font face="宋体">(如图)</font></span></span></span></span></p>
<p class="imagemiddle" style="text-align: center;"></p>
<p style="text-indent:21.0000pt; text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">程序是基于</font><font face="Calibri">MQTT/TCP</font><font face="宋体">例程编写:</font></span></span></span></span></p>
<p style="text-indent:21.0000pt; text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="Calibri">1</font><font face="宋体">、只需要配置要连接的</font><font face="Calibri">MQTT</font><font face="宋体">服务器的</font><font face="Calibri">URL</font><font face="宋体">即可,并且要设置</font><font face="Calibri">wifi</font><font face="宋体">的密码和</font><font face="Calibri">SSID</font><font face="宋体">。</font></span></span></span></span></p>
<p style="text-indent:21.0000pt; text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">我这里使用</font><font face="Calibri">"mqtt://broker.emqx.io"</font></span></span></span></span></p>
<ol start="2">
<li style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">下载,并打开监视器。</font></span></span></span></span></li>
<li style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">在</font><font face="Calibri">MQTTX</font><font face="宋体">客户端创建连接,并订阅主题</font><font face="Calibri">/topic/qos0</font><font face="宋体">。就可以在客户端发送消息给</font><font face="Calibri">ESP32</font><font face="宋体">。效果如图所示。</font></span></span></span></span></li>
</ol>
<p class="imagemiddle" style="text-align: center;"></p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"></p>
<p align="justify" style="margin-left:28px; text-align:justify"> </p>
<p align="justify" style="text-align:justify"> 4、程序</p>
<pre>
<code>/* MQTT (over TCP) Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "protocol_examples_common.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "esp_log.h"
#include "mqtt_client.h"
static const char *TAG = "MQTT_EXAMPLE";
static void log_error_if_nonzero(const char * message, int error_code)
{
if (error_code != 0) {
ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code);
}
}
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/qos1", "data_3", 0, 1, 0);
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
//订阅TOPIC:/topic/qos0
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
//订阅TOPIC:/topic/qos1
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
//取消订阅TOPIC:/topic/qos1
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");
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;
}
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)
{
//定义一个MQTT客户端配置结构体,输入MQTT的url
esp_mqtt_client_config_t mqtt_cfg = {
// .uri = CONFIG_BROKER_URL,
.uri= "mqtt://broker.emqx.io"
};
#if CONFIG_BROKER_URL_FROM_STDIN
char line;
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 = '\0';
break;
} else if (c > 0 && c < 127) {
line = 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 */
//通过esp_mqtt_client_init获取MQTT客户端结构体指针,参数为MQTT客户端配置结构体
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);
//开启MQTT功能
esp_mqtt_client_start(client);
}
void app_main(void)
{
ESP_LOGI(TAG, " Startup..");
ESP_LOGI(TAG, " Free memory: %d bytes", esp_get_free_heap_size());
ESP_LOGI(TAG, " 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.
*/
//连接WIFI
ESP_ERROR_CHECK(example_connect());
mqtt_app_start();
}
</code></pre>
<p align="justify" style="text-indent:21.0000pt; text-align:justify"> </p>
<p>C确实麻烦,前几年用java做mqtt,简直比C舒服太多了。</p>
freebsder 发表于 2021-7-30 16:17
C确实麻烦,前几年用java做mqtt,简直比C舒服太多了。
<p>膜拜大佬,小白只会C</p>
<p>谢谢分享!</p>
页:
[1]