Arduino interface with 24LC08

Dear all

I am having arduino UNO and i have connected hardaware where i could able use DS1307 and 24LC08 eeprom device.i would like to know

For seven bit addressing what should be slave address for 24LC08 module.

i am bit confuse when i read datashet there are 2 addressing modes

7 bit or 10 bit addressing mode. How should we put value of slave address in this case.
I know arduino support library function . for sake of knowledge how it can be calculated.

i have got below code from herehttp://www.bristolwatch.com/arduino/arduino_ds1307.htm

if i wanted to write differnt timing into eeprom location how should i write or append the page .

/*

http://www.bristolwatch.com/arduino/arduino_ds1307.htm
Arduino with a DS1307 Real Time Clock
Lewis Loflin lewis@bvu.net
This code comes with no warranty.

*/


#include <Wire.h> // specify use of Wire.h library.

#define ONE_HZ_SW 2 // one Hz square wave from Ds1307
#define blinkPin 13
#define SW0 4
#define SW1 5
#define SW2 6

void setup()

{
  Wire.begin(); // join i2c bus (address optional for master)
  Serial.begin(9600);
  digitalWrite(blinkPin, 0);

  pinMode(ONE_HZ_SW, INPUT);
  pinMode(SW0, INPUT);  // for this use a slide switch
  pinMode(SW1, INPUT);  // N.O. push button switch
  pinMode(SW2, INPUT);  // N.O. push button switch

  digitalWrite(ONE_HZ_SW, HIGH);
  digitalWrite(SW0, HIGH); // pull-ups on
  digitalWrite(SW1, HIGH);
  digitalWrite(SW2, HIGH);
}

void loop()
{
  // wait or HIGH
  while (!digitalRead(ONE_HZ_SW)) {
  }
  Wire.beginTransmission(0x68);
  Wire.write(0);  // location pointer
  Wire.endTransmission();
  Wire.requestFrom(0x68, 7); // send 7 bytes
  byte secs = Wire.read();
  byte mins = Wire.read();
  byte hrs = Wire.read();
  byte day = Wire.read();
  byte date = Wire.read();
  byte month = Wire.read();
  byte year = Wire.read();

  // hours, minutes, seconds

  Serial.print("The time is ");
  if (hrs < 10) Serial.print("0");
  Serial.print(hrs, HEX);
  Serial.print(":");
  if (mins < 10) Serial.print("0");
  Serial.print(mins, HEX);
  Serial.print(":");
  if (secs < 10) Serial.print("0");
  Serial.println(secs, HEX);

  // use MM-DD-YYYY

  Serial.print("The date is ");
  if (month < 10) Serial.print("0");
  Serial.print(month, HEX);
  Serial.print("-");
  if (date < 10) Serial.print("0");
  Serial.print(date, HEX);
  Serial.print("-");
  Serial.print("20");
  if (year < 10) Serial.print("0");
  Serial.println(year, HEX);
  Serial.println();

  if (!(digitalRead(SW0))) set_time(); // hold the switch to set time
  while (digitalRead(ONE_HZ_SW)) {
  } // wait or LOW
  toggle(blinkPin);
}

// toggle the state on a pin
void toggle(int pinNum)
{
  int pinState = digitalRead(pinNum);
  pinState = !pinState;
  digitalWrite(pinNum, pinState);
}

void set_time()   {
  byte minutes = 0;
  byte hours = 0;

  while (!digitalRead(SW0))
    // set time switch must be released to exit
  {
    while (!digitalRead(SW1)) // set minutes
    {
      minutes++;
      if ((minutes & 0x0f) > 9) minutes = minutes + 6;
      if (minutes > 0x59) minutes = 0;
      Serial.print("Minutes = ");
      if (minutes >= 9) Serial.print("0");
      Serial.println(minutes, HEX);

      delay(750);
    }

    while (!digitalRead(SW2)) // set hours
    {
      hours++;
      if ((hours & 0x0f) > 9) hours =  hours + 6;
      if (hours > 0x23) hours = 0;
      Serial.print("Hours = ");
      if (hours <= 9) Serial.print("0");
      Serial.println(hours, HEX);
      delay(750);
    }

    Wire.beginTransmission(0x68); // activate DS1307
    Wire.write(0); // where to begin
    Wire.write(0x00);          //seconds
    Wire.write(minutes);          //minutes
    Wire.write(0x80 | hours);    //hours (24hr time)
    Wire.write(0x06);  // Day 01-07
    Wire.write(0x16);  // Date 0-31
    Wire.write(0x11);  // month 0-12
    Wire.write(0x13);  // Year 00-99
    Wire.write(0x10); // Control 0x10 produces a 1 HZ square wave on pin 7.
    Wire.endTransmission();
  }
}

