野路子學習esp32(十三) 自動鏈接WiFi並啟動MQTT 學習記錄@a.宏萬


最近真的被樂鑫官方的idf搞瘋了,對於我這樣的野路子選手來說 ,簡直就是災難。
不會c 不懂底層 不知道啥 指針 還好看很多英文的官方案例,簡直了

最近幾天的研究成果,貼個代碼出來,基本上的功能就是 開機自動鏈接wifi  並啟動 MQTT
收到mqtt消息后 根據消息內容做處理 

這個地方還是找了一個大師 幫忙踩解決的 
mqtt發過來的消息是一個char*  我們做判斷是用字符串  char  

解決方案

            char Mqtt_data[100]; 
            sprintf(Mqtt_data,"%.*s", event->data_len , event->data);  

            printf("Mqtt_data=%s\r\n", Mqtt_data);  

            if(strcmp("switch",Mqtt_data)==0)
            {
                LED(300);
            }        

 

這樣就可以對比了  字符串對比函數 

strcmp

還有 如果我們把數據保存在 nvs_flash  中,比如我寫的 把wifi的信息保存了,但是怎么取出來使用呢 ,

網上是沒有人說的 

解決方案

 

    ESP_ERROR_CHECK(nvs_flash_init());
    nvs_handle_t my_handle;
    nvs_open("WIFICONFIG", NVS_READWRITE, &my_handle);//打開

    //ESP_ERROR_CHECK(nvs_set_str(my_handle, "WIFI_SSID", "xz220"));////ESP_ERROR_CHECK(nvs_set_str(my_handle, "WIFI_PASSWORD", "www.kyhmy.com"));//
  
    size_t required_size_SSID;
    nvs_get_str(my_handle, "WIFI_SSID", NULL, &required_size_SSID);
    char *WIFI_SSID = malloc(required_size_SSID);
    nvs_get_str(my_handle, "WIFI_SSID", WIFI_SSID, &required_size_SSID);
    printf("WIFI_SSID=%s\r\n", WIFI_SSID);  

    size_t required_size_PASSWORD;
    nvs_get_str(my_handle, "WIFI_PASSWORD", NULL, &required_size_PASSWORD);
    char *WIFI_PASSWORD = malloc(required_size_PASSWORD);
    nvs_get_str(my_handle, "WIFI_PASSWORD", WIFI_PASSWORD, &required_size_PASSWORD);
    printf("WIFI_PASSWORD=%s\r\n", WIFI_PASSWORD);  
 
    ESP_ERROR_CHECK(nvs_commit(my_handle));//提交
    nvs_close(my_handle);//退出

 

以上代碼 說明了 如果讀寫 nvs_flash
但是讀取到的信息同樣是 char*

我們需要的是
     wifi_config_t sta_config = {
        .sta = {
            .ssid = "ssid",
            .password ="password",
            .bssid_set = false
        }
    };

 

解決方法

 size_t len_SSID = required_size_SSID < 32 ? required_size_SSID : 32;
    memcpy(sta_config.sta.ssid,WIFI_SSID,len_SSID);

    size_t len_PASSWORD = required_size_PASSWORD < 64 ? required_size_PASSWORD : 64;
    memcpy((void *)sta_config.sta.password, (const void *)WIFI_PASSWORD, len_PASSWORD);

使用內存復制的方案,直接將char* 指針復制到 WiFi的配置中

 

以下是全部的代碼 基本上是官方文檔的案例

 

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
 
#include "esp_wifi.h" 
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "driver/gpio.h"

#include "esp_log.h"
#include "mqtt_client.h"


#include <sys/param.h>
#include "tcpip_adapter.h"
#include "esp_eth.h"

#include <esp_http_server.h>



static const char *TAG = "HwClient";

esp_err_t event_handler(void *ctx, system_event_t *event)
{
    return ESP_OK;
}

static void LED(int32_t time) {
    gpio_set_level(GPIO_NUM_2, 1);
    vTaskDelay(time / portTICK_PERIOD_MS);
    gpio_set_level(GPIO_NUM_2, 0);
}

