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);
}
更多推荐
所有评论(0)