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

发布了73 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_38240926/article/details/103645119