Monday, January 23, 2012

A Review of SnootLab's 'Memoire' Arduino Shield

SnootLabs were kind enough  to send me one of their Memoire Shields. This useful little shield combines an SD card slot with a DS1307 Real Time Clock (RTC). If you haven't come across one before, an RTC is a hardware clock with its own battery back-up, so that when your Arduino gets turned off, it does not forget the time.

The rationale for combining SD card with a RTC is that you can read temperatures or whatever and write then to the SD card along with the date and time form the RTC.


This useful card costs about 25 USD in kit form and a bit more ready assembled. I actually enjoy this kind of thing in kit form. It is easy enough to assemble and the instructions are clear and logical. They are found on the 'downloads' tab for the product information and you will also find the schematic and Eagle files there too.


One immediately noticeable feature of the board is the prototyping area. Which gives you can solder in your own temperature sensors or whatever else you want to log along with the time.

Rather than make a logger, I decided to make myself a thick juicy Arduino sandwich and combine it with a Freetronics LCD shield and an Arduino Uno to make a clock. I reviewed LCD Shields a while back.

Its a rather expensive and over-engineered clock - but none the less a clock. You set the time by sending a string from the Serial monitor and from then on, it will keep time for you.


The three boards are shown below.


The Snootlabs shield is placed on the Arduino Uno and then the LCD shield on top of that.

The only potential conflict in pin usage between the two shields is for pin D9 that is used for a general purpose LED on the Snootshield. As the LCD shield uses this for LCD Enable, occasional flickering of  the LED was not seen as a problem.

Conclusion
In summary, its a useful shield with good documentation from SnootLabs.

There are other boards including this from AdaFruit. The AdaFruit version is a similar price and even a similar layout. It does however use a buffer chip for the SD interface, where as the Snootlabs design uses potential dividers to drop the SD card levels.

Correction: In an earlier version of this post, I stated that the Snootlabs device did not have its own regulator - actually it does. Its a SMD ready soldered onto the bottom of the board. 


The code for the example project was adapted from here. Its Arduinio 1.0 code.


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

#define DS1307_ADDRESS 0x68
byte zero = 0x00; //workaround for issue #527
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Serial.println("Set date sending format: YYMMDD HHMMSS W");
  Serial.println("Where W = day of week - 1-7");
  lcd.begin(16, 2);
  lcd.print("Clock");
}

void loop()
{
  if (Serial.available())
  {
    setTimeFromSerial();
  }
  printDateTime();
  delay(1000);
}

void setTimeFromSerial()
{
  byte year = (Serial.read()-'0') * 10 + (Serial.read()-'0');
  byte month = (Serial.read()-'0') * 10 + (Serial.read()-'0');
  byte day = (Serial.read()-'0') * 10 + (Serial.read()-'0');
  Serial.read();
  byte hour = (Serial.read()-'0') * 10 + (Serial.read()-'0');
  byte minute = (Serial.read()-'0') * 10 + (Serial.read()-'0');
  byte second = (Serial.read()-'0') * 10 + (Serial.read()-'0');
  Serial.read();
  byte weekDay = (Serial.read()-'0');

  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero); //stop Oscillator

  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(weekDay));
  Wire.write(decToBcd(day));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));

  Wire.write(zero); //start 

  Wire.endTransmission();

}


byte decToBcd(byte val){
// Convert normal decimal numbers to binary coded decimal
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)  {
// Convert binary coded decimal to normal decimal numbers
  return ( (val/16*10) + (val%16) );
}

void printDateTime(){

  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);

  int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
  int weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
  int monthDay = bcdToDec(Wire.read());
  int month = bcdToDec(Wire.read());
  int year = bcdToDec(Wire.read());

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(hour);
  lcd.print(":");
  if (minute < 10) lcd.print("0");
  lcd.print(minute);
  lcd.print(":");
  if (second < 10) lcd.print("0");
  lcd.print(second);
  

}

About the Author
These are my books. Click on the image below to find out more about them.





No comments: