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