野路子学习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); }