2

following sketch will run totally fine and as expected :

#include <Wire.h>
#include "SparkFun_External_EEPROM.h"
ExternalEEPROM ExtEEPROM;
char username[33] = "";
char password[65] = "";
void setup()
{
 Serial.begin(115200);
 delay(1000);
 Wire.begin();
 #define EEPROM_ADDRESS 0b1011000 // 0x58
 ExtEEPROM.setMemorySize(256000/8); // 256kbit = 32kbyte
 ExtEEPROM.setPageSize(64); // 64 byte page size.
 ExtEEPROM.enablePollForWriteComplete();
 ExtEEPROM.setPageWriteTime(10); // max. ms for AT24C128
 if (ExtEEPROM.begin(EEPROM_ADDRESS, Wire) == false) 
 {
 Serial.println("No memory detected. Freezing.");
 while (1);
 }
 Serial.println("Memory detected!");
 String uuu = "myusername";
 String ppp = "mypassword";
 uuu.toCharArray(username, sizeof(username) - 1);
 ppp.toCharArray(password, sizeof(password) - 1);
 Serial.print("password=");Serial.println(password);
 ExtEEPROM.put(0, username);
 //delay(100);
 ExtEEPROM.put(0 + sizeof(username), "greatnewpassword");
}
 
void loop() {
 char xxx[33] = "";
 ExtEEPROM.get(0, xxx);
 Serial.print("xxx=");Serial.println(xxx); // prints the username
 char yyy[33] = "";
 ExtEEPROM.get(0 + sizeof(username), yyy);
 Serial.print("yyy=");Serial.println(yyy); // prints the password
 delay(1000);
}

However, if I replace ExtEEPROM.put(0 + sizeof(username), "greatnewpassword"); to ExtEEPROM.put(0 + sizeof(username), password);, then yyy prints empty in the serial monitor. Why?

asked Mar 2, 2022 at 2:45
5
  • 2
    Try doing a serial print of password to see if the toCharArray call did what it was supposed to do. Commented Mar 2, 2022 at 4:53
  • 2
    OT: Don't write any_boolean == false, use !any_boolean. If you think think, you should make sure that anyone understands, then I'd recommend (any_boolean == false) == true. :-D Commented Mar 2, 2022 at 7:02
  • 1
    OT: sizeof is an operator, not a function, so use sizeof variable. However, its operand can be a type, and then it needs parentheses for syntactIcal reasons. This leads to this ubiquitous bad habit to write it as a function. Commented Mar 2, 2022 at 7:09
  • 1
    Are you sure you are putting the actual array password, rather than a pointer produced by its decay (like char *foo = password; ExtEEPROM.put(..., foo);)? Commented Mar 2, 2022 at 9:11
  • 256kbit is not 256000 bits. It's 256 * 1024 bits, or 262144. Commented Mar 2, 2022 at 10:11

3 Answers 3

2

As Majenko already mentions:

.get() and .put() should only be used for atomic, self-contained, types like int or float, not pointers like char *.

Not sure what atomic means here, but you may .put and .get any data type, especially a struct.

struct EPROMData {
 char username[33];
 char password[65];
}; 
EPROMData data {"myusername","mypassword"};
void setup() {
 ...
 ExtEEPROM.put(0,data);
}
void loop() {
 EPROMData d;
 ExtEEPROM.get(0,d);
 Serial.print("user="); Serial.println(d.username); 
 ...
}

Sure, if the data type is a pointer or a String object (containing a pointer only), you won't be happy with .put / .get

answered Mar 2, 2022 at 15:46
1
  • 1
    By atomic I mean "it is a thing complete in itself". A struct is complete. An int is complete. A char * is not complete since it doesn't contain the data, it is only a pointer to it. So it's not "atomic". Same goes for a String object, since the object doesn't contain the string data, only a pointer to allocated memory that contains the string data. Commented Mar 3, 2022 at 0:08
1

.get and .put are being passed a char pointer, not the contents of a char array. Thus you're not writing the content of the string but the address in memory where it's being stored.

With a string literal that is fixed and never changes, so what you write and what you read are fine. With a variable though the address could be anything, and storing the address of some RAM where a string is stored is pointless.

.get() and .put() should only be used for atomic, self-contained, types like int or float, not pointers like char *.

Instead you need to be using the .read(address, buffer, size) and .write(address, buffer, size) functions to read and write the contents of your char arrays.

answered Mar 2, 2022 at 10:53
1
  • In the OP's code, get() and put() are being passed actual arrays, not pointers. As the arrays are being passed by reference, they do not decay to pointers. Commented Mar 3, 2022 at 8:27
1

problem seems to be the lib I am using. I think it can not handle data overlapping page size.

if I replace from this

char username[33] = "";
char password[65] = "";

to this:

char username[16] = "";
char password[16] = "";

everything works fine as it saves and reads from the EEPROM via I2C.

Juraj
18.3k4 gold badges31 silver badges49 bronze badges
answered Mar 2, 2022 at 21:21
1
  • the conversation has been moved to chat. Commented Mar 4, 2022 at 5:42

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.