Write Read Sensor Data to External EEPROM with Arduino

Arduino, External EEPROM,LM35 circuit diagram

In this Arduino with EEPROM programming tutorial we will show how to read/write sensor data into and from external EEPROM using I2C protocol. The sensor data is acquired using the Arduino analog pin and the final data type is usually of float type. This float type data sensor data is saved into EEPROM and read back again to show EEPROM write and EEPROM read operation of float data type. So here we show how to read write sensor float data into external EEPROM. For writing and reading string text data type see the tutorial read write to external EEPROM with Arduino tutorials. For sensor we will use the LM35 temperature sensor and for the external EEPROM we will use the microchip 24LC256 external EEPROM IC.

Arduino Wire or I2C library

To use the I2C serial communication with Arduino there is a standard library called Wire.h. This needs to be imported when working with Arduino.

#include <Wire.h>

 If the Arduino is to made master then we declare it as I2C master device using the following statement in the setup() function.

Wire.begin()

If the Arduino is to made a slave then we write the following statement in the setup() function.

Wire.begin(SLAVE_ADDRESS);

where we define the SLAVE_ADDRESS as follows:

#define SLAVE_ADDRESS 0x08

 Master Communication

The master can send information to slave device, request information from slave device.

To start sending message from the master we need to begin the transmission, write the data and then end the transmission. This creates I2C message with address and data. The following statement begins the transmission.

Wire.beginTransmission(SLAVE_ADDRESS);

The next step is to queue data for transmission. This is done using the following command.

Wire.write()

This function takes parameters which can be a byte, a string(number of bytes), an array in which case second parameter is the length of the bytes, 

Wire.write(value); // append a byte
Wire.write(string); // append a string
Wire.write(data, length); // append an array with a specified number of bytes

Finally Wire.write() can also return the amount of bytes appended to the message using the statement like the following.

number =Wire.write(string); // store the number of bytes appended in a variable

 The transmission from master ends using either of the following statement.

Wire.endTransmission(); // send the message

The above statement can have optional bus release parameter which can be TRUE and FALSE. If TRUE then a stop message is sent which frees the I2C bus. If FALSE is specified then a restart message is sent, the I2C bus is not released. 

A stop message is sent using the following statement.

Wire.endTransmission(stop); // send the message and close the connection

The response to the Wire.endTransmission() is a status byte which can be the followings:

The master device can also request information from the slave device. This is done using the following statement:

Wire.requestFrom()

It can take upto 3 parameters. The first parameter is the address of the slave device, the second parameter is the data size in number of bytes and the third which is optional is whether to release the I2C bus.

Wire.requestFrom(address, quantity);
Wire.requestFrom(address, quantity, stop);

After sending the information request, the master can then wait and read the response from the slave. The master can store the information from the slave in a variable as illustrated below.

data = Wire.read(); // store the information in a variable

This will read single byte from the input buffer. For multiple bytes the buffer is checked for any bytes in the buffer which is done using the following statement.

number = Wire.available();

This when executed returns the number of bytes remaining in the buffer. Using the following statement we can continuously check whether there is any data in the buffer and save it in variable and print it.

while(Wire.available()) // Repeat as long as there is data waiting
{
char c = Wire.read(); // Read in one byte
Serial.print(c); // Print the byte
}

External EEPROM with Arduino Circuit Diagram

The following shows the circuit diagram of interfacing external EEPROM with Arduino, the LM35 temperature sensor, the two push buttons and the LCD.

Arduino, External EEPROM,LM35 circuit diagram

EEPROM Read Write Circuit operation

To illustrate the Arduino read write operation of sensor data on external EEPROM we will use LM35 temperature sensor and I2C serial 24LC256 external EEPROM. The LM35 sensor is connected to analog pin A0 of Arduino. The 24LC256 external EEPROM is connected A4(SDA) and A5(SCL) pins of Arduino. Two push button switches are used for read and write operations which are connected to pin 8 and 9 respectively. When the write push button at pin 9 is pressed then the currently read temperature float data is written to the EEPROM and when read push button at pin 8 is pressed then the last stored float temperature data is retrieved and display on serial monitor. Also LCD is used to display the temperature read from the LM35 sensor. The LCD is connected to digital port D of Arduino.

Arduino EEPROM Video

The following video shows how the above described write and read sensor data to and from external EEPROM with Arduino.

 

External EEPROM Float Senor Data Read/Write Arduino Program

The Arduino program code to read and write to external 24LC256 external serial EEPROM using I2C protocol is below.


#include <Wire.h>
#include <LiquidCrystal.h>


LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // setup the LCD interface pins


