esp8266 nvs應用

esp8266 nvs應用

一個芯片,做成一個產品,都會需要在斷定的時候對一些數據進行保存,以esp8266爲例,需要連接網絡,所以設備必須能夠保存ssid,password,否則設備如何聯網,本文就結合上篇文章at命令的開發,通過at命令將ssid,password調用nvs接口,將數據保存起來,設備開機,直接讀取後進行聯網操作。

1.增加at命令方法

1.at命令增加到列表

atcmd_table_t at_table[] = {
    {"AT+TEST",at_test_fun},
    {"AT+CONNECTWIFI",at_connect_wifi_fun},

};

2.實現at命令處理函數at_connect_wifi_fun
聯網(寫ssid,password):AT+CONNECTWIFI=1234,12345678[回車]
讀取ssid.password:AT+CONNECTWIFI=read[回車]

void at_connect_wifi_fun(int argc,char * argv)
{
    wifi_msg_t wifi_msg_new;
    char msg_str[64];
    char *p;
    nvs_handle handle_wifi;
    int len = 0;
    int rc;

    
    memset(&wifi_msg_new,0,sizeof(wifi_msg_new));
    memset(msg_str,0,64);

    //argc 參數長度,argv內容
    if(0 != strncmp(argv,"read",4))
    {
        printf("---write\n");
        //寫wifi ssid password
        memcpy(msg_str,argv,argc);
        printf("at parameter:%s\n",msg_str);
        
        p = strchr(msg_str,',');
        //提取ssid'
        memcpy(wifi_msg_new.ssid,msg_str,(p-msg_str));
        //提取password
        memcpy(wifi_msg_new.password,(p+1),(argc-1-(p-msg_str)));
        printf("write wifi ssid:%s,wifi psword:%s\n",wifi_msg_new.ssid,wifi_msg_new.password);

        //將WiFi msg寫入nv
        rc = (int)nvs_open("wifi_msg", NVS_READWRITE, &handle_wifi);
        if(rc == ESP_ERR_NVS_NOT_FOUND)
        {
            printf("write open nvs error\n");
       //     uart_write_bytes(UART_NUM_0, (const char *) "OPERROR", len);
            return;
        }
        printf("rc:%d\n",rc);
        rc = nvs_set_blob(handle_wifi, "wifimsg", &wifi_msg_new,sizeof(wifi_msg_new));
        if(rc == ESP_ERR_NVS_INVALID_HANDLE)
        {
            printf("write set nvs error,rc:%d\n",rc);
          //  uart_write_bytes(UART_NUM_0, (const char *) "SETERROR", len);
            return;
        }
        ESP_ERROR_CHECK( nvs_commit(handle_wifi));

        nvs_close(handle_wifi);
        printf("write nvs ok\n");

      //  uart_write_bytes(UART_NUM_0, (const char *) "OK", len);
    }
    else
    {
        //讀wifi ssid password
        printf("---read\n");
        rc = (int)nvs_open("wifi_msg", NVS_READWRITE, &handle_wifi);
        if(rc == ESP_ERR_NVS_NOT_FOUND)
        {
            printf("read open nvs error\n");
           // uart_write_bytes(UART_NUM_0, (const char *) "OPERROR", len);
            return;
        }

        len = sizeof(wifi_msg_new);
        rc = nvs_get_blob(handle_wifi, "wifimsg", (void *)&wifi_msg_new,(size_t *)&len);
        if(rc ==  ESP_ERR_NVS_INVALID_HANDLE)
        {
            printf("read get nvs error\n");
          //  uart_write_bytes(UART_NUM_0, (const char *) "GETERROR", len);
            return;
        }

        printf("read wifi ssid[len:%d]:%s,wifi psword[len:%d]:%s\n",strlen(wifi_msg_new.ssid),wifi_msg_new.ssid,strlen(wifi_msg_new.password),wifi_msg_new.password);

        
        nvs_close(handle_wifi);
        printf("read nvs ok\n");

      //  uart_write_bytes(UART_NUM_0, (const char *) "OK", len);

    }
}

這裏簡單介紹下nvs接口使用流程(詳情請看sdk 例程):

//打開
nvs_open
//寫nv
nvs_get_blob,nvs_set_str,nvs_set_i32等接口寫不同類型數據
//提交寫的數據
nvs_commit
//關閉
nvs_close

這裏at命令讀寫一個注意事項:
win下回車=rtos 下\r\n,佔有兩個字節,我們在處理接受的字符串時,需要去掉兩個字節,特麼對設置WiFi的用戶名和密碼來說,如果不去掉,會造成wifi的密碼錯誤,導致連不上wifi。

所以針對上一篇at命令的串口數據讀寫做如下修改:
在這裏插入圖片描述

2.編譯運行測試at接口

make app

燒錄,reset
寫測試:
在這裏插入圖片描述
讀測試:
在這裏插入圖片描述

3.完善開機讀取聯網信息

至此
我們只需要在設備開機從nvs中獲取ssid password去聯網即可,修改將ssid password固化在代碼中。
聯網開機在user_main.c中的wifi初始化
在這裏插入圖片描述
下面是wifi_msg_fun接口,其實就是at命令讀取nvs中的信息

void read_wifi_msg_fun(char * ssid,char * pswd)
{
    nvs_handle handle_wifi;
    int len = 0;
    int rc;
    wifi_msg_t wifi_msg_new;

    
    memset(&wifi_msg_new,0,sizeof(wifi_msg_new));

    //讀wifi ssid password
    printf("---read\n");
    rc = (int)nvs_open("wifi_msg", NVS_READWRITE, &handle_wifi);
    if(rc == ESP_ERR_NVS_NOT_FOUND)
    {
        printf("read open nvs error\n");
       // uart_write_bytes(UART_NUM_0, (const char *) "OPERROR", len);
        return;
    }
    
    len = sizeof(wifi_msg_new);
    rc = nvs_get_blob(handle_wifi, "wifimsg", (void *)&wifi_msg_new,(size_t *)&len);
    if(rc ==  ESP_ERR_NVS_INVALID_HANDLE)
    {
        printf("read get nvs error\n");
      //  uart_write_bytes(UART_NUM_0, (const char *) "GETERROR", len);
        return;
    }
    
    printf("read wifi ssid[len:%d]:%s,wifi psword[len:%d]:%s\n",strlen(wifi_msg_new.ssid),wifi_msg_new.ssid,strlen(wifi_msg_new.password),wifi_msg_new.password);

    memcpy(ssid,wifi_msg_new.ssid,strlen(wifi_msg_new.ssid));
    memcpy(pswd,wifi_msg_new.password,strlen(wifi_msg_new.password));
    
    nvs_close(handle_wifi);
    printf("read nvs ok\n");

}

4.編譯燒寫後測試

燒寫成功,reset重啓,寫聯網信息,在重啓,log註釋
在這裏插入圖片描述在這裏插入圖片描述
到此爲止
esp8266我們已經完成了以下內容,聯網,連wifi,led操作,key操作,at命令開發,sntp更新系統時間,對接阿里雲平臺,nvs(保存用戶數據),從sdk看,還有http協議相關,oled,ota升級,smart_config(配網)沒玩,進去先不做相關內容更新了,後面有時間在繼續玩這個開發板了,現有的功能我是基於esp8266_sdk_3.1.1開發,先將工程project(工程project的使用以前有過介紹不在敘述了)上傳吧,有需要的自行去下載。如果仔細看我的esp8266的10篇博客,掌握我已經完成的內容也沒有多大難度的。

下載鏈接://download.csdn.net/download/qq_38240926/12045130

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章