Introduction

There are numerous EEPROM memories, but one I used was the AT24C64 from Atmel. Atmel is the same company behind the Atmega 328p which is the brain of the Arduino Pro Mini. You would be surprised to see how they interact with people/makers/consumers on Twitter and Google Plus. This memory is non-volatile, which means it wont lose its data went our watch, or your device runs out of power.

Its main features include:

  • Low-voltage operation (VCC = 2.7V to 5.5V);
  • Internally organized 8192 words x 8 bits;
  • 2-wire serial interface (I2C);
  • Schmitt trigger, filtered inputs for noise suppression;
  • Bidirectional data transfer protocol;
  • 100 kHz and 400 kHz (5V) clock rate;
  • Write protect pin for hardware data protection
  • Self-timed write cycle (10 ms max);
  • High reliability – endurance: 1 million write cycles – data retention: 100 Years;
  • 8-Pin PDIP, 8-Pin SOIC, 8-pin TSSOP Packages;

Other interesting fact about this memory is that it consumes up to 2 mA when reading / writing, but only up to 2 uA when on standby.

Placing the component

at24c64 dip8 pinout pin

To place the AT24C64 is as simple as it gets, because this IC doesn’t need any capacitors or crystals at all. Just connect VCC, GND to its correspondent pins on the Atmega, and the SDA to pin A4 and SCL to pin A5. Pins A0, A1 and A2 from the EEPROM can be connected to VCC or GND or even left unconnected, depending on which address you want to set to the device. This is because this way you can have multiples memories on the same serial bus. Very useful indeed. The WP is the write-protect pin, and will allow normal writes if connected to GND.  If left unconnected, WP is internally pulled down to GND.

Adapting the code to read/write the EEPROM

Now we can insert the EEPROM.h library on the code. Then create the EEPROMWritelong() and EEPROMReadlong() because our number of steps and calories and distance walked will probably be higher than thousands, and we don’t want our variables to overflow.

void EEPROMWritelong(int address, long value) {
 byte four = (value & 0xFF);
 byte three = ((value >> 8) & 0xFF);
 byte two = ((value >> 16) & 0xFF);
 byte one = ((value >> 24) & 0xFF);

 EEPROM.write(address, four);
 EEPROM.write(address + 1, three);
 EEPROM.write(address + 2, two);
 EEPROM.write(address + 3, one);
}

 long EEPROMReadlong(long address) {
 long four = EEPROM.read(address);
 long three = EEPROM.read(address + 1);
 long two = EEPROM.read(address + 2);
 long one = EEPROM.read(address + 3);

 return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0        xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}

Now we can get this together with our code from the previous article:

//INCLUDES
#include <LowPower.h>
#include <Wire.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
#include <EEPROM.h>

//GLOBAL
#define LED_PIN 13

//BUTTON
#define BUTTON 2

//EEPROM
unsigned long int steps;
#define addStp 0 //address of byte to store number of steps
#define addCal 4 //address of byte to store number of calories 
#define addKm 8 //address of byte to store number of km 

//TIME
#define PCF8563address 0x51
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 readPCF8563() {
 Wire.beginTransmission(PCF8563address);
 Wire.write(0x02);
 Wire.endTransmission();
 Wire.requestFrom(PCF8563address, 7);
 second = bcdToDec(Wire.read() & B01111111); 
 minute = bcdToDec(Wire.read() & B01111111); 
 hour = bcdToDec(Wire.read() & B00111111);
 dayOfMonth = bcdToDec(Wire.read() & B00111111);
 dayOfWeek = bcdToDec(Wire.read() & B00000111);
 month = bcdToDec(Wire.read() & B00011111); 
 year = bcdToDec(Wire.read());
}

void wakeUp(){
 // Just a handler for the pin interrupt.
 while (!digitalRead(BUTTON)) {};
}

void setup() {
 pinMode(BUTTON, INPUT_PULLUP);
 pinMode(LED_PIN, OUTPUT);
 pinMode(0, OUTPUT);
 pinMode(1, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(4, OUTPUT);
 pinMode(5, OUTPUT);
 pinMode(6, OUTPUT);
 pinMode(7, OUTPUT);
 pinMode(8, OUTPUT);
 pinMode(9, OUTPUT);
 pinMode(10, OUTPUT);
 pinMode(11, OUTPUT);
 pinMode(12, OUTPUT);

 digitalWrite(0, LOW);
 digitalWrite(1, LOW);
 digitalWrite(3, LOW);
 digitalWrite(4, LOW);
 digitalWrite(5, LOW);
 digitalWrite(6, LOW);
 digitalWrite(7, LOW);
 digitalWrite(8, LOW);
 digitalWrite(9, LOW);
 digitalWrite(10, LOW);
 digitalWrite(11, LOW);
 digitalWrite(12, LOW);
 digitalWrite(LED_PIN, LOW);

 Wire.begin();
 Serial.begin(9600);
 delay(100);
}

void loop(){
 attachInterrupt(0, wakeUp, LOW);
 LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
 detachInterrupt(0);
 readPCF8563();
 Serial.print(hour);
 Serial.print(":");
 Serial.print(minute);
 Serial.print(":");
 Serial.println(second);
 steps = 100; //number of steps from step counter
 EEPROMWritelong(addStp, steps); //number of steps can achieve millions
 Serial.println("Written!");
 Serial.println(EEPROMReadlong(addStp));
 delay(1000);
}

void EEPROMWritelong(int address, long value) {
 byte four = (value & 0xFF);
 byte three = ((value >> 8) & 0xFF);
 byte two = ((value >> 16) & 0xFF);
 byte one = ((value >> 24) & 0xFF);

 EEPROM.write(address, four);
 EEPROM.write(address + 1, three);
 EEPROM.write(address + 2, two);
 EEPROM.write(address + 3, one);
}

long EEPROMReadlong(long address) {
 long four = EEPROM.read(address);
 long three = EEPROM.read(address + 1);
 long two = EEPROM.read(address + 2);
 long one = EEPROM.read(address + 3);

 return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0        xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}

WP_20150909_20_46_24_Pro

Conclusion

 serial i2c arduino eepromAs we have seen, it was possible to write and then read a variable to the AT24C64. The breadboard circuit was still really simple. The digital multimeter read 16 uA of current, just like my last article, with the Atmega and the real-time PCF8563, but without the memory. This means that when on standby, the EEPROM consumes so little power that it is even hard to get a reading. Doing the same as on that article, after disabling the brownout detector, the current lowered from those 16 uA to a miserable 0.7 uA.

arduino bare bones protoboard breadboard pro mini low power down

The blog post covering how to do this, you can find here. It is really useful when making a device that has a small battery, such as phones, smartwatches, digital music players, watches –  devices that use batteries like the CR2032, or LIR of some type. On my next article I’ll put a Oled display on my smartwatch project and see how low the power consumption can get.

Where to go from here

6 thoughts on “Adding EEPROM to your Arduino Pro Mini Smartwatch

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s