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?

5
  • 2
    Try doing a serial print of password to see if the toCharArray call did what it was supposed to do.
    – Nick Gammon
    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 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. 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);)? Mar 2, 2022 at 9:11
  • 256kbit is not 256000 bits. It's 256 * 1024 bits, or 262144.
    – Majenko
    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

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.
    – Majenko
    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.

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. 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.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.