This year, as part of the publicity for their Christmas charity gifts, Concern Worldwide (who I’m lucky enough to work for) commissioned an artist to come up with a design for an advent calendar.
The resulting design by Robert Fiszer is really rather lovely (you can check out the campaign here)- and lends itself rather well to be illuminated as a Christmas decoration for the Concern office.

So as a spare tinkering time project I thought I would have a go at building an Arduino controlled LED advent calendar that illuminates the relevant day and counts down to the 24th.
My requirements needed it to be powered by USB, and that it’s a standalone project with it’s own date clock – as the office IT department would frown upon me installing things on my work PC to run Christmas decorations from. In order to do this I needed to read up on using a battery backed up RTC (Real Time Clock) and a way to control 24 LEDs from my arduino micro.
I decided on using a shift register – the other option would be to use a chain of NeoPixel LEDs, but I wanted to learn about shift registers and get an idea about how they worked. For an excellent introduction to shift registers check out this blog from Bildr.
Essentially a shift register is a way of converting a serial signal from the arduino into a parallel series of high and low signals to the output pins on each chip. Each shift register has 16 pins, 8 output pins, 2 earth pins, 2 positive 5 volt pins, 3 serial input pins consisting of clock, latch and time signals, and a final serial output pin which is used when daisy chaining them together.
The 74HC595 8-bit Shift Register I used was available cheaply on ebay and looks like this:

Wired up with an arduino on breadboard it looks like this:
Even with just 8 outputs it looks a bit messy. With 3 shift registers daisy chained together it looks even more complicated:
But remember the diagram above – the circuit is still fairly simple, what makes it look complicated is the loops of wire which are all the same length. The challenge I found with the chip is that one of the outputs is on one side, with the remaining 7 on the other.
To tidy everything up, I soldered the chips in carriers onto a piece of full sized Adafruit perma-proto breadboard. I highly recommend using this stuff – it costs a bit more than the generic soldering boards you can buy on ebay, but it’s strong and laid out sensibly using the same layout as standard prototyping boards. In my layout I spaced the shift registers 1 hole apart and moved the offside output around the corner of the chip, so that all 8 outputs were on the same side. To connect my LEDs I was able to add 8 socket female headers as I found soldering the LED wires directly into the board was difficult as the stranded copper wire would snap easily. Plus using headers gives me the option to swap out the LEDs for something else in the future. For LEDs I found pre-soldered 5 volt LEDs available on ebay that included the resistor.
My board includes 4 shift registers giving me a total of 32 outputs – this would enable me to re-purpose the board in future, as I’m thinking after advent it would make a nice monthly calendar.
Here’s the board without any of the LEDs attached:

For the time circuit I used a DS 1307 RTC – the one I used shares the same chipset as the Adafruit one detailed here (link) (normally I’d buy the adafruit one to support their website, but I couldn’t find it available online).
The code:
/* Shift register calendar */ // Date and time functions using a DS1307 RTC connected via I2C and Wire lib #include <Wire.h> #include "RTClib.h" #if defined(ARDUINO_ARCH_SAMD) // for Zero, output on USB Serial console, remove line below if using programming port to program the Zero! #define Serial SerialUSB #endif RTC_DS1307 rtc; // shift register setup //**************************************************************// // Name : shiftOutCode, Dual One By One // // Author : Carlyn Maw, Tom Igoe // // Date : 25 Oct, 2006 // // Version : 1.0 // // Notes : Code for using a 74HC595 Shift Register // // : to count from 0 to 255 // //**************************************************************// int SER_Pin = 4; //pin 14 on the 75HC595 int RCLK_Pin = 5; //pin 12 on the 75HC595 int SRCLK_Pin = 6; //pin 11 on the 75HC595 int caldate = 0; //How many of the shift registers - change this #define number_of_74hc595s 4 //do not touch #define numOfRegisterPins number_of_74hc595s * 8 boolean registers[numOfRegisterPins]; void setup() { pinMode(SER_Pin, OUTPUT); pinMode(RCLK_Pin, OUTPUT); pinMode(SRCLK_Pin, OUTPUT); //reset all register pins clearRegisters(); writeRegisters(); #ifndef ESP8266 while (!Serial); // for Leonardo/Micro/Zero #endif Serial.begin(57600); if (! rtc.begin()) { Serial.println("Couldn't find RTC"); while (1); } if (! rtc.isrunning()) { Serial.println("RTC is NOT running!"); // following line sets the RTC to the date & time this sketch was compiled rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // This line sets the RTC with an explicit date & time, for example to set // January 6, 2014 at 3am you would call: // rtc.adjust(DateTime(2014, 1, 6, 3, 0, 0)); } } //set all register pins to LOW void clearRegisters(){ for(int i = numOfRegisterPins - 1; i >= 0; i--){ registers[i] = LOW; } writeRegisters(); } //Set and display registers //Only call AFTER all values are set how you would like (slow otherwise) void writeRegisters(){ digitalWrite(RCLK_Pin, LOW); for(int i = numOfRegisterPins - 1; i >= 0; i--){ digitalWrite(SRCLK_Pin, LOW); int val = registers[i]; digitalWrite(SER_Pin, val); digitalWrite(SRCLK_Pin, HIGH); } digitalWrite(RCLK_Pin, HIGH); } //set an individual pin HIGH or LOW void setRegisterPin(int index, int value){ registers[index] = value; } void loop() { DateTime now = rtc.now(); caldate = now.day(); Serial.print(caldate); Serial.print(now.day(), DEC); delay(1500); clearRegisters(); delay(500); for (int i = 0; i < caldate; i++) { setRegisterPin(i, HIGH); writeRegisters(); delay(100); } }
Note – the RTC was the trickiest part of the circuit, and after reading lots of posts from people who’ve had issues with the DS1307 I’d recommend using one of the integrated chip varieties.
The code for the calendar is fairly simple – it checks the date from the RTC and then lights up the appropriate number of lights. I’ve made it loop to give a bit more visual interest, but it’s easy enough to modify the code to make it just light up once when you plug it in.
Assembly
I printed out the calendar image and pasted it onto a bit of board with holes behind each ‘light’. Using a frame from a previous project (the Concern general election Swingometer) to bring it all together. To mount the LEDs I used bottle tops – this involved drinking a lot of diet coke, and when I ran out of that, wine.

Here’s the final version, in action as if it’s Christmas Eve showing all the lights as I removed the RTC.
If you liked this project, please buy a gift from Concern’s shop – my personal favourite is the solar lights as they are a neat technological solution to the tricky problem of lighting.