NVRAM of DS3231 real time clock

I'm successufully setting and reading the time of the DS3231 RTC module using IC2_RTC.H of Manjunath CV.

However I can't find any examples of storing and reading data from the non volatile ram.

As far as I know the module has 32KB of NVRAM.

Looking at the library source I see:

void NVRAM::write(uint8_t address, uint8_t data)
{
	address = (address % length) + 0x08;
	Wire.beginTransmission(DS1307_ADDR);
	Wire.write(address);
	Wire.write(data);
	Wire.endTransmission();
}

Which looks like writing unsigned byte values at unsigned byte addresses.

But this code:

  RTC_RAM.begin () ;

  for (int i = 0 ; i < RTC_RAM.length ; i++) {
      RTC_RAM.write(i,i*2) ;
  }

  for (int i = 0 ; i < RTC_RAM.length ; i++) {
      Serial.print("BYTE : "); 
      Serial.print(i) ;
      Serial.print(" : ") ;
      Serial.print(RTC_RAM.read(i)) ;
      Serial.println () ;
  }

Gives me these results:

BYTE : 0 : 0
BYTE : 1 : 2
BYTE : 2 : 4
BYTE : 3 : 6
BYTE : 4 : 8
BYTE : 5 : 10
BYTE : 6 : 12
BYTE : 7 : 12
BYTE : 8 : 16
BYTE : 9 : 21
BYTE : 10 : 128
BYTE : 11 : 0
BYTE : 12 : 0
BYTE : 13 : 0
BYTE : 14 : 0
BYTE : 15 : 0

Correct up to byte 8, but then rather gah gah.

What have I missed? TIA !

PS: What is RTC_RAM.length for?

What module?

Some of them have the AT24C32 4K x 8-bit EEPROM non-volatile memory.

1 Like

Datasheet of DS3231 only seems to list 18 registers, no NVRAM ?

1 Like

If it's like this, then the NVRAM address is 0x57

1 Like

Yes, if it's the ZS-042 module shown in jim-p's picture, it has the AT24C32 4K EEPROM chip on it, at address 0x57. The AT24Cxx.h library would be the one to use. See the examples in that library.

1 Like

It is the "AZ-Delivery DS3231 Real Time Clock Module" and the datasheet says it has 32KB of non volatile memory.

So they mean kilo bits (not kilo bytes)?

Thanks for that, I've installed the library and will have a look at the examples from here

https://github.com/cvmanjoo/AT24Cxx/blob/master/examples/i2c_eeprom_write/i2c_eeprom_write.ino

I think it may be that second smaller chip next to the RTC chip...

Probably, but they might hope that you will be confused and think bytes instead.

ATTENTION:
There was another poster on the forum with the same board from AZ. It turned out that the EEPROM was a fake and did not work

Or maybe broken? Seems a lot of trouble to go to to make a fake. It would cost more. Maybe they use low quality components...

Not at all, and they are much cheaper to make than to put a real, working IC in the case.

The market is literally flooded with fakes, recycled and reject chips, especially if you buy from Asian sellers on Amazon, eBay, Alibaba and the like.

I've had a look at the examples, and the parameters in the library are not named exactly well or explicitly... This line:

AT24Cxx eep(i2c_address, 32);

presumably means 32 kilo bits?

I'd have named

uint32_t eeprom_size ;

as

uint32_t eeprom_size_in_kbits ;

for more clarity. And the same of the second parameter of the constructor.

(If indeed I've interpreted the sources correctly....!)

Arg. I'll let you know....

See this example article, from Analog, a chip manufacturer: Counterfeit ICs—the Serious Problem that Only We Can Make Go Away | Analog Devices

And this on on fake ATmega328p chips (it is nearly impossible to buy a real one, these days):

1 Like

Almosy certainly, EEPROMs,FRAMs etc are usually specified in K bits.

Hmmm, is this code correct to write then read 16 bytes to and from the EEPROM?

/*
 * EEPROM Write test
 */

#include <AT24Cxx.h>
#define i2c_address 0x57

/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/
AT24Cxx eep(i2c_address, 32);

void setup() {
  
  Serial.begin(9600); // initialize serial and wait for port to open:
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

}

void loop() {

  for (int i = 0 ; i < 16 ; ++i) {
      eep.write(i, i*2);
  }

  for (int i = 0 ; i < 16 ; ++i) {
    int iVal = eep.read(i);
    Serial.print("at ");
    Serial.print(i);
    Serial.print(" read ");
    Serial.println(iVal);  
  }

  delay(5000);
}

Because the results are not encouraging...

at 0 read 30
at 1 read 30
at 2 read 30
at 3 read 30
at 4 read 30
at 5 read 30
at 6 read 30
at 7 read 30
at 8 read 30
at 9 read 30
at 10 read 30
at 11 read 30
at 12 read 30
at 13 read 30
at 14 read 30
at 15 read 30

Is there an error in my code. The manual from AZ_Delivery says 0x57 as well.

I didn't even imagine that problem existed, thanks for the link!

With any new device library, start by carefully reading the library documentation and verifying that the library examples work as expected.

It has been a long time since I've used one of those EEProms, but there are timing restrictions on the write operation. If those are not built into the library, they have to be built into your code.

So, I would not expect this to work, without first checking:

  for (int i = 0 ; i < 16 ; ++i) {
      eep.write(i, i*2);
  }

The data size is uint8_t, you are using an int