7 bit or 10 bit addressing mode. How should we put value of slave address in this case.

The Arduino supports only 7bit addresses. So use addresses 0x50 to 0x53 for this chip.

As per data sheet I consider device ID config

1010 000 0.A0 for write operaion
1010 000 1 A for write operation

How it will be 50 and 53

If I take compliment 0101 1111 5f

50 =0101 0000
If I wanted to give start address how shall give

In rtc device and all they say address 0x02 means second
0x03 is minute. And so on

How it will be eeprom i2c device.

How to give address. Weather slave address remain same like i2c device or it will change.

The wire library handles the read/write bit for you. Run an I2C sketch and see for yourself, or try the numbers that were suggested and come back here if they're wrong.

I know it will handle by library.my question how we will get this value.
There is some way u might passing argument . How u calculate it

Are you asking out of curiosity only? As in, you just want to understand I2C addressing better?

i wanted to know technically. how it will be 0X53 or 0X50

as per datasheet 0XA0 or 0XA1 .

The wire library handles this for you. The library knows if you are performing a read or a write by the function you call in the library.

Writing to the I2C device at address 0x50 results in the value 0xA0 appearing on the I2C bus. The library takes the device address and shifts it left 1 bit so 0x50 becomes 0xA0. It then OR's in the read/write bit into the LSB. For a write it's a '0', so you get 0xA0.

Reading from the I2C device at address 0x50 results in the value 0xA1 appearing on the I2C bus. The library takes the device address and shifts it left 1 bit so 0x50 becomes 0xA0 - as before. It then OR's in the read/write bit into the LSB. For a read it's a '1', so you get 0xA1.

Then what about 53.
Which function uses for read operation
As per above thing 50 means read operation
How about write operation

Ok, as a point of reference, here is the datasheet I'm looking at. It's an 8kbit EEPROM, so 1kbytes.

From page 1 of the datasheet:

The device is organized as four blocks of 256 x 8-bit memory ...

From page 7 of the datasheet:

The control byte consists of a four-bit control code. For the 24XX08, this is set as ‘1010’ binary for read and write operations. The next three bits of the control byte are the block-select bits (B2, B1, B0). B2 is a “don’t care” for the 24XX08. They are used by the master device to select which of the four 256 word-blocks of memory are to be accessed. These bits are in effect the three Most Significant bits of the word address

I read that as the device has 4 addresses on the I2C bus that it will respond to: Addresses 0x50, 0x51, 0x52 and 0x53 - to select one of the four 256-byte blocks of memory. (It may also respond to addresses 0x54, 0x55, 0x56 & 0x57 but you would need to verify that yourself). These are the addresses you use regardless of whether you are reading or writing.

If you wanted to write the number 6 to address 24 (address 24 being in the first page of the device) then you would do something like this:

Wire.beginTransmission( 0x50 );
Wire.write(0x18);
Wire.write(0x06);
Wire.endTransmission();

If you then wanted to read that number back, you would do something like this:

// tell the device the address to read from
Wire.beginTransmission( 0x50 );
Wire.write(0x18);
Wire.endTransmission();

// read the value
Wire.requestFrom( 0x50, 1 );
data = Wire.read();

If you wanted to write the number 10 to location 770 of the device, then you would know from the datasheet that location 770 is the third byte on page 3 (page 0 = bytes 0..255, page 1 = bytes 256..511, page 2 = bytes 512..767 & page 3 = bytes 768..1023). You would do something like this:

Wire.beginTransmission( 0x53 );
Wire.write(0x02);
Wire.write(0x0A);
Wire.endTransmission();

