这阵子心血来潮想搞一下esp8266的wifi,需要存储wifi密码,所以想使用一下esp8266的flash,一查,原来esp8266有eeprom,比stm32好太多了,而且不需要麻烦的读写保护操作,arduino的EEPROM.h库全帮你操作好了,简直不要太爽。
esp8266的EEPROM空间可达4096个,即EEPROM可操作的地址为0~4095。
一个地址空间为1Bety(0~255或者0xff),超过了就要用下一个空间进行存储了,类似于24c02这种EEPROM。
#include <EEPROM.h>
#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 <EEPROM.h>
#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 <ESP8266WiFi.h>
#include <EEPROM.h>
#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