当前位置: 首页 > news >正文

esp32,使用esp-idf链接mqtt服务器,消息接收

本次连接使用的是mqtt的官方公共服务器,前提是要先链接wifi

注意:1.mqtt服务器发给esp32的消息,中间没有/0,使用“%s”这种格式打印的数据会自动往后打印,直到遇见/0,解决方法是

ESP_LOGI(TAG_MQTT,"topic->%.*s",mqtt_data->topic_len,mqtt_data->topic);

定长打印,根据参数里面的长度。

2.消息发送时使用strlen可以获取字符串或者数组的真实大小,不会发送数组的闲杂空位

snprintf(data,sizeof(data),"{data :%d}",a);
esp_mqtt_client_publish(client_handle,MQTT_TOPIC2,data,strlen(data),1,0);

#include <stdio.h> #include "mqtt_client.h" #include "esp_log.h" #include "esp_wifi.h" #include "nvs_flash.h" #include "esp_event.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include <string.h> #define mqtt_url "mqtt://broker-cn.emqx.io" #define mqtt_server_port 1883 #define mqtt_client_id "esp32s3_20260118" #define mqtt_username "esp32s3" #define mqtt_password "esp32s3_password" #define MQTT_TOPIC1 "/topic/esp32_0118" #define MQTT_TOPIC2 "/topic/mqttx_0118" #define TAG_MQTT "TAG_MQTT" #define TAG "STA" #define TAG2 "IP" #define SSID "Redmi" #define PASSWORD "123456789" TaskHandle_t mqtt_task_handel=NULL; //mqtt服务句柄 esp_mqtt_client_handle_t client_handle=NULL; QueueHandle_t esp32_wifi_sem=NULL; //声明mqtt发送消息的任务函数 void mqtt_send_task(); //wifi的事件回调函数 void wifi_cb(void* event_handler_arg,esp_event_base_t event_base,int32_t event_id,void* event_data){ if(event_base==WIFI_EVENT){ switch (event_id) { case WIFI_EVENT_STA_START://开启sta模式成功 esp_wifi_connect();//链接路由器 break; case WIFI_EVENT_STA_CONNECTED://成功连接到路由器 ESP_LOGI(TAG,"esp32s3 connected wifi"); break; case WIFI_EVENT_STA_DISCONNECTED://断开连接 ESP_LOGI(TAG,"esp32s3 disconnected wifi"); esp_wifi_connect(); break; default: break; } } else if (event_base==IP_EVENT) { switch (event_id) { case IP_EVENT_STA_GOT_IP: ESP_LOGI(TAG2,"esp32 got ip,connnecet success"); //释放二进制信号量,开启mqtt服务 xSemaphoreGive(esp32_wifi_sem); break; default: break; } } } //mqtt的事件回调函数 void mqtt_event_cb(void* event_handler_arg,esp_event_base_t event_base,int32_t event_id,void* event_data){ esp_mqtt_event_handle_t mqtt_data=(esp_mqtt_event_handle_t)event_data; switch (event_id) { case MQTT_EVENT_CONNECTED: ESP_LOGI(TAG_MQTT,"esp32 connect mqttserver"); //qos 是订阅的服务的级别,0表示无回应,1表示有,2表示一定有回应 esp_mqtt_client_subscribe_single(client_handle,MQTT_TOPIC1,1); break; case MQTT_EVENT_DISCONNECTED: ESP_LOGI(TAG_MQTT,"esp32 disconnect mqttserver"); break; case MQTT_EVENT_PUBLISHED: ESP_LOGI(TAG_MQTT,"esp32 recive mqttserver publish ack"); break; case MQTT_EVENT_SUBSCRIBED: ESP_LOGI(TAG_MQTT,"esp32 recive mqttserver subscribe ack"); break; case MQTT_EVENT_DATA: // ESP_LOGI(TAG_MQTT,"esp32 recive mqttserver data--------"); // ESP_LOGI(TAG_MQTT,"topic->%s",mqtt_data->topic); // ESP_LOGI(TAG_MQTT,"data->%s",mqtt_data->data); ESP_LOGI(TAG_MQTT,"esp32 recive mqttserver data--------"); ESP_LOGI(TAG_MQTT,"topic->%.*s",mqtt_data->topic_len,mqtt_data->topic); ESP_LOGI(TAG_MQTT,"data->%.*s",mqtt_data->data_len,mqtt_data->data); break; default: break; } } //mqtt配置函数 void mqtt_client_start(){ esp_mqtt_client_config_t mqtt_config={ .broker.address.uri=mqtt_url, .broker.address.port=mqtt_server_port, .credentials.client_id=mqtt_client_id, .credentials.username=mqtt_username, .credentials.authentication.password=mqtt_password, }; client_handle=esp_mqtt_client_init(&mqtt_config); esp_mqtt_client_register_event(client_handle,ESP_EVENT_ANY_ID,mqtt_event_cb,NULL); esp_mqtt_client_start(client_handle); } //mqtt发送消息的任务函数 void mqtt_send_task(){ //阻塞等待信号量 xSemaphoreTake(esp32_wifi_sem,portMAX_DELAY); //开启mqtt服务 mqtt_client_start(); char data[32]={0}; uint8_t a=0; while(1){ //strlen是实际大小,sizeof是数组定义的大小 snprintf(data,sizeof(data),"{data :%d}",a); esp_mqtt_client_publish(client_handle,MQTT_TOPIC2,data,strlen(data),1,0); a++; vTaskDelay(pdMS_TO_TICKS(1000)); } } void app_main(void) { //创建二进制信号量 esp32_wifi_sem=xSemaphoreCreateBinary(); //初始化nvs,后续会用来保存wifi的账号密码 nvs_flash_init(); //初始化网络接口(TCP/IP 协议栈相关) esp_netif_init(); //创建创建默认事件循环机制 esp_event_loop_create_default(); //创建默认的 STA(站点)网络接口对象。 esp_netif_create_default_wifi_sta(); //按照默认配置,初始化wifi的操作 wifi_init_config_t cfg=WIFI_INIT_CONFIG_DEFAULT(); esp_wifi_init(&cfg); //向事件循环里面加入回调函数,有对应事件发生时会自动调用回调函数 esp_event_handler_register(WIFI_EVENT,ESP_EVENT_ANY_ID,wifi_cb,NULL);//sta,数据链路层· //获取到ip,网络层 esp_event_handler_register(IP_EVENT,IP_EVENT_STA_GOT_IP,wifi_cb,NULL); //初始化 wifi_config_t,设置安全阈值和 PMF 能力。 wifi_config_t conf={ .sta.threshold.authmode=WIFI_AUTH_WPA2_PSK, .sta.pmf_cfg.capable=true, .sta.pmf_cfg.required=false, }; memset(conf.sta.ssid,0,strlen(SSID)); memcpy(conf.sta.ssid,SSID,strlen(SSID)); memset(conf.sta.password,0,strlen(PASSWORD)); memcpy(conf.sta.password,PASSWORD,strlen(PASSWORD)); esp_wifi_set_config(WIFI_IF_STA,&conf); esp_wifi_set_mode(WIFI_MODE_STA); //启动 Wi‑Fi,开始连接流程 esp_wifi_start(); //创建发送消息的任务 xTaskCreatePinnedToCore(mqtt_send_task,"mqtt_send_task",4096,NULL,2,&mqtt_task_handel,1); }
http://www.jsqmd.com/news/269906/