If you are calling Wire.beginTransmission(), Wire.write() and Wire.endTransmission(), then you are essentially telling the device something, whether it's data to write to memory or setting the device up for a subsequent read operation.

If you are calling Wire.requestFrom() then you are asking the device for something.

As I said before, you don't have to worry about the R/W bit as the library sorts that out for you depending on the function(s) you call.

Dear All.

I have 2 i2c device connected to Arduino Uno board

I2c1 device External EEPROm 24LC08
I2c2 device is External RTC device PCF85613 I have tested device individually & they are working well. I have attached serial monitor for reference.

When device is both independently connected they work properly. as soon as SDA /SCL line are shorted as shown in figure where i used pull up resistor mentioned in datasheet Timing of RTC stop working.

Few people recommend to use one side pull up resistor SDA/SCL line. means currently PCF8563 uses 4.75k and EEPROM uses 10K .

i have tried common pull up resistor SDA/SCL once 4.75K &10k .In both cases timing wont increment if SDA and SCL connected independently with Arduino SDA/SCL line it start working.

What i need to do Here.similar thing i tried with PIC18 controller where RTC start updating nut getting jump from few no in second. if i connected SDA/SCL line independent sec paramter get update in 1 Sec

If my second device slave device 0X51 RTC slave address is overlapping memory address of EEPROM ??

#include "Wire.h"
#define PCF8563address 0x51
int position_pointer = 0x3f0;


byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
String days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

byte bcdToDec(byte value)
{
  return ((value / 16) * 10 + value % 16);
}

byte decToBcd(byte value) {
  return (value / 10 * 16 + value % 10);
}

void setPCF8563()
// this sets the time and date to the PCF8563
{
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x02);
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

void readPCF8563()
// this gets the time and date from the PCF8563
{
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x02);
  Wire.endTransmission();
  Wire.requestFrom(PCF8563address, 7);
  second     = bcdToDec(Wire.read() & B01111111); // remove VL error bit
  minute     = bcdToDec(Wire.read() & B01111111); // remove unwanted bits from MSB
  hour       = bcdToDec(Wire.read() & B00111111);
  dayOfMonth = bcdToDec(Wire.read() & B00111111);
  dayOfWeek  = bcdToDec(Wire.read() & B00000111);
  month      = bcdToDec(Wire.read() & B00011111);  // remove century bit, 1999 is over
  year       = bcdToDec(Wire.read());
}

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  // change the following to set your initial time
  second = 0;
  minute = 24;
  hour = 19;
  dayOfWeek = 2;
  dayOfMonth = 25;
  month = 8;
  year = 20;
  // comment out the next line and upload again to set and keep the time from resetting every reset
  setPCF8563();

Wire.beginTransmission(0x50); 
Wire.write(position_pointer); 
Wire.write("Arduino");
  Wire.endTransmission();
  
}

void loop()
{
  readPCF8563();
  Serial.print(days[dayOfWeek]);
  Serial.print(" ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/20");
  Serial.print(year, DEC);
  Serial.print(" - ");
  Serial.print(hour, DEC);
  Serial.print(":");
  if (minute < 10)
  {
    Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");
  if (second < 10)
  {
    Serial.print("0");
  }
  Serial.println(second, DEC);

Wire.beginTransmission(0x50); 
Wire.write(position_pointer); 
Wire.endTransmission();
Wire.requestFrom(0x50, 7);
 while (Wire.available()) 
 {
    byte c = Wire.read(); // receive a byte as character
    Serial.println(c); // print the character
  }
  
Serial.println("................................................");
  
  delay(1000);
}

I read that as the device has 4 addresses on the I2C bus that it will respond to: Addresses 0x50, 0x51, 0x52 and 0x53 - to select one of the four 256-byte blocks of memory. (It may also respond to addresses 0x54, 0x55, 0x56 & 0x57 but you would need to verify that yourself). These are the addresses you use regardless of whether you are reading or writing

In which page it mentioned. i could not able to get can u send me datasheet with page no??

https://www.microchip.com/wwwproducts/en/24LC08B

The device is organized
as four blocks of 256 x 8-bit memory with a two-wire
serial interface.

I am going to use 64 program 643=192 Start time address ( each address contain hour,min,sec)
64
3=192 Stop time address ( each address contain hour,min,sec)

Total i need 384 memory location.

As u said if i Slave address with 0X50 can access 0X00 to 0XFF
Slave address with 0X53 can access 0X00 to 0XFF

All the bits I quoted came from the datasheet for the 24LC08. See the link on the first line of my previous reply.

As far as I can tell, the PCF8563 sits at address 0x51 on the I2C bus. This address is also used by the 24LC08 for its second block of 256 bytes of EEPROM memory.

Having these 2 devices on the I2C bus at the same time will result in a conflict. When you address the RTC, both the RTC and the EEPROM will try and respond at the same time.

You have several options

  • Change the RTC for one that uses a different I2C address
  • Change the EEPROM for one that uses a different I2C address
  • Use a software I2C solution for one of the devices
  • Use an I2C multiplexer chip

There's probably other options as well.

ok thanks for information . if i use https://www.mouser.in/Semiconductors/Clock-Timer-ICs/Real-Time-Clock/_/N-4k3bh?P=1z0z7pt&Keyword=MCP7940&FS=True

MCP7940 RTC device weather This will sort out my problem.??
Example code

Slave address used by RTC is 0X6F

Is there any software available to check EEPROM external write. As you said it takes 255 memory location in 1 page . when i changed line of this code

Wire.requestFrom(0x50, 255);
I could not able to print all 255 memory location.
I wanted to try arbitrary write few parameters into External eeprom location and print same thing.

In PIC microcontroller , For internal EEprom we can check what we writing. In this case for Arduino where we writing into external software how to check??

Wire.requestFrom(0x50, 7);
 while (Wire.available())
 {
    byte c = Wire.read(); // receive a byte as character
    Serial.println(c); // print the character
  }

Weather this code is write. If i wanted to add next page i would define EEprom_Address as 0X51

#include <Wire.h>     // for I2C
 
#define eeprom_address 0x50    // device address 
byte d=0;
 
void setup()
{
  Serial.begin(9600); // Initialize the serial
  Wire.begin();
 
  //write data out
  Serial.println("Writing data.");
  for (int i=0; i<254; i++)
  {
    writeData(i,i);
  }
  Serial.println("Complete");
  //read data back
  Serial.println("Reading data.");
  for (int i=0; i<254; i++)
  {
    Serial.print(i);
    Serial.print(" : ");
    d=readData(i);
    Serial.println(d, DEC);
  }
  Serial.println("Complete");
 
}
 
// writes a byte of data in memory location eaddress
void writeData(unsigned int eaddress, byte data) 
{
  Wire.beginTransmission(eeprom_address);
  // set the pointer position
  Wire.write((int)(eaddress >> 8));
  Wire.write((int)(eaddress & 0xFF));
  Wire.write(data);
  Wire.endTransmission();
  delay(10);
}
 
// reads a byte of data from memory location eaddress
byte readData(unsigned int eaddress) 
{
  byte result;
  Wire.beginTransmission(eeprom_address);
  // set the pointer position
  Wire.write((int)(eaddress >> 8));
  Wire.write((int)(eaddress & 0xFF));
  Wire.endTransmission();
  Wire.requestFrom(eeprom_address,1); // get the byte of data
  result = Wire.read();
  return result;
}
 
void loop()
{
}

If you wanted to write to the next page, then the address would be 0x51.

As a possible alternative to buying another RTC chip, there are several cheap I2C RTC + EEPROM modules you could choose from. They have EEPROMs that have higher capacity (4K) that occupy a single i2c address. Your whole module would be accessible using 2 I2C addresses.

The code written #14 thread is ok. Let me know any software available to check EEPROM has wrote properly or not.

I would like to check all memory location first and read the written data, Data might be 1 toFF has memory location.

Weather we can Do separate lines for i2c bus .

Where I2c bus one uses EEPROM 24lC08 device
where another bus uses RTC NXP PCF85163 Device

can we able to communicate above device in this case where Slave address having conflicts

because EEPROM uses 0X50,0X51,0X52,0X53

where RTC uses device ID 0X51