const int writeBTN = 9;
const int readBTN = 8;

const int debounceDelay = 50; // 50 ms delay to wait until stable read

char tempStore[16];

const byte EEPROM_ADDR = 0x50; // I2C address for 24LC128 EEPROM
char MEM[16];


void setup() {
	Serial.begin(9600);
	lcd.begin(16,2); // initialize the LCD
	Wire.begin();

	pinMode(writeBTN, INPUT_PULLUP);
	pinMode(readBTN, INPUT_PULLUP);
	
	lcd.setCursor(0,0);
	lcd.print("Temperature:");
}

void loop() {

	float Tc = analogRead(A0);
        Tc = (Tc/10)*4.9;

	dtostrf(Tc, 3, 2, tempStore);
        strcat(tempStore, "C");
    
	lcd.setCursor(0,1);
	lcd.print(tempStore);	
	

	if(!debounce(writeBTN)){
		Serial.println();
		Serial.println("Writing to Ext.EEPROM...");

		for(unsigned int i=0; i < sizeof(tempStore); i++){
			writeEEPROM(i, tempStore[i]);
		}
		Serial.println("Write Complete");
	}

	if(!debounce(readBTN)){
		Serial.println();
		Serial.println("Reading Ext.EEPROM...");
		for (unsigned int j = 0; j < sizeof(MEM); j++){
			MEM[j] = readEEPROM(j);
		}
		Serial.println("Read Complete");
		Serial.println("EEPROM Content:");
		Serial.println(MEM);
	}	 
}


void writeEEPROM(int address, byte data){
	Wire.beginTransmission(EEPROM_ADDR);
	Wire.write((int)highByte(address));
	Wire.write((int)lowByte(address));
	Wire.write(data);
	Wire.endTransmission();
	delay(5); // wait to complete the write cycle
}


byte readEEPROM(unsigned int address){
	byte data;
	Wire.beginTransmission(EEPROM_ADDR);
	Wire.write((int)highByte(address));
	Wire.write((int)lowByte(address));
	Wire.endTransmission();
	Wire.requestFrom(EEPROM_ADDR,(byte)1);
	while(Wire.available() == 0);  // wait for data
	data = Wire.read();
	return data;
}

boolean debounce(int pin){
  boolean state;
  boolean previousState;
  previousState = digitalRead(pin); // store switch state

  for(int counter=0; counter < debounceDelay; counter++){
  delay(1); // wait for 1 ms
  state = digitalRead(pin); // read the pin
    if( state != previousState){
    counter = 0; // reset the counter if the state changes
    previousState = state; // save the current state
    }
  }
  
  return state; // now return the stable state
}

In the above external EEPROM program code we have included the lcd library and the wire library. The lcd library is for the LCD and the wire library is required for implementing I2C communication between Arduino and the EEPROM IC(Integrated Circuit). The code line LiquidCrystal lcd() tells the compiler how to configure the connecting wires between Arduino and LCD. The next lines creates alias name writeBTN and readBTN  for the write and read pins 9 and 8 respectively. We have used Arduino debounce code with debounceDelay of 50ms to read push button presses to avoid any false readings due to contact bounce. A char array called tempStore[16] is created to store the sensor value in string format. The next lines of code are for EEPROM. First we have setup constant variable name EPPROM_ADDR with value of 0x50 because all the EEPROM address lines A0,A1 and A2 are grounded. The variable MEM[16] is created to hold the string data retrieved from the external 24LC256 EEPROM memory.

In the setup() function, we initialize the serial communication, the lcd communication and the I2C serial communication. The push button are made input pins with internal pullup resistor. Then for the printing the current read temperature data we print out string Temperature on the first line of the LCD.

In the loop()  function we read in the LM35 temperature sensor data from the analog pin A0. The simple LM35 temperature sensor Arduino tutorial explains how to read temperature and display on LCD. The temperature read is saved as float value and then converted and saved in the tempStore[] array as string using the dtostrf() function. Then using the strcat() we add "C" to the end of the string value saved in tempStore[] array. This saved float value as string is then displayed on the LCD on the second line. After this we monitor the push button press using the Arduino debounce code. When the write push button is pressed we write the current temperature value saved in the tempStore[] array into the external EEPROM and if read push button is pressed then we read the sensor data saved previously in EEPROM. These I2C write and I2C read operation are achieved using the writeEEPROM() and readEEPROM() functions explained in the how to read write external EEPROM with Arduino tutorial.

So in this Arduino with external EEPROM programming tutorial, we showed how to read/write EEPROM using I2C protocol with Arduino and provided Arduino EEPROM example code.

Post a Comment

Previous Post Next Post