【esp8266】使用esp8266内部EEPROM存储,掉电不丢失

这阵子心血来潮想搞一下esp8266的wifi,需要存储wifi密码,所以想使用一下esp8266的flash,一查,原来esp8266有eeprom,比stm32好太多了,而且不需要麻烦的读写保护操作,arduino的EEPROM.h库全帮你操作好了,简直不要太爽。

esp8266的EEPROM空间可达4096个,即EEPROM可操作的地址为0~4095。
一个地址空间为1Bety(0~255或者0xff),超过了就要用下一个空间进行存储了,类似于24c02这种EEPROM。


#include 
#define EEPROM_WiFi_Addr  2     //地址,EEPROM范围:0~4095
#define	EEPROM_Size		  1024  //开辟1024个位空间
int data;
 
 void setup(){
  EEPROM.begin(EEPROM_Size);             //开启EEPROM  
  Serial.begin(9600);

  //读取存储的数据
  Serial.println("");
  data=EEPROM.read(EEPROM_WiFi_Addr);    //读取EEPROM_WiFi_Addr地址的值
  Serial.printf("last_data:%d",data);

  //更新数据
  data = data + 1;
  Serial.printf("  now:%d",data);
  EEPROM.write(EEPROM_WiFi_Addr, data);  //新数据 最大存储一个Bety(0-255)的值,如果超过这个值,需要下一个空间
  EEPROM.commit();                       //提交存储 结束存储
}

void loop(){

}

使用EEPROM保存WiFi密码:

#include  

#define EEPROM_WIFI_Name_Addr   10     //WIFI名字的地址
#define EEPROM_WIFI_Key_Addr    40     //WIFI密码的地址
#define EEPROM_Name_Size_Addr   0     //WIFI名字的长度地址
#define EEPROM_Key_Size_Addr    1     //WIFI密码的长度地址

//串口
const int baudRate = 9600;          // 串口波特率
String  inputString = "";           // 存储接收到的数据
boolean stringComplete  = false;    // 新数据标志位



String WIFI_Name  = "adan1";      //WIFI名字
String WIFI_Key   = "88888888";     //密码

void setup() 
{
  EEPROM.begin(1024);                    //开启EEPROM,开辟1024个位空间  
  Serial.begin(baudRate); 
  inputString.reserve(200);
  
  if(EEPROM.read(EEPROM_Key_Size_Addr)!=0xff)            //如果WIFI密码长度有改变,则读取密码
  {
    WIFI_Key  = Read_String(EEPROM_Key_Size_Addr, EEPROM_WIFI_Key_Addr);    //读取WIFI密码,
  }
  Serial.println("Size_Addr:" +  String(EEPROM.read(EEPROM_Key_Size_Addr))  );
  Serial.printf("WIFI_KEY:%s \r\n",WIFI_Key);
}

void loop() {
  if (stringComplete) {
    Serial.print("收到数据: ");
    Serial.println(inputString);    //因为有换行符,所以会比你输入的多一个数据,也就是你输入八个数据,实际会加一个'\n'
    if(inputString.length()>8)
    {
      WIFI_Key = inputString;
      Write_String(EEPROM_Key_Size_Addr,EEPROM_WIFI_Key_Addr,WIFI_Key);
    }
    Serial.print("key:");
    Serial.print(WIFI_Key);
    Serial.print("  length:");
    Serial.println(inputString.length()-1);

    inputString = "";
    stringComplete = false;
  }
}




//length写入记录字符串长度的地址,addr是字符串的地址,str为要保存的字符串
void Write_String(int len_addr,int addr,String str){
//  EEPROM.write(len_addr, str.length());//写入str字符串的长度
  EEPROM.write(len_addr, str.length()-1);//写入str字符串的长度
  //把str所有数据逐个保存在EEPROM
  for (int i = 0; i < str.length(); i++){
    EEPROM.write(addr + i, str[i]);
  }
  EEPROM.commit();
}

//length位是字符串长度,addr是起始位(字符串首地址)
String Read_String(int len_addr, int addr){ 
  String data = "";
  char length = EEPROM.read(len_addr);    //读取记录在EEPROM中的数据长度
  //从EEPROM中逐个取出每一位的值,并链接
  for (int i = 0; i < length; i++){
    data += char(EEPROM.read(addr + i));
  }
  return data;
}

// 串口接收中断
void serialEvent() {
  while (Serial.available()) 
  {
    char inChar  = (char)Serial.read();
    inputString += inChar;
    
    if (inChar == '\n') 
    {
      stringComplete = true;
    }
  }
}

加入ESP8266 STA模式记录WiFi密码连接例程:

#include 
#include  

#define EEPROM_WIFI_Name_Addr   10     //WIFI名字的地址
#define EEPROM_WIFI_Key_Addr    40     //WIFI密码的地址
#define EEPROM_Name_Size_Addr   0     //WIFI名字的长度地址
#define EEPROM_Key_Size_Addr    1     //WIFI密码的长度地址

//串口
const int baudRate = 9600;          // 串口波特率
String  inputString = "";           // 存储接收到的数据
boolean stringComplete  = false;    // 新数据标志位



