im trying to write some functions helping me to save WiFi configurations for some IoT projekt.
I havent got an ESP8266 here for testing today, so i just started coding.
To make things easier, i want to declare all Strings i want to read/write with a constant max. lenth.
I know this code is full of errors, but i hope you can give me some good advice
#include <EEPROM.h>
char wifi_ssid_private[32];
char wifi_password_private[32];
char clientName[10] = "newClient";
char ipAddr[11] = "172.24.1.1";//Pi Access Point IP-Adr.
//startAdr: offset (bytes), writeString: String to be written to EEPROM
void writeEEPROM(int startAdr, String writeString) {
EEPROM.begin(512); //Max bytes of eeprom to use
delay(3000);
Serial.println();
Serial.println("Startup");
//write to eeprom
int charLength=writeString.length();
Serial.println("writing eeprom:");
for (int i = 0; i < charLength; ++i)
{
EEPROM.write(startAdr + i, writeString[i]);
Serial.print("Wrote: ");
Serial.println(writeString[i]);
}
}
char* readEEPROM(int startAdr, int maxLength, char* dest) {
Serial.println("Reading EEPROM");
EEPROM.begin(512);
for (int i = 0; i < maxLength; ++i)
{
dest += char(EEPROM.read(startAdr + i));
if(dest[i]='\0') break;//break when end of sting is reached before maxLength
}
//esid.trim();
Serial.print("ready reading:");
Serial.println(dest);
return dest;
}
void setup() {
Serial.begin(9600);
delay(100);
strcat(wifi_ssid_private, "myWiFiSSID");
strcat(wifi_password_private, "myWiFiPW");
writeEEPROM(0,wifi_ssid_private);//32 byte max length
writeEEPROM(32,wifi_password_private);//32 byte max length
writeEEPROM(64,clientName);//10 byte max length
writeEEPROM(74,ipAddr);//11 byte max length
/*85 byte saved in total?*/
Serial.println("everything saved...");
//get SSID max 32byte
readEEPROM(0,32,wifi_ssid_private);
/*i dont know whats the better way, but the next line is not compiling*/
//get PW max 32byte
wifi_password_private[] = readEEPROM(32,32,wifi_password_private);
}
void loop() {
// put your main code here, to run repeatedly:
}
/*
examples/sources
http://forum.arduino.cc/index.php?topic=428836.0
https://gist.github.com/dogrocker/f998dde4dbac923c47c1
void setup() {
Serial.begin(115200);
EEPROM.begin(512);
delay(3000);
Serial.println();
Serial.println();
Serial.println("Startup");
//write to eeprom
String qsid="Global";
int charLength=qsid.length();
Serial.println("writing eeprom ssid:");
for (int i = 0; i < qsid.length(); ++i)
{
EEPROM.write(i, qsid[i]);
Serial.print("Wrote: ");
Serial.println(qsid[i]);
}
//read to eeprom
Serial.println("Reading EEPROM ssid");
String esid;
for (int i = 0; i < charLength; ++i)
{
esid += char(EEPROM.read(i));
}
//esid.trim();
Serial.println(esid.length());
Serial.print("SSID: ");
Serial.println(esid);
*/
Whats the best way to get the readed chars out of my readEEPROM() function back to my global char array variables?
Edit:
So my code now looks like this. Still had no chance to test it on an ESP but its compiling, yeay
Seems like i need EEPROM.commit(); to write my strings buffered in the RAM to the EEPROM.
Ive seen EEPROM.end(); too, can anyone tell me the difference?
Seems like there are differences between EEPROM writing of an regular arduino and the ESP8266.
Is the #include <EEPROM.h> the right one for the ESP?
#include <ESP8266WiFiScan.h>
#include <WiFiUdp.h>
#include <WiFiClientSecure.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WiFiGeneric.h>
#include <ESP8266WiFiType.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WiFiAP.h>
#include <WiFiServer.h>
#include <ESP8266WiFiSTA.h>
/*are there libs i can exclude? like the WiFiAP cause i do not use ESP as an AccessPoint?*/
#include <EEPROM.h>
char wifi_ssid_private[32];
char wifi_password_private[32];
char clientName[10] = "newClient";
char ipAddr[16] = "172.024.001.001";//Pi Access Point IP-Adr.
//startAdr: offset (bytes), writeString: String to be written to EEPROM
void writeEEPROM(int startAdr, String writeString) {
EEPROM.begin(512); //Max bytes of eeprom to use
yield();
yield();
Serial.println();
Serial.println("Startup");
//write to eeprom
int charLength=writeString.length();
Serial.println("writing eeprom:");
for (int i = 0; i < charLength; ++i)
{
EEPROM.write(startAdr + i, writeString[i]);
Serial.print("Wrote: ");
Serial.println(writeString[i]);
}
}
void readEEPROM(int startAdr, int maxLength, char* dest) {
Serial.println("Reading EEPROM");
EEPROM.begin(512);
for (int i = 0; i < maxLength; ++i)
{
dest += char(EEPROM.read(startAdr + i));
if(dest[i]='\0') break;//break when end of sting is reached before maxLength
}
//esid.trim();
Serial.print("ready reading:");
Serial.println(dest);
}
void setup() {
Serial.begin(9600);
yield();
yield();
strcat(wifi_ssid_private, "myWiFiSSID");
strcat(wifi_password_private, "myWiFiPW");
writeEEPROM(0,wifi_ssid_private);//32 byte max length
writeEEPROM(32,wifi_password_private);//32 byte max length
writeEEPROM(64,clientName);//10 byte max length
writeEEPROM(74,ipAddr);//17 byte max length
EEPROM.commit();
/*85 byte saved in total?*/
Serial.println("everything saved...");
yield();
//get SSID max 32byte
readEEPROM(0,32,wifi_ssid_private);
//get PW max 32byte
wifi_password_private = readEEPROM(32,32,wifi_password_private);
//get clientName max 10byte
wifi_password_private = readEEPROM(64,10,clientName);
//get ipAddr max 16byte
wifi_password_private = readEEPROM(74,16,ipAddr);
}
void loop() {
// put your main code here, to run repeatedly:
yield();
}
/*
examples/sources
http://forum.arduino.cc/index.php?topic=428836.0
https://gist.github.com/dogrocker/f998dde4dbac923c47c1
*/
I dont stop believing that here are some poeple who listen to my words and maybe can give a little advice.
So i found out that EEPROM.put/get suppose to work with objects.
Ive tried a little example but that didnt work.
back to my own code:
#include <EEPROM.h>
char wifi_ssid_private[32];
char wifi_password_private[32];
char clientName[10] = "newClient";
char ipAddr[16] = "172.024.001.001";//Pi Access Point IP-Adr.
//startAdr: offset (bytes), writeString: String to be written to EEPROM
void writeEEPROM(int startAdr, int laenge, char* writeString) {
EEPROM.begin(512); //Max bytes of eeprom to use
yield();
Serial.println();
//write to eeprom
Serial.println("writing eeprom:");
for (int i = 0; i < laenge; i++)
{
EEPROM.write(startAdr + i, writeString[i]);
Serial.print(writeString[i]);
}
EEPROM.commit();
Serial.println();
delay(10);
Serial.println(char(EEPROM.read(startAdr)));
EEPROM.end();
}
void readEEPROM(int startAdr, int maxLength, char* dest) {
Serial.println("Reading EEPROM");
EEPROM.begin(512);
delay(10);
for (int i = 0; i < maxLength; i++)
{
*dest += char(EEPROM.read(startAdr + i));
//if(dest[i]='\0') break;//break when end of sting is reached before maxLength
}
EEPROM.end();
//esid.trim();
Serial.print("ready reading:");
Serial.println(dest);
}
void setup() {
Serial.begin(9600);
delay(100);
strcat(wifi_ssid_private, "SSID1234");
strcat(wifi_password_private, "PW1234");
writeEEPROM(0,32,wifi_ssid_private);//32 byte max length
writeEEPROM(32,32, wifi_password_private);//32 byte max length
//writeEEPROM(64,10, clientName);//10 byte max length
//writeEEPROM(74,16, ipAddr);//16 byte max length
/*85 byte saved in total?*/
Serial.println("everything saved...");
readEEPROM(0,32,wifi_ssid_private);
readEEPROM(32,32,wifi_password_private);
//readEEPROM(64,10,clientName);
//readEEPROM(74,16,ipAddr);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("Loop");
delay(1000);
EEPROM.begin(512);
Serial.println(char(EEPROM.read(0)));
Serial.println(char(EEPROM.read(32)));
EEPROM.end();
}
but Serial Monitor says:
writing eeprom:
SSID1234
S
writing eeprom:
PW1234
P
everything saved...
Reading EEPROM
ready reading:PSID1234
Reading EEPROM
ready reading:�W1234
Loop
S
P
Loop
S
P
Those "S"/"P"s are just to show that saving chars in EEPROM seems to work but always the first char i read with my read function is wrong.
EDIT:
changing this line of read function and it works great even fpr the first char in ssid and password: dest[i] = char(EEPROM.read(startAdr + i));
so dest += fucks up the first char
Does anyone know the reason?
JimmyPesto:
i know my own code, thanks for that.
whats the type of "ssid" and "password" in YOUR example.
It's not my example, it's from the ESP8266 Arduino Core. If you would have opened it, you'd know that ssid and password are normal null terminated character arrays as well:
I thought you get that i was adressing you since no one else has posted anything.
The file youve linked was just those two functions no declaration of ssid and password. Okay you can find that in this github repo. more information on these eeprom functions
Funny that they used the same sice for ssid and password as me.
And yes, your idea is working great. Ive just tried that before you posted it.
Any idea what += does, so that the first char fails?
"dest" is a pointer to the character array. (The location of the first character of the array). "*dest" is the value that is stored at this location. It is the same as writing dest[0].
What your program was doing was just adding the read character to the first value of the string: it originally was the letter 'S', which is ASCII 83. Then it read the entire string, so adding the ASCII values of SSID1234: 83+83+83+73+68+49+50+51+52 = 592, you've only got one byte of data, so the most significant bits get cut off: 592 % 256 = 80 = ASCII 'P'.
All other characters were never changed by your read function, so they remained "SID1234".
That's because you were reusing "wifi_ssid_private" as "dest", so both of these variables are pointers to the same array, "SSID1234".
To change the other chars in the array, you have to index it using square brackets.
Yes, a String is an object (note the capital S), and has an append operator. A char array on the other hand, is just that, an array of chars. The addition operator just adds values together.
For everyone whos interested, heres my working code.
Note that i later get the ssid, pw etc via MQTT and my MQTT-Server already checked whether or not they are valid strings of the max length the arduino programm has allocated.
#include <EEPROM.h>
char wifi_ssid_private[32];
char wifi_password_private[32];
char clientName[10] = "newClient";
char ipAddr[16] = "172.024.001.001";//Pi Access Point IP-Adr.
//startAdr: offset (bytes), writeString: String to be written to EEPROM
void writeEEPROM(int startAdr, int laenge, char* writeString) {
EEPROM.begin(512); //Max bytes of eeprom to use
yield();
Serial.println();
Serial.print("writing EEPROM: ");
//write to eeprom
for (int i = 0; i < laenge; i++)
{
EEPROM.write(startAdr + i, writeString[i]);
Serial.print(writeString[i]);
}
EEPROM.commit();
EEPROM.end();
}
void readEEPROM(int startAdr, int maxLength, char* dest) {
EEPROM.begin(512);
delay(10);
for (int i = 0; i < maxLength; i++)
{
dest[i] = char(EEPROM.read(startAdr + i));
}
EEPROM.end();
Serial.print("ready reading EEPROM:");
Serial.println(dest);
}
void setup() {
Serial.begin(9600);
delay(100);
strcat(wifi_ssid_private, "SSID1234");
strcat(wifi_password_private, "PW1234");
writeEEPROM(0,32,wifi_ssid_private);//32 byte max length
writeEEPROM(32,32, wifi_password_private);//32 byte max length
writeEEPROM(64,10, clientName);//10 byte max length
writeEEPROM(74,16, ipAddr);//16 byte max length
/*85 byte saved in total?*/
Serial.println("everything saved...");
readEEPROM(0,32,wifi_ssid_private);
readEEPROM(32,32,wifi_password_private);
readEEPROM(64,10,clientName);
readEEPROM(74,16,ipAddr);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("Loop");
delay(1000);
}