我的编程空间,编程开发者的网络收藏夹
学习永远不晚

图文手把手教程--ESP32 MQTT对接EMQX本地服务器(VSCODE+ESP-IDF)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

图文手把手教程--ESP32 MQTT对接EMQX本地服务器(VSCODE+ESP-IDF)

本文内容

1)使用MQTT_TCP例程,ESP32通过MQTT协议与MQTT本地服务器(EMQX)进行通信。

2)如何搭建EMQX MQTT本地服务器。

3)如何使用MQTT.fx客户端调试工具或MQTTX客户端调试工具。

开发环境

1)系统平台:windows7或windows10。

2)开发板:乐鑫开发板ESP32-DevKitC-V4(模组是ESP32­WROOM­32E)。

3)集成开发环境:VSCODE+ESP-IDF插件,见以下链接

图文手把手教程(史上最强):windows下ESP32集成开发环境搭建和HelloWorld显示(乐鑫官方推荐方法-使用VSCode安装ESP-IDF插件)

一、准备工作

需要下载工具并安装,如下:

1.下载MQTT.fx客户端(版本v1.7.1):http://mqttfx.jensd.de/index.php/download,官网找不到下载入口?

这里提供博客下载:https://download.csdn.net/download/felix_tao/86248840

2.下载MQTT X客户端(版本v1.8.0.win64):https://mqttx.app/zh

二、搭建EMQX本地MQTT服务器

1.下载EMQX开源版,官方网址:https://www.emqx.com/zh/try?product=broker

选择版本号v5.0.3,系统:windows,然后点击“免费下载”。

 

2.将下载好的 emqx-5.0.3-windows-amd64.tar.gz,进行解压,我是解压到E盘根目录。

注意:根目录下最好不要有中文。

3.打开命令行工具,进入目录运行EMQX服务。

电脑左下角,右键开始->运行->输入cmd,确定->打开命令行工具,操作如下:

1)切换到E盘:输入e:

2)进入到EMQX的bin目录:输入cd E:\emqx-5.0.3-windows-amd64\bin

3)启动EMQX服务器,输入emqx start,如需停止服务器,输入emqx stop

4)查看EMQX服务器状态,先进入bin目录:输入cd E:\emqx-5.0.3-windows-amd64\bin

5)接着输入:emqx_ctl status,可以看到EMQX服务器已启动

 4.登陆EMQX服务器,验证是否可用。

1)打开浏览器,输入地址:http://127.0.0.1:18083/

2)输入用户名:admin,输入密码:public,点击Login

3)更改界面为中文。

至此,本地EMQX本地MQTT服务器已搭建成功。

三、MQTT.fx客户端简单说明,如下图所示。

1主页面
2通用设置界面
3用户信息设置
4安全证书设置
5网络代理设置
6遗嘱设置

 四、MQTT.fx客户端与WebSocket 客户端互发消息。

1.使用MQTT.fx连接到EMQX本地服务器。

1)General设置如下图所示。

 2)User Credentials设置。

 以上设置完毕后,点击Apply保存,然后关闭退出。

3)进行连接,亮绿灯,表示连接成功。

 2.MQTT.fx发布和订阅主题,以ESP32例程的topic主题为例。

1)MQTT.fx客户端发布主题:/topic/qos1,服务质量等级选择QoS1,消息内容如下:

{ "msg": "hello I am mqtt.fx" }

2)MQTT.fx客户端订阅主题:/topic/qos0,服务质量等级选择QoS0

3.登陆EMQX服务器管理页面,连接WebSocket 客户端到服务器,并发布和订阅主题。

1)打开WebSocket 客户端,输入IP地址、端口号,用户名和密码,即可连接。

 

2)WebSocket客户端订阅主题:/topic/qos1,服务质量等级选择QoS1。

3)WebSocket客户端发布主题:/topic/qos0,服务质量等级选择QoS0,消息内容如下:

{ "msg": "hello I am emqx web" }

4.MQTT.fx客户端与WebSocket 客户端互发消息。

1)MQTT.fx客户端发送,WebSocket 客户端接收。

 

2)WebSocket 客户端发送,MQTT.fx客户端接收。

 

至此, MQTT.fx客户端与WebSocket 客户端互发消息成功,服务器是EMQX。

 五、ESP32连接到EMQX服务器,与MQTT.fx客户端互发消息

1.VSCODE+ESP-IDF插件开发环境的搭建,见本文的开头的链接。

2.打开示例项目MQTT_TCP:VSCODE中->"查看"->”命令面板“->输入:Show Examples projects->选择Use current ESP-IDF(E:\ESP32-IDF\esp\esp-idf)->弹出示例ESP-IDF Examples,选择mqtt->tcp->Create project using example tcp->选择示例保存的路径。

 例如:E:\ESP32-IDF\project-example,因ESP-IDF框架与示例是分离的,所以示例保存的路径可以随意,但需要注意:路径不能有中文和空格,否则报错。

 创建完后,如下图所示。

关于示例的说明,请阅读官方的注释。

 打开E:\ESP32-IDF\esp\esp-idf\examples\protocols->README,如下图所示。

 README的内容如下:

 对示例有个大概了解后,接下来需要修改代码。

3.修改示例代码。

1)修改wifi配置,这里修改为自己的wifi帐号和密码即可。

wifi_config_t wifi_config = {        .sta = {            .ssid = "Xiaomi_tao",            .password = "123456",        },    };

2)修改MQTT配置,如果是使用EMQX本地服务器,即只需要修改MQTT服务器IP即可。

注意:这里的IP是指自己电脑的IPv4地址,如果是win7系统,ESP32连不上EMQX服务器,则需要将IPv4地址修改为静态固定IP地址,我这里是win10系统,不改固定IP地址也可以连上。

esp_mqtt_client_config_t mqtt_cfg = {        .host = "192.168.31.107",                  //MQTT服务器IP        .event_handle = mqtt_event_handler,        //MQTT事件        .port=1883,    //端口        .username = "admin",                       //用户名        .password = "public",                      //密码        // .user_context = (void *)your_context    };

3.修改app_main.c,如下:

#include #include #include #include #include "esp_wifi.h"#include "esp_system.h"#include "nvs_flash.h"#include "esp_event.h"#include "esp_netif.h"#include "esp_event_loop.h"#include "tcpip_adapter_types.h"//#include "protocol_examples_common.h"#include "freertos/FreeRTOS.h"#include "freertos/task.h"#include "freertos/semphr.h"#include "freertos/queue.h"#include "freertos/event_groups.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";//wifi连上事件static EventGroupHandle_t wifi_event_group;//mqtt连上事件static EventGroupHandle_t mqtt_event_group;const static int CONNECTED_BIT = BIT0;esp_mqtt_client_handle_t mqttclient;// 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 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);    esp_mqtt_event_handle_t event = event_data;    esp_mqtt_client_handle_t client = event->client;    int msg_id;    switch ((esp_mqtt_event_id_t)event_id) {    case MQTT_EVENT_CONNECTED:  //MQTT连上事件        ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");        xEventGroupSetBits(mqtt_event_group, CONNECTED_BIT);                //发布主题        // printf("Connecting to MQTT broker OK");        // 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);                // //发送订阅        // msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 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:  //MQTT断开连接事件        ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");        //mqtt连上事件        xEventGroupClearBits(mqtt_event_group, CONNECTED_BIT);        break;    case MQTT_EVENT_SUBSCRIBED:  //MQTT发送订阅事件        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:  //MQTT取消订阅事件        ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);        break;    case MQTT_EVENT_PUBLISHED:  //MQTT发布事件        ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);        break;    case MQTT_EVENT_DATA:  //MQTT接受数据事件        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:  //MQTT错误事件        ESP_LOGI(TAG, "MQTT_EVENT_ERROR");        xEventGroupClearBits(mqtt_event_group, CONNECTED_BIT);        // 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;    }}//wifi状态机static esp_err_t wifi_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:            xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);            break;        case SYSTEM_EVENT_STA_DISCONNECTED:            esp_wifi_connect();            xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);            break;        default:            break;    }    return ESP_OK;}//wifi初始化static void wifi_init(void){    tcpip_adapter_init();    wifi_event_group = xEventGroupCreate();    mqtt_event_group = xEventGroupCreate();    ESP_ERROR_CHECK(esp_event_loop_init(wifi_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 = "Xiaomi_tao",            .password = "123456",        },    };    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));    ESP_LOGI(TAG, "start the WIFI SSID:[%s]", wifi_config.sta.ssid);    ESP_ERROR_CHECK(esp_wifi_start());    ESP_LOGI(TAG, "Waiting for wifi");    //等待wifi连上    xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);}//mqtt初始化static void mqtt_app_start(void){    esp_mqtt_client_config_t mqtt_cfg = {        .host = "192.168.31.107",                  //MQTT服务器IP        .event_handle = mqtt_event_handler,        //MQTT事件        .port=1883,    //端口        .username = "admin",                       //用户名        .password = "public",                      //密码        // .user_context = (void *)your_context    };#if CONFIG_BROKER_URL_FROM_STDIN    char 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     printf("esp_mqtt_client_start\r\n");    //通过esp_mqtt_client_init获取一个MQTT客户端结构体指针,参数是MQTT客户端配置结构体    mqttclient = esp_mqtt_client_init(&mqtt_cfg);            //注册MQTT事件    esp_mqtt_client_register_event(mqttclient, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);    //开启MQTT功能    esp_mqtt_client_start(mqttclient);    //等mqtt连上    xEventGroupWaitBits(mqtt_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);}void app_main(void){    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_BASE", ESP_LOG_VERBOSE);    esp_log_level_set("esp-tls", 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());        //ESP_ERROR_CHECK(example_connect());    nvs_flash_init();    wifi_init();    mqtt_app_start();    while (1) {                printf("system is running!\r\n");        //发布主题        esp_mqtt_client_publish(mqttclient, "/topic/qos0", "Hello MQTT,I am ESP32", 0, 0, 0);        vTaskDelay(1000 / portTICK_PERIOD_MS);    }}

4.修改完毕后,编译下载,打开串口调试助手,可以看到连接EMQX服务器成功。

注意:EMQX服务器,每次开机后,都要重新启动,\bin目示下,命令:emqx start。

5.打开EMQX服务器网页http://127.0.0.1:18083/,可以看到ESP32与MQTT.fx都连接成功。

 6.ESP32与MQTT.fx客户端互通消息。

1)ESP32主动发送消息给MQTT.fx客户端。

