Makuna / Rtc

Arduino Library for RTCs, Ds1302, Ds1307, Ds3231, Ds3232, Ds3234 and Pcf8563/BM8563 with deep support. Please refer to the Wiki for more details. Please use the Github Discussions to ask questions as the GitHub Issues feature is used for bug tracking.
GNU Lesser General Public License v3.0
369 stars 127 forks source link

EepromAT24C32.h I can only store max. 30 bytes at once, not the limit of 32 bytes as I expect #104

Closed rudydevolder closed 4 years ago

rudydevolder commented 4 years ago

I used the example in the source code: "DS3231_memory.ino" :

My environment is:

But first of all I needed to change some lines to make it compile without errors for Ubunu, Platformio and the STM:

The 3 changes I made are:

  1. Changing the line with:

    include towards

    include in Ubuntu the capital 'T'in the filename makes a difference.

  2. Putting a Predeclared definition "void printDateTime(const RtcDateTime& dt); " in front because in Platformio I get a compile error. This is a common problem I got when importing code from Arduino in platformio, but simple to solve.

  3. In the function: void printDateTime(const RtcDateTime& dt) I got a compile error for "snprintf_P"doesn't exist for the STM: so I changed: { snprintf_P(datestring, countof(datestring), PSTR("%02u/%02u/%04u %02u:%02u:%02u"), dt.Month(), dt.Day(), dt.Year(), dt.Hour(), dt.Minute(), dt.Second() );

    towards:

    sprintf(datestring, //countof(datestring), PSTR("%02u/%02u/%04u %02u:%02u:%02u"), dt.Month(), dt.Day(), dt.Year(), dt.Hour(), dt.Minute(), dt.Second() );

    Serial1.print(datestring); }

    Than I experimented with different data, I know the max. bytes in 1 buffer to write is 32 bytes because of the limitation in page-size.

With: const char data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123"; //which is 30 bytes long ( excluding the trailing '\0' ) everything works fine.

But when I changed data to: const char data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ01234"; //which is 31 bytes long I got problems when reading the data: I got in the serial terminal: lenght of data stored: 31 address didn't match 12 something did'nt match, count = 12, gotten 0 data read (0) = ""

Makuna commented 4 years ago

The terminal output doesn't match the sketch, did you make other changes? The first line in your serial terminal capture isn't present in the sketch.

After each request for data, check the error, as it seems the same data is being returned for both the address and size of the string (12).

uint8_t address = RtcEeprom.GetMemory(0);
if (RtcEeprom.LastError() != 0) {
            // we have a communications error
            // see https://www.arduino.cc/en/Reference/WireEndTransmission for 
            // what the number means
            Serial.print("EEPROM communications error = ");
            Serial.println(RtcEeprom.LastError());
}
uint8_t count = RtcEeprom.GetMemory(1);
if (RtcEeprom.LastError() != 0) {
            // we have a communications error
            // see https://www.arduino.cc/en/Reference/WireEndTransmission for 
            // what the number means
            Serial.print("EEPROM communications error = ");
            Serial.println(RtcEeprom.LastError());
}
rudydevolder commented 4 years ago

Hi Makuna, I just found something remarquable, I've put some extra code in between just to read the RTC after every EEPROM read. Strangely it reported the time 01/01/2000 00:00:00, while before the write to EEPROM it reported a correct time. After further testing I found out that when I write more than 30 bytes the I2c communication isn't working any more. I've put some extra scanI2C() code to scan the i2c bus and report me the occupied addresses. But just after writing more than 30 bytes, scanI2C reports "no devices". When I change the code to write less than 31 bytes in EEPROM everything works fine again. Maybe a bug in the wire library for the STM?

Makuna commented 4 years ago

Well, I feel a little dumb, as the problem is commented in the example, its just not clear.

https://www.arduino.cc/en/reference/wire

Any single transaction on Wire is limited to 32 bytes. Since all read/write transactions to the eeprom require two bytes for the address, this only leaves 30 bytes of data that can be written.

Reading can support the full 32 bytes due to using two transactions, one to set the address (2 bytes) and one to read (up to 32 bytes). This is called "sequential read". There is no "sequential write" so writing has a limit.

Makuna commented 4 years ago

https://github.com/Makuna/Rtc/pull/105

rudydevolder commented 4 years ago

Hi Makuna, Thx very much for the good explanation. I'm not sure I can add in this comments and close the case because Github is also still a bit of mystery to me.

Makuna commented 4 years ago

I updated the wiki, and https://github.com/Makuna/Rtc/pull/106 adds the comments to the methods.