本文内容

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/#/login

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,如下:

/* MQTT (over TCP) ExampleThis example code is in the Public Domain (or CC0 licensed, at your option.)Unless required by applicable law or agreed to in writing, thissoftware is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES ORCONDITIONS 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 "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);
//     }
// }/** @brief Event handler registered to receive MQTT events**  This function is called by the MQTT client event loop.** @param handler_args user data registered to the event.* @param base Event base for the handler(always MQTT Base in this example).* @param event_id The id for the received event.* @param event_data The data for the event, esp_mqtt_event_handle_t.*/
//事件处理函数
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_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 */printf("esp_mqtt_client_start\r\n");//通过esp_mqtt_client_init获取一个MQTT客户端结构体指针,参数是MQTT客户端配置结构体mqttclient = esp_mqtt_client_init(&mqtt_cfg);/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler *///注册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());/* 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());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/#/login,可以看到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博客

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

  1. 图文手把手教程--ESP32 MQTT连接阿里云生活物联网平台

    本文内容 1)在阿里云生活物联网平台,创建自有品牌项目,并在项目下创建产品"智能灯001". 2)下载阿里云SDK-esp-aliyun,使用例程smart_light,通过&qu ...

  2. 图文手把手教程--ESP32 MQTT连接腾讯云物联网平台及OTA固件升级

    本文内容 1)在腾讯云物联网开发平台,新建项目,并在项目下新建设备"light_001". 2)下载腾讯云SDK-esp-qcloud,使用例程led_light,通过" ...

  3. 图文手把手教程--ESP32 OTA空中升级(阿里云物联网平台)

    本文内容 1)使用ota_example_mqtt例程,通过阿里云物联网平台,进行OTA升级. 2)将例程编译成两个版本,版本1.0.0下载至ESP32开发板,版本2.0.0上传至阿里云物联网平台. ...

  4. 图文手把手教程--ESP32 OTA空中升级(VSCODE+IDF)

    本文内容 1)使用hello_world例程,编译生成hello_world.bin文件,并且开启HTTP本地服务器. 2)使用simple_ota_example例程,通过HTTP服务器访问hell ...

  5. 图文手把手教程--ESP32 一键配网(Smartconfig、Airkiss)

    本文内容 1)使用smart_config例程,使用乐鑫ESPTouch APP或者微信公众号配网. 2)修改smart_config例程,使ESP32复位后,如果已配过网,则不再进行配网,而是直接连 ...

  6. MQTT | Windows + mosquitto搭建MQTT Broker(本地服务器)与MQTTX客户端联调

    文章目录 一.前言 二.mosquitto 2.1.安装 2.2.修改mosquitto.conf配置文件 2.2.1.listener 2.2.2.allow_anonymous 2.2.3.pas ...

  7. ESP32联网-MQTT-连接到本地服务器(LInux)

    上一篇说到用JAVA写Linstener . 很多人会问网上有很多现成的(可视化的),为啥要自己写呢? 我想说自己写的话对MQTT协议会更加的了解,而且得到的数据到时候会更加好处理,现成的东西不带这功 ...

  8. 云服务器架设网站教程_手把手教你搭建腾讯云服务器入门(图文教程)

    本文由博主 威威喵 原创 博客主页:https://blog.csdn.net/smile_running 背景 暑假期间,愁着无聊但也不能荒废学业吧,毕竟以后想靠技术混口饭吃!为了实施自己的计划,特 ...

  9. EC20模组使用MQTT库对接EMQX,基于STM32F407

    一.说明 本lib库基于STM32F407编译,其他的cortexM4内核也支持,采用串口和EC20模组通信. 库包括两个文件:ec20_mqtt.h和ec20_mqtt.lib.使用时添加lib文件 ...

最新文章

  1. 某程序员遭遇奇葩事:辞退自己的leader竟然命令自己回前公司,给前同事讲代码!...
  2. python翻译程序-Python桌面应用案例:TXT文档翻译工具(源代码)
  3. C++map的基本操作和使用
  4. Python面试题:如何判断字典a在字典b
  5. 前端学习(2307):react之props和state
  6. 【转】在无人值守程序(服务)中调用Microsoft Graph
  7. 电脑开机显示checking media解决方法
  8. 【shell实例】定时21:00-21:05,循环调用DSQL脚本,其它时段自动退出
  9. 转:集群、分布式、负载均衡区别与联系
  10. 标题: Huffman树
  11. 基于javaEE的网上商城购物系统
  12. 如何把pdf转换成ezd_电脑怎么把pdf转换成ppt
  13. Ubuntu系统备份
  14. pwnthebox-rip
  15. 当Forms表单遇到Power BI
  16. 那些年啊,那些事——一个程序员的奋斗史 ——21
  17. 壁挂炉计算机控制系统,DIY壁挂炉温控器连入米家实现自动和远程控制
  18. 湖南大学计算机通信学院陈果,湖南大学考研研究生导师简介-陈果
  19. 2020阿里实习生校招笔试题
  20. nacos 单机部署_使用Docker部署Nacos-Server(单机版)

热门文章

  1. xbox one 手柄在ubuntu下的使用和开发
  2. Hyper-V下Centos7连接不上外网
  3. 查看yum安装软件的目录
  4. 八种网络攻击类型,你了解多少?
  5. Android百度地图显示POI
  6. 打开HFSS出现Unable to detect installed products的报错,要求make sure that config/admin.xml exists
  7. String的intern方法
  8. 纪录片拍摄前期准备内容
  9. Mysql按条件求和Sum函数
  10. 云计算基础:云计算运用越来越广泛,我们应该如何去学习云计算