zoukankan      html  css  js  c++  java
  • 野路子学习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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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);  
     
    }
     
     



  • 相关阅读:
    微信跳一跳,Python辅助自动跳程序
    关于 adb devices找不到的解决方法
    vue--axios使用post方法与后台进行异步传值是报错POST http://localhost:8080/api/AddEmployeeApi 405 (METHOD NOT ALLOWED)
    vue 中引入外部css路径中使用@报错,提示找不到文件
    centos7服务器配置接口供外网调用
    排球计分程序改进
    排球计分程序(九)——总结
    排球计分程序(八)——验证编辑方法(Edit method)和编辑视图(Edit view)
    排球计分(七)—— 使用EF框架,创建Controller,生成数据库
    排球计分程序(六)——接口的设计与实现
  • 原文地址:https://www.cnblogs.com/hongwans/p/11239494.html
Copyright © 2011-2022 走看看