Tips and Tricks (8)

Previous T&T

Fed up setting parameters remotely to your Arduino based application? Why wouldn’t we use the built EEPROM space for storing data?

Note: Read the reference pages before getting any further in order to understand the fundamentals about EEPROM.

The EEPROM functions come from a library, so that the first thing to do is to declare its use on top of the sketch:

#include

Secondly, the EEPROM read and write functions deal with bytes data, which are, at first glance, uncompatible with other types of data (integers, longs, doubles). So that we will have to use the data converters that we studied before.

Here is the declaration of the global variable

typedef union combo_t {   
	double dValue;
	uint32_t lValue;
	int16_t iValue;
	uint8_t bValue[]; // Little endian format (LSB first)
} combo; 
combo _cboValue;

dValue, lValue and iValue overlap as well as bValue which size is equal to the largest data type, so as to say 4 bytes. And now are some converting functions for storing doubles and signed integers in EEPROM. The original data in stored in the appropriate dValue, lValue or iValue variable and read byte by byte in the bValue vector.

void writeDoubleInEEPROM(uint16_t address, double value) {
	_cboValue.dValue = value;
	for (uint8_t i = 0; i < 4; i++){
		EEPROM.write((address + i), _cboValue.bValue[i]);			
	}
}

double readDoubleFromEEPROM(uint16_t address) {
	for (uint8_t i = 0; i < 4; i++){
		_cboValue.bValue[i] = EEPROM.read(address + i);			
	}
	return(_cboValue.dValue);
}

void writeIntegerInEEPROM(uint16_t address, int16_t value) {
	_cboValue.iValue = value;
	for (uint8_t i = 0; i < 2; i++){
		EEPROM.write((address + i), _cboValue.bValue[i]);			
	}
}

int16_t readIntegerFromEEPROM(uint16_t address) {
	for (uint8_t i = 0; i < 2; i++){
		_cboValue.bValue[i] = EEPROM.read(address + i);			
	}
	return(_cboValue.iValue);
}

void writeLongInEEPROM(uint16_t address, int16_t value) {
	_cboValue.lValue = value;
	for (uint8_t i = 0; i < 4; i++){
		EEPROM.write((address + i), _cboValue.bValue[i]);			
	}
}

uint32_t readLongFromEEPROM(uint16_t address) {
	for (uint8_t i = 0; i < 4; i++){
		_cboValue.bValue[i] = EEPROM.read(address + i);			
	}
	return(_cboValue.lValue);
}

All you have to do is to decide about the location for each variable, taking into account the limited capacity of EEPROM (1024 bytes on the ATmega328, 512 bytes on the ATmega168 and ATmega8) and the size of the stored data. Memory locations may be declared as constants on top of the skecth, like

/* Memory locations */
#define MEM_LOC_DATA1 0 // Stores a long
#define MEM_LOC_DATA2 4 // Stores an integer
#define MEM_LOC_DATA3 6 // Stores a double

And so on…

Next T&T

One Comment

  1. […] must me used in order to get the double formated value. Firstly, you will need to declare a union type variable in order to map the double formated value and the array of […]

Leave a Reply

You must be logged in to post a comment.