Tuesday, October 18, 2011

Task 38 - using the I2C bus with an EEPROM 24LC64

(The post following this one goes into different device addresses)
The address given in the original code - below, more or less - has the 24LC64 connected as follows:

Pin A0 is LOW;
Pin A1 is LOW;
Pin A2 is LOW.

This requires the device address to be 0x50.

Later, we will see devices connected so that they are to be addressed as  0x51  &  0x52, merely by varying  the LOW/HIGH status of A0, A1, & A2.


This is how several devices can be connected to the same I2C bus - they are addressed differently.
/*
 * Project:      eeprom_fromWeb
 * Author:      hkhijhe - tidied by Jane-Maree Howard
 * Date:         01/10/2010
 * Platform:   Arduino 22
 * Purpose:    To demonstrate use of the I2C bus with an EEPROM 24LC64
 -             "You were issued with an eeprom 24LC64 IC.
 -              This is a TWI memory that you connect to SCL and SDA on the Arduino.
 -              Run the program from the blog.
 -              Show your code changes and the serial monitor output in your blog
". 
 * Operation:  Because this chip is I2C,
 -               it only uses Arduino analog pins 4 & 5 (SDA and SCL),
 -               and of course the power (5V) and GND.
 -             Connect as follows:
 -                Arduino pin 4 to EEPROM pin 5
 -                Arduino pin 5 to EEPROM pin 6
 -                Arduino 5V to EEPROM pin 8
 -                Arduino GND to EEPROM pin 1,2,3,4
 -             Be sure to leave pin 7 of the EEPROM open or tie it to GND,
 -               otherwise the EEPROM will be write protected.
 -             Include: Wire.h - the I2C library
 -             Declare: various i2c_eeprom_read.. i2c_eeprom_write.. procedures
 -             Setup(): Opens the Wire connection, the Serial connection,
 -                      writes a char-string to the EEPROM, & prints heading
 -                      NOTE: the char-string has length = 28
 -             Loop():  Reads from the EEPROM, & prints, one byte at a time, & repeats                 
 */

#include {Wire.h}               //I2C library-usual brackets warning
 
  void setup()
  {
    // a char-string of data to write to the EEPROM - 28 characters long!!
    char somedata[] = "this is data from the eeprom";

   /*
    char somedata[] = "this is Jane-Maree's eeprom data"; - 32 characters..
     .. & it bombs.  Gibberish - I've tried it!  See WARNING below..

   */
    Wire.begin();                 // Wire connection initialised
    Serial.begin(9600);       // Serial connection @ 9600 baud
    // now write the char-string to the EEPROM
    i2c_eeprom_write_page(0x50, 0, (byte *)somedata, sizeof(somedata));
    delay(10);                     //add a small delay..
    // ..& print a heading
    Serial.println("\nMemory written");
    Serial.println("\nNow read memory & print to Serial port");
  } //setup()

  void loop()
  {
    int addr=0;               // address parameter, starts @ 0
    // now access the first address (0) from the memory
    byte b = i2c_eeprom_read_byte(0x50, 0);
    // while there are non-zero bytes..
    while (b!=0)
    {
      Serial.print((char)b); //..print content to serial port..
      addr++;                      //..next address &..
      //..access next address from the memory.
      b = i2c_eeprom_read_byte(0x50, addr);
    }//while ()
    Serial.println(" ");     // new line..
    delay(2000);               // ..2 second delay, & start again!
  } //loop()
 

  void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data )
  {
    int rdata = data;
    Wire.beginTransmission(deviceaddress);
    Wire.send((int)(eeaddress >> 8));             // MSB
    Wire.send((int)(eeaddress & 0xFF));        // LSB
    Wire.send(rdata);
    Wire.endTransmission();
  } //i2c_eeprom_write_byte()

  /*
    WARNING: address is a page address, 6-bit end will wrap around
    also, data can be maximum of about 30 bytes,
    because the Wire library has a buffer of 32 bytes
  */
  void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length )
  {
    Wire.beginTransmission(deviceaddress);
    Wire.send((int)(eeaddresspage >> 8));       // MSB
    Wire.send((int)(eeaddresspage & 0xFF));  // LSB
    byte c;
    for ( c = 0; c < length; c++)
      Wire.send(data[c]);
    Wire.endTransmission();
  } //i2c_eeprom_write_page()

  byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress )
  {
    byte rdata = 0xFF;
   
    Wire.beginTransmission(deviceaddress);
    Wire.send((int)(eeaddress >> 8));             // MSB
    Wire.send((int)(eeaddress & 0xFF));        // LSB
    Wire.endTransmission();
   
    Wire.requestFrom(deviceaddress,1);
    if (Wire.available())
      rdata = Wire.receive();
    return rdata;
  } //i2c_eeprom_read_byte()

  // maybe let's not read more than 30 or 32 bytes at a time! See NOTE!
  void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length )
  {
    Wire.beginTransmission(deviceaddress);
    Wire.send((int)(eeaddress >> 8));          // MSB
    Wire.send((int)(eeaddress & 0xFF));     // LSB
    Wire.endTransmission();
   
    Wire.requestFrom(deviceaddress,length);
    int c = 0;
    for ( c = 0; c < length; c++ )
      if (Wire.available())
        buffer[c] = Wire.receive();          
  } //i2c_eeprom_read_buffer()



You can see the gibberish along the top, caused by a buffer over-run.

i think this was what happened earlier, when i was 'experimenting'.

When all else fails, 
   Read The Instructions.

Now i need to figure out how to get around that buffer problem - i've not yet understood how to add a C-header file (.h) & C-file (.cpp)..

1 comment:

  1. so far, so good - & a bonus!
    My EEPROM chip has risen from the dead!
    (hmm.. does that make it a vampire, or a werewolf, or.. what are those other things - zombies!)
    No it's not a zombie.. it's alive & well.

    ReplyDelete