String WIFI_Name  = "adan1";      //WIFI名字
String WIFI_Key   = "88888888";   //密码
bool autoConnect = true;          //设置自动wifi连接所需变量

void Data_Dispose();

void setup() 
{
  //初始化
  EEPROM.begin(1024);                    //开启EEPROM,开辟1024个位空间  
  Serial.begin(baudRate); 
  inputString.reserve(200);
  
  //获取EEPROM的数据
  if(EEPROM.read(EEPROM_Key_Size_Addr)!=0xff)            //如果WIFI密码长度有改变,则读取密码
  {
    WIFI_Key  = Read_String(EEPROM_Key_Size_Addr, EEPROM_WIFI_Key_Addr);    //读取WIFI密码,
  }
  Serial.print("Size_Addr:" +  String(EEPROM.read(EEPROM_Key_Size_Addr))  );
  Serial.printf("  WIFI_KEY:%s \r\n",WIFI_Key);
 
  //连接WiFi
  WiFi.setAutoConnect(autoConnect);   //启用自动连接模式
  WiFi.begin(WIFI_Name , WIFI_Key);   //设置WiFi名和密码
//  WIFI_Connect();
//  if (WiFi.status() == WL_CONNECTED)
//  {
//    Serial.print("WIFI_Name: "  + String(WIFI_Name));
//    Serial.print("  WIFI_Key: "   + String(WIFI_Key)); 
//    Serial.print("  无线IP地址为: ");
//    Serial.println(WiFi.localIP());
//  }

}

int Now_Time=0,Last_time=0;
int Now_Time1=0,Last_time1=0;
void loop() 
{
  //每0.5s检查一次WiFi连接
  Now_Time  = millis();
  Now_Time1 = millis();
  if(Now_Time-Last_time>=500)
  {
    Last_time=Now_Time;
    WIFI_Connect(); 
  }
  //如果连接上了则运行WiFi相关的程序
  if(Now_Time1  - Last_time1>=5000)
  {
    Last_time1  = Now_Time1;
    if (WiFi.status() == WL_CONNECTED)
    {
      Serial.print("WIFI_Name: "    + String(WIFI_Name));
      Serial.print("  WIFI_Key: "    + String(WIFI_Key)); 
      Serial.print("  WIFI_RSSI:  "   + String(WiFi.RSSI()));  //WIFI信号强度
      Serial.print("  无线IP地址为: ");
      Serial.println(WiFi.localIP());
    }
  }
  
  Data_Dispose();                     //处理新输入的WiFi密码


}




//length写入记录字符串长度的地址,addr是字符串的地址,str为要保存的字符串
void Write_String(int len_addr,int addr,String str){
//  EEPROM.write(len_addr, str.length());//写入str字符串的长度
  EEPROM.write(len_addr, str.length()-1);//写入str字符串的长度
  //把str所有数据逐个保存在EEPROM
  for (int i = 0; i < str.length(); i++){
    EEPROM.write(addr + i, str[i]);
  }
  EEPROM.commit();
}

//length位是字符串长度,addr是起始位(字符串首地址)
String Read_String(int len_addr, int addr){ 
  String data = "";
  char length = EEPROM.read(len_addr);    //读取记录在EEPROM中的数据长度
  //从EEPROM中逐个取出每一位的值,并链接
  for (int i = 0; i < length; i++){
    data += char(EEPROM.read(addr + i));
  }
  return data;
}


void Data_Dispose()
{
  if (stringComplete) {
    Serial.print("收到数据: ");
    Serial.println(inputString);    //因为有换行符,所以会比你输入的多一个数据,也就是你输入八个数据,实际会加一个'\n'
    if(inputString.length()>8)
    {
      WIFI_Key = inputString;
      Write_String(EEPROM_Key_Size_Addr,EEPROM_WIFI_Key_Addr,WIFI_Key);
    }
    Serial.print("key:");
    Serial.print(WIFI_Key);
    Serial.print("  length:");
    Serial.println(inputString.length()-1);

    inputString = "";
    stringComplete = false;
  }
}

//检查/等待WiFi连接
void WIFI_Connect()
{ 
  if (WiFi.status() != WL_CONNECTED)  //判定网络状态 这里用while会出BUG进不去串口中断  搞了好久还是不知道问题所在
  {
    Data_Dispose();                   //处理新输入的WiFi密码
    Serial.print("."); 
  }
 // Serial.println("");
}


// 串口接收中断
void serialEvent() {
  while (Serial.available()) 
  {
    char inChar  = (char)Serial.read();
    inputString += inChar; 
    
    if (inChar == '\n') 
    {
      stringComplete = true;
    }
  }
}

期间遇到一个bug,改了好几次还是没解决,即==void WIFI_Connect()==中的if不能换成while一直等待连接,否则串口中断无法接收到数据,具体问题未知。

参考文章(推荐看这篇–>)(基于Ardunio)ESP8266之使用EEPROM

你可能感兴趣的:(单片机,嵌入式硬件,esp8266,物联网,c++)