static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
{
    esp_mqtt_client_handle_t client = event->client;
    int msg_id;
    // your_context_t *context = event->context;
    switch (event->event_id) {
        case MQTT_EVENT_CONNECTED://連接事件 
            ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
            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://斷開事件
            ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
            break;

        case MQTT_EVENT_SUBSCRIBED://訂閱事件 
            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://未訂閱事件
            ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_PUBLISHED://發布的事件
            ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_DATA://數據事件
            ESP_LOGI(TAG, "MQTT_EVENT_DATA");
            printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);   
            //printf("DATA=%.*s", event->data_len , event->data);  
             
            char Mqtt_data[100]; 
            sprintf(Mqtt_data,"%.*s", event->data_len , event->data);  

           
            printf("Mqtt_data=%s\r\n", Mqtt_data);  

            if(strcmp("switch",Mqtt_data)==0)
            {
                LED(300);
            }    
            if(strcmp("LongPress",Mqtt_data)==0) 
            {
                LED(5000);
            }     
            break;
        case MQTT_EVENT_ERROR://錯誤事件
            ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
            break;
        case MQTT_EVENT_BEFORE_CONNECT: //事件在連接之前發生

            break;
        default:
            ESP_LOGI(TAG, "Other event id:%d", event->event_id);
            break;
    }
    return ESP_OK;
}

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);
    mqtt_event_handler_cb(event_data);
} 


void app_main()
{   
    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_TCP", ESP_LOG_VERBOSE);
    esp_log_level_set("TRANSPORT_SSL", 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());
    nvs_handle_t my_handle;
    nvs_open("WIFICONFIG", NVS_READWRITE, &my_handle);//打開

    //ESP_ERROR_CHECK(nvs_set_str(my_handle, "WIFI_SSID", "xz220"));////ESP_ERROR_CHECK(nvs_set_str(my_handle, "WIFI_PASSWORD", "www.kyhmy.com"));//
  
    size_t required_size_SSID;
    nvs_get_str(my_handle, "WIFI_SSID", NULL, &required_size_SSID);
    char *WIFI_SSID = malloc(required_size_SSID);
    nvs_get_str(my_handle, "WIFI_SSID", WIFI_SSID, &required_size_SSID);
    printf("WIFI_SSID=%s\r\n", WIFI_SSID);  

    size_t required_size_PASSWORD;
    nvs_get_str(my_handle, "WIFI_PASSWORD", NULL, &required_size_PASSWORD);
    char *WIFI_PASSWORD = malloc(required_size_PASSWORD);
    nvs_get_str(my_handle, "WIFI_PASSWORD", WIFI_PASSWORD, &required_size_PASSWORD);
    printf("WIFI_PASSWORD=%s\r\n", WIFI_PASSWORD);  
 
    ESP_ERROR_CHECK(nvs_commit(my_handle));//提交
    nvs_close(my_handle);//退出
 

    tcpip_adapter_init();
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    ESP_ERROR_CHECK( esp_event_loop_init(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) );
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
 
     wifi_config_t sta_config = {
        .sta = {
            .ssid = "ssid",
            .password ="password",
            .bssid_set = false
        }
    };

    size_t len_SSID = required_size_SSID < 32 ? required_size_SSID : 32;
    memcpy(sta_config.sta.ssid,WIFI_SSID,len_SSID);

    size_t len_PASSWORD = required_size_PASSWORD < 64 ? required_size_PASSWORD : 64;
    memcpy((void *)sta_config.sta.password, (const void *)WIFI_PASSWORD, len_PASSWORD);

    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) );
    ESP_ERROR_CHECK( esp_wifi_start() );
    ESP_ERROR_CHECK( esp_wifi_connect() );
  
    const esp_mqtt_client_config_t mqtt_cfg = {
    .host = "*.*.*.*", 
    };
    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);
    ESP_ERROR_CHECK(esp_mqtt_client_start(client));
 
    gpio_set_direction(GPIO_NUM_2, GPIO_MODE_OUTPUT);  
 
}
 

 

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM