本次连接使用的是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);
}

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