相关文章:

  • 从理论到代码:Agentic AI实时响应优化的提示工程实现与调试技巧
  • 腾讯云的IP是原生IP吗?
  • DeploySharp 全面支持 YOLO26 系列,助力开发者快速部署落地应用
  • 设备维修班的惊喜发现,CAXA三维球比扳手还好用
  • 02.01.05.菲力尔FLIR GigE相机 环境搭建篇(CentOS9系统下 areaDetector的aravis安装配置)
  • CAXA用一年省下六万外包费
  • 工程机械制造国产 CAD技工经验数字化传承应用
  • 02.01.04.菲力尔FLIR GigE相机 环境搭建篇(CentOS9系统下 areaDetector安装配置)
  • CAXA让大三学生爱上机械设计
  • 禅道8.2.1升级到12.5.3,浏览器提示“重定向次数过多”
  • 高通CEO安蒙播客访谈:移动DNA也能做好数据中心
  • 部署qwen14B 实战
  • 商旅平台有哪些?2026年主流商旅平台盘点及新趋势报告
  • 俄罗斯SALUTEDEV团队VIBE:超轻量AI实现高效图片编辑
  • mdadm 故障处理二
  • 当智能体爆发在即,数据库如何成为“发动机”?
  • [HAL库分析—GPIO] - 指南
  • Snap联手多所高校突破:静态模型实现动态化动画生成
  • django计算机毕设之基于大数据+django+网络爬虫的安客居二手房屋信息采集系统的设计与实现(完整前后端代码+说明文档+LW,调试定制等)
  • Vue2 vs Vue3:核心差异全面解析
  • 小波变换特征融合优化实战
  • 最强卸载工具Geek Uninstaller下载安装全流程图解(附免安装中文版资源包) - xiema
  • 03.01.01.菲力尔FLIR GigE相机 快速开始篇(ADSpinnaker案例 使用Eclise开发工具:创建Makefile项目方式 获取Spinnaker版本)
  • Vue+Laravel全栈开发实战指南
  • 【场景:识别C2通信】评估出站IP是否为已知恶意地址,方法:IP离线库+威胁情报融合
  • PHP8.2 vs 8.4:关键差异与升级指南
  • django毕设选题推荐:基于django数据可视化+网络爬虫的安客居二手房屋信息采集系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • IP定位技术:游戏反外挂体系中的精准识别引擎
  • 嵌入模型推理加速:ONNX Runtime在AI原生应用中的使用教程
  • 别慌!高AI率论文有救了:我的亲身降重全流程,从90%到10%只需这几招