24c04 writing issue

hi , while reading only 255 number is coming . no stored in the eeprom . using the 24c04 .

#include "Wire.h"
 

 
// EEPROM I2C Address
#define EEPROM_I2C_ADDRESS 0x50
 
// Analog pin for potentiometer
int analogPin = 0;
 
// Integer to hold potentiometer value
int val = 0;
 
// Byte to hold data read from EEPROM
int readVal = 0;
 
// Integer to hold number of addresses to fill
int maxaddress = 150;
 

 
 
// Function to write to EEPROOM
void writeEEPROM(int address, byte val, int i2c_address)
{
  // Begin transmission to I2C EEPROM
  Wire.beginTransmission(i2c_address);
 
  // Send memory address as two 8-bit bytes
  Wire.write((int)(address >> 8));   // MSB
  Wire.write((int)(address & 0xFF)); // LSB
 
  // Send data to be stored
  Wire.write(val);
 
  // End the transmission
  Wire.endTransmission();
 
  // Add 5ms delay for EEPROM
  delay(5);
}
 
// Function to read from EEPROM
byte readEEPROM(int address, int i2c_address)
{
  // Define byte for received data
  byte rcvData = 0xFF;
 
  // Begin transmission to I2C EEPROM
  Wire.beginTransmission(i2c_address);
 
  // Send memory address as two 8-bit bytes
  Wire.write((int)(address >> 8));   // MSB
  Wire.write((int)(address & 0xFF)); // LSB
 
  // End the transmission
  Wire.endTransmission();
 
  // Request one byte of data at current memory address
  Wire.requestFrom(i2c_address, 1);
 
  // Read the data and assign to variable
  rcvData =  Wire.read();
 
  // Return the data as function output
  return rcvData;
}
 
 
void setup()
{
  // Connect to I2C bus as master
  Wire.begin();
 
  // Setup Serial Monitor
  Serial.begin(9600);
 
 
 
  // Print to Serial Monitor
  Serial.println("Start Recording...");
 
  // Run until maximum address is reached
 
  for (int address = 0; address <= maxaddress; address++) {
 
    // Read pot and map to range of 0-180 for servo
    val = map(analogRead(analogPin), 0, 1023, 0, 180);
 
    // Write to the servo
    // Delay to allow servo to settle in position
   
    delay(15);
 
    // Record the position in the external EEPROM
    writeEEPROM(address, val, EEPROM_I2C_ADDRESS);
 
    // Print to Serial Monitor
    Serial.print("ADDR = ");
    Serial.print(address);
    Serial.print("\t");
    Serial.println(val);
 
  }
 
  // Print to Serial Monitor
  Serial.println("Recording Finished!");
 
  // Delay 5 Seconds
  delay(5000);
 
  // Print to Serial Monitor
  Serial.println("Begin Playback...");
 
  // Run until maximum address is reached
 
  for (int address = 0; address <= maxaddress; address++) {
 
    // Read value from EEPROM
    readVal = readEEPROM(address, EEPROM_I2C_ADDRESS);
 
 
    // Write to the servo
    // Delay to allow servo to settle in position
   
    delay(15);
 
    // Print to Serial Monitor
    Serial.print("ADDR = ");
    Serial.print(address);
    Serial.print("\t");
    Serial.println(readVal);
 
  }
 
  // Print to Serial Monitor
  Serial.println("Playback Finished!");
 
}
 
void loop()
{
 
  // Nothing in loop
 
}

0xFF = 255 is what you normally "read" from any i2c device that is not connected. What does the i2cScanner sketch tell you? Why do you not record the result of Wire.endTransission() and check that it was successful?

hi, connection is ok . pullup resistor value is 4.7k . scanning is ok
11:09:28.745 -> I2C Scanner
11:09:28.745 -> Scanning...
11:09:28.745 -> I2C device found at address 0x50 !
11:09:28.791 -> I2C device found at address 0x51 !
11:09:28.838 -> done

current chip used : 24c04

Hi,
Welcome to the forum.

