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