2)MQTT.fx客户端发送消息给ESP32。

 7.ESP32与MQTTX客户端互通消息,与MQTT.fx客户端用法是一样的。

1)修改中文版本。

2)填写相关信息。

 2)ESP32主动发送消息给MQTTX客户端。

3)MQTTX客户端发送消息给ESP32。

 至此,本文内容全部完毕,愉快的玩耍吧!

完整的例程代码下载:https://download.csdn.net/download/felix_tao/86248836

使用例程,报错怎么办,解决办法如下:

1)打开VSCODE报错,c_cpp_properties.json无法找到E:\\ESP32-IDF...

解决办法:点击.vscode->c_cpp_properties.json,修改盘符即可,例如将E盘改为D盘。

2)编译工程报错:

[0/1] Re-running CMake...
FAILED: build.ninja 
CreateProcess failed: The system cannot find the file specified.
ninja: error: rebuilding 'build.ninja': subcommand failed

解决方法:清除编译产生的所有文件,左下角->点击垃圾桶图标(ESP-IDF Full Clean)->清除后,接着重新编译即OK。

本文参考了以下博客,鸣谢!

第二十一章 ESP32开发MQTT Client ESP-IDF_开源一小步的博客-CSDN博客_esp32 mqtt

mqtt.fx | 一款超级好用的Mqtt客户端软件(下载、安装、使用详解)_Mculover666的博客-CSDN博客_mqtt.fx

验证EMQ X服务器的搭建以及MQTTX的简单使用_哈哈浩丶的博客-CSDN博客

来源地址:https://blog.csdn.net/felix_tao/article/details/125882339

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

图文手把手教程--ESP32 MQTT对接EMQX本地服务器(VSCODE+ESP-IDF)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

目录