Can you please post a circuit diagram, not a Fritzy?

Thanks.. Tom.. :grinning: :+1: :coffee: :australia:

You are addressing the eeprom with the scheme used for larger eeproms with 2 byte address.

However, I don't think you will use the typical address scheme for the smaller eeproms which split the storage address into the control byte and an address byte.

The two addresses found by the scanner indicate to me that the eeprom is divided into to two memory blocks of 256x8 bits.
That is, the device is organized as two 2K eeproms, and you access within each block with a 1 byte address.

Try to modify your read and write functions. For example

// Function to write to EEPROOM
void writeEEPROM(int address, byte val, int i2c_address)
{
  // Begin transmission to I2C EEPROM
  Wire.beginTransmission(i2c_address); //0x50 or 0x51
 
  // Send memory address as two 8-bit bytes
  //Wire.write((int)(address >> 8));   // MSB
  //Wire.write((int)(address & 0xFF)); // LSB
  
  //Send memory address as one 8-bit byte
   Wire.write(address); //byte address 0>255
 
  // Send data to be stored
  Wire.write(val);
 
  // End the transmission
  Wire.endTransmission();
 
  // Add 5ms delay for EEPROM
  delay(5);
}
1 Like

Hi,
Have you googled
24c04 arduino

Can you try the example from this site please?

If you disconnect the EEprom from the UNO and run the I2C scanner what is detected?
Are you using a module with the EEprom on it, or just the IC?

Thanks.. Tom... :grinning: :+1: :coffee: :australia:

Hi TomGeorge , Wow... After modification code of

//Send memory address as one 8-bit byte
Wire.write(address); //byte address 0>255

Now Perfectly Reading and Writing
........................................................................................................

currently i have mapped 12bit into 8 bit and stored

i need store the data as 16 bit and 32 bit .

I have seen Forum discussion & google search they are mostly about the internal EEPROM .

Can you suggest some 16 and 32 bit storage sample code in external i2c EEPROM .

The same principles hold. You will need to store the multiple individual bytes of your data in separate storage locations and reassemble when read.

One issue with the external eeproms is the small page size and the fact that you can not block write across page boundaries. For simplicity, I suggest that you stick with writing the individual bytes.

If you need faster writing, you can use a library which manages the page boundaries for you. I use Jack Christensen's extEEPROM.h which is available through the library manager.

thanks.... https://create.arduino.cc/projecthub/electropeak/sd-card-module-with-arduino-how-to-read-write-data-37f390 the following link was useful for when i am sd card ... Similar kind of link or Similar kind of code will be useful incase of with Big Memory Size 24c512 EEPROM with 16 bit A/D convertor value input .. Since i am new

Can you suggest some 16 and 32 bit storage sample code in external i2c EEPROM .

For the 16 bit values, Arduino provides some functions to break the integer into two bytes and recombine them

highByte()
lowByte()
word cast

For the 32 bit data you can right shift the data to isolate individual bytes

byte4 = value>>24; 
byet3 = value>>16;
byte2 = value>>8;
byte1 = value

The recombination of the four bytes back to a long can be a little tricky because of some casting issues with the left shifts back and I use a method which avoids the individual byte casting.

Here's some example code

#include <Wire.h>
#define eepromAddress 0x50 //i2c Address of EEPROM
byte storageAddress; //limit to 255 

