I have an ESP32 controller and am using AT24C1024 for communication. In my code, I am trying to access an external EEPROM at positions writing data from 0 to 10000 position data is = '1'. However, when I read data from position '1', I sometimes get junk values, such as 0, 255, or old written values. I have already tried changing the clock speed with Wire.setClock(100000)
, and I have attempted multiple writes to that location, but these modifications did not resolve the issue.
#include <Wire.h>
#define EEPROM_ADDR 0x50
#define SDA_PIN 21
#define SCL_PIN 22
#define DATA_LIMIT 10000
#define VALUE 1
void setup() {
Serial.begin(115200);
// Wire.begin(SDA_PIN, SCL_PIN);
Wire.begin();
for (uint16_t i = 0; i < DATA_LIMIT; i++) {
writeEEPROM(i, VALUE);
}
for (uint16_t i = 0; i < DATA_LIMIT; i++) {
uint8_t value = readEEPROM(i);
Serial.print(i);
Serial.print(" -> ");
Serial.println(value);
delay(30);
}
Serial.println("End");
}
void loop() {
}
void writeEEPROM(uint16_t memAddress, uint8_t data) {
Wire.beginTransmission(EEPROM_ADDR);
Wire.write((int)(memAddress >> 8));
Wire.write((int)(memAddress & 0xFF));
Wire.write(data);
uint8_t result = Wire.endTransmission();
if (result != 0) {
Serial.print("'W'- F : ");
}
delay(10);
}
uint8_t readEEPROM(uint16_t memAddress) {
Wire.beginTransmission(EEPROM_ADDR);
Wire.write((int)(memAddress >> 8)); // MSB of memory address
Wire.write((int)(memAddress & 0xFF)); // LSB of memory address
Wire.endTransmission();
Wire.requestFrom(EEPROM_ADDR, 1);
if (Wire.available()) {
return Wire.read();
}
return 0;
}
1 Answer 1
Wire.beginTransmission(EEPROM_ADDR);
Although this code might work when you are addressing the first page of the memory, however if you read the datasheet carefully under the section of Device Addressing and Figure 7 Device Addressing.
| 1 | 0 | 1 | 0 | 0 | A1 | Pg | R/W |
MSB LSB
The I2C addressing includes the memory page address bit and the status of A1 pin. So assuming A1 is 0 with internal pulldown or hardware unconnected, the correct addressing should be
Wire.beginTransmission((uint8_t)(EPROM_ADDR | (uint8_t) (dataAddress >> 16));
The Wire library itself will be responsible to convert the 7-bit I2C addressing to 8-bit I2C addressing and the R/W bit.
BTW, although code like Wire.write((int)(memAddress >> 8));
because the compiler might take care of it. But since Wire.write()
take an argument of uint8_t
as the parameter, so the casting should be (uint8_t) (memAddress >> 8)
instead of (int) (memAddress >> 8)
.
-
1Since the range of
memAddress
is [0, 9999], the bits above 2^13 are all zero. So this cannot be the reason for the problem.the busybee– the busybee2024年09月25日 10:03:32 +00:00Commented Sep 25, 2024 at 10:03 -
@thebusybee, datasheet (page 3) say memory is "internally organized as 512 pages of 256 bytes each".hcheung– hcheung2024年09月25日 10:16:57 +00:00Commented Sep 25, 2024 at 10:16
-
Wire.beginTransmission((uint8_t)(EPROM_ADDR | (uint8_t) (dataAddress >> 16));
and(uint8_t) (memAddress >> 8)
. I changed this configuration, this configuration is correct, but now also 0 to 10000 position write the data is '1' comming junk character (0, 255 and old data) ,approximately 9500 data only correct, another data has junk characterGopal– Gopal2024年09月25日 11:51:55 +00:00Commented Sep 25, 2024 at 11:51 -
Did you make the change to the
readEEPROM(uint16_t memAddress)
accordingly and theWire.requestFrom(EEPROM_ADDR, 1);
?hcheung– hcheung2024年09月25日 12:02:46 +00:00Commented Sep 25, 2024 at 12:02 -
1"512 pages of 256 bytes" Yes, and 10000 bytes need 40 pages. So the page number calculated from
memAddress
will never change the most significant bitP0
, which is always 0.the busybee– the busybee2024年09月25日 16:25:01 +00:00Commented Sep 25, 2024 at 16:25