void setup() {
  Serial.begin(115200);
  int intValue = 9999; 
  Serial.print("16 bit value to store in eeprom = ");
  Serial.println(intValue);
  
  storageAddress = 0;//manage storageAddress
  writeEEPROM(storageAddress, lowByte(intValue), eepromAddress);
  writeEEPROM(storageAddress + 1, highByte(intValue), eepromAddress);
  Serial.print("16 bit value retreived from eeprom = ");
  byte l = readEEPROM(storageAddress, eepromAddress);
  byte h = readEEPROM(storageAddress + 1, eepromAddress);
  int combineInt = word(h,l);
  Serial.println(combineInt);
  
  long longValue = 12345678;
  Serial.print("32 bit value to store in eeprom = ");
  Serial.println(longValue);
  byte byteVal[4];//4 bytes to hold separated values
  byteVal[3] = longValue >> 24;
  byteVal[2] = longValue >> 16;
  byteVal[1] = longValue >> 8;
  byteVal[0] = longValue;

  storageAddress = 16; //manage storage address
  
  for (byte i = 0; i < 4; i++)
  {
    writeEEPROM(storageAddress, byteVal[i], eepromAddress);
    storageAddress++;
  }

  //read data back and recombine
  storageAddress = 16;
  for (byte i = 0; i < 4; i++) 
  {
    byteVal[i] = readEEPROM(storageAddress, eepromAddress);
    storageAddress++;
  }
  
  long recombinedValue = 0;
  recombinedValue = byteVal[3];
  recombinedValue = recombinedValue << 8 | byteVal[2];
  recombinedValue = recombinedValue << 8 | byteVal[1];
  recombinedValue = recombinedValue << 8 | byteVal[0];

  Serial.print("32 bit value retreived from eeprom = ");
  Serial.println(recombinedValue);

}

void loop() {}

// Function to write to EEPROOM
void writeEEPROM(byte address, byte val, int i2c_Address)
{
  Wire.beginTransmission(i2c_Address);
  //Wire.write(address >> 8); not used for small eeprom
  Wire.write(address);
  Wire.write(val);
  Wire.endTransmission();
  delay(5);
}

// Function to read from EEPROM
byte readEEPROM(byte address, int i2c_Address)
{
  byte rcvData = 0xFF;

  Wire.beginTransmission(i2c_Address);
  //Wire.write(address >> 8);//not used for small eeprom
  Wire.write(address);
  Wire.endTransmission();
  Wire.requestFrom(i2c_Address, 1);
  rcvData =  Wire.read();
  return rcvData;
}

Sorry ... i am disturbing you again .. i have try to modify something with help of google but nothing worked out .it's not storing the data

11:59:44.720 -> 16 bit value16 bit value to store in eeprom = 9999
11:59:44.720 -> 16 bit value retreived from eeprom = -1
11:59:44.720 -> 32 bit value to store in eeprom = 12345678
11:59:44.765 -> 32 bit value retreived from eeprom = -1

But now

11:59:44.720 -> 16 bit value16 bit value to store in eeprom = 9999
11:59:44.720 -> 16 bit value retreived from eeprom = -1
11:59:44.720 -> 32 bit value to store in eeprom = 12345678
11:59:44.765 -> 32 bit value retreived from eeprom = -1

Run the i2c scanner program again to confirm that all is correct with the connection to the eeprom.

Please post code which successfully stores and reads back one byte to storage location 0 but fails to store and read back a two byte integer stored at address 1 and 2 and a fails to store and read back a four byte long stored at address 3,4,5,6.

for the 8 bit storage & read it's working perfect .

for the 16 bit & 32 bit it's not working . Any How for my project 24C04 memory space is not enough & i can't buy 24c512 due to deliver issue here . I do have the w25q32(winfond) new and memory space also high but i don't have much idea on SPI Memory .

requesting you as beginning level give me simple idea with example code - A0 & A1 data's must stored with w25q32 and how read the same data .

if possible please add one float data type Read & Write like A0 data 1023/2.5 =

I have no experience with that part or SPI flash so I can not help you in that respect.

for the 8 bit storage & read it's working perfect .
for the 16 bit & 32 bit it's not working

I can help you with i2c external eeprom issues. Regardless of the size of eeprom you use, you will face the same issues of breaking data into bytes for storing and retreiving.

You will have to post your code. The code I previously tested was with a 24C32 which is part of an rtc module. It uses a two byte address scheme, but the code I posted for you was designed with the one byte for your smaller eeprom.

the same code used and tested but output as follows.

11:59:44.720 -> 16 bit value16 bit value to store in eeprom = 9999
11:59:44.720 -> 16 bit value retreived from eeprom = -1
11:59:44.720 -> 32 bit value to store in eeprom = 12345678
11:59:44.765 -> 32 bit value retreived from eeprom = -1

Have you confirmed with the i2c scanner program that all is correct with the eeprom connection?

Where is the code which successfully stores and retreives one byte?

I can see a return value of -1 when the ground between the eeprom and the Arduino is not connected.

Please check that connection.

#include "Wire.h"

// EEPROM I2C Address
#define EEPROM_I2C_ADDRESS 0x50

// Analog pin for potentiometer
int analogPin = 0;

// Integer to hold potentiometer value
int val = 0;

// Byte to hold data read from EEPROM
int readVal = 0;

// Integer to hold number of addresses to fill
int maxaddress = 150;

// Function to write to EEPROOM
void writeEEPROM(byte address, byte val, int i2c_address)
{
// Begin transmission to I2C EEPROM
Wire.beginTransmission(i2c_address);

// Send memory address as two 8-bit bytes
//Wire.write((int)(address >> 8)); // MSB
//Wire.write((int)(address & 0xFF)); // LSB
Wire.write(address);

// Send data to be stored
Wire.write(val);

// End the transmission
Wire.endTransmission();

// Add 5ms delay for EEPROM
delay(5);
}

// Function to read from EEPROM
byte readEEPROM(byte address, int i2c_address)
{
// Define byte for received data
byte rcvData = 0xFF;

// Begin transmission to I2C EEPROM
Wire.beginTransmission(i2c_address);

// Send memory address as two 8-bit bytes
//Wire.write((int)(address >> 8)); // MSB
//Wire.write((int)(address & 0xFF)); // LSB
Wire.write(address);

// End the transmission
Wire.endTransmission();

// Request one byte of data at current memory address
Wire.requestFrom(i2c_address, 1);

// Read the data and assign to variable
rcvData = Wire.read();

// Return the data as function output
return rcvData;
}

void setup()
{
// Connect to I2C bus as master
Wire.begin();

// Setup Serial Monitor
Serial.begin(9600);

// Print to Serial Monitor
Serial.println("Start Recording...");

// Run until maximum address is reached

for (int address = 0; address <= maxaddress; address++) {

// Read pot and map to range of 0-180 for servo
val = map(analogRead(analogPin), 0, 1023, 0, 180);

// Write to the servo
// Delay to allow servo to settle in position

delay(15);

// Record the position in the external EEPROM
writeEEPROM(address, val, EEPROM_I2C_ADDRESS);

// Print to Serial Monitor
Serial.print("ADDR = ");
Serial.print(address);
Serial.print("\t");
Serial.println(val);

}

// Print to Serial Monitor
Serial.println("Recording Finished!");

// Delay 5 Seconds
delay(5000);

// Print to Serial Monitor
Serial.println("Begin Playback...");

// Run until maximum address is reached

for (int address = 0; address <= maxaddress; address++) {

// Read value from EEPROM
readVal = readEEPROM(address, EEPROM_I2C_ADDRESS);


// Write to the servo
// Delay to allow servo to settle in position
// Convert value to integer for servo

delay(15);

// Print to Serial Monitor
Serial.print("ADDR = ");
Serial.print(address);
Serial.print("\t");
Serial.println(readVal);

}

// Print to Serial Monitor
Serial.println("Playback Finished!");

}

void loop()
{}

// Nothing in loop
8 bit successful
22:25:51.691 -> Start Recording...
22:25:51.691 -> ADDR = 0 55
22:25:51.782 -> ADDR = 1 44
22:25:51.782 -> ADDR = 2 39
22:25:51.782 -> ADDR = 3 38
22:25:54.843 -> Recording Finished!
22:25:59.836 -> Begin Playback...
22:25:59.836 -> ADDR = 0 55
22:25:59.885 -> ADDR = 1 44
22:25:59.885 -> ADDR = 2 39
22:25:59.885 -> ADDR = 3 38

GND Pin is ok and connected stage