Introduction: Digital/Analog Clock - Arduino + PaperCraft

About: Hello, I'm a Software Engineer!
In this instructable we will be recreating a clock inspired by Alvin Aronson's original design. When I first saw this clock I was very impressed by how clean an elegant the design was I immediately wanted to recreate this effect.

Alvin Aronson's original design (made with corian and wood):

I hope some of you feel the same and use this as a guide to be one-step closer to having one of your own

Essentially, we have a seven segment clock where instead of LED's we have digits moving in and out of the pane, the shadow created by these digits will allow the user to read the time against the white on white digits. By using 28 servos, we can use a arduino to first process the current time and then push the digits out accordingly through the motor controller. more will be explained in the later pages.

I've tried to keep the parts as simple as possible, using readily available parts without a deep knowledge of electronics one can begin to explore creating their own clock. I do not have 3D printer so construction will be done by way of papercrafting.

Step 1: Gather Your Materials

Here are the things you'll need. I intended to fit this in the "kit contest" category so i've limited the build to simple parts without need for soldering. Alternatively. Arduino Uno and motor-controller can be replaces with Arduino Mega which wall allow direct control of up to 64 servos. The build costs cost me around $130 in parts. Keep in mind you can reuses the parts to create other great projects like a Hexapod!

The Electronics Kit :
Arduino Uno
DS1307 or RTC clock breakout- keeps track of time
Servo motor controller - controls servo motors
28 Servos - they rotate 180 degrees

Construction:
Cardstock
Hobby aluminum tubing* - To allow digits to slide smoothly ; need a inner and outer tube
Double sided tape
Sticky Pads
Paper Clip

*Or use a pack of cheap lead pencils

Tools:
Papercutter - Shiloutte Portrait (optional)
Glue Gun
Dremel - to cut tubing (optional)
Knife (optional)



Step 2: Test the Electronic Parts

Servos
So you have a lovely ball of servos now. Better test them first. (One of mine were defective)

Connect the SSC-32 to the arduino using the attached picture as a guide
http://marc-tetrapod.blogspot.ca/2012/10/arduino-ssc-32-servo.html

RTC
What the RTC allows you to do is keep track of time using a  small lithium battery. Any system [Your computer and your phone] with a clock will have one. This is the most used way to keep track of time when things are powered on/off constantly. We will hook up this circuit later on in this instructable

Step 3: Design the Clock

The following pieces were designed in Adobe illustrator. With the intention of being cut onto paper. If you're using a 3D printer you'll likely have to use different methods but the basic idea will be the same. Also please share your designs:)

We have 6 layers:
[01] Front Face - Clock Face 
[01] Front Face - Segment face 
[02] Front Shield - Holds Tubing 
[03] Base - Holds Servo + Tubing
[03] Base - Holds Servo + Tubing
[04] Back Shield - Holds Servo 

Note: some files will need to be cut twice. see above for ordering details

Step 4: Cut Out the Pieces

The following pieces were designed in Adobe illustrator and cut with a Shiloutte Portrait. If you feel like you have the time you may want too cut out these layers by hand.

The metal rods were cut using a dremel. I cut the bigger tube 1cm and the one that slides inside it to 2cm

Step 5: Construction

In this step you will put the layers together using a padded double sided adhesive to construct the body. Use the images to guide you through this process 

Note: Metal tubing is inserted into each segment

Step 6: Add the Digits

Front Steps:
-Place inner tubing in outer tubing
-Apply Glue
-Place front facing piece
-Repeat

Back Steps:
-Cut and bend paperclip as shown in pictures
-Apply Glue
-Insert
-Bend
-Repeat

Step 7: Add the Servos

Attach servos to the paperclips we added in the previous step. the frame will ensure that the servos wont slip. You may use glue if you wish.

Step 8: Finish Contruction

Add the last layer (the back shield)

Step 9: Wire Up Electronics

Servo Controller
  1. There are 32 pins on the SSC-32 controller, plug your 28 servos in make sure you go in order.
  2. Connect the RX pin to the TX pint on the Arduino
  3. Connect the ground pin to Arduino Ground pin
RTC [DS1307]
For more information http://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/overview
  1. Connect 5V to Arduino 5V
  2. Connect GND to Arduino GND
  3. Connect SDA to Arduino analog pin 4.
  4. Connect SCL Arduino analog pin 5.

Step 10: Programing

Algorithm

Main Loop
  1. Retrieve time from RTC module (in Hour and Minutes)
  2. If time is different Display Time
  3. Repeat
Display Time
  1. Split time into four digits. (using modulo/div 10)
  2. For each seven segment display, Move segments out to display digit
Display Digit
  1. Place decoder logic. Translate int into seven segment ordering.
  2. Move needed servos from X degree.  Move unneeded servos Y degrees ( Where X is the out position and Y is the position of the plane.
Sample

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

RTC_DS1307 RTC;

short segA = 0; //Display pin 14
short segB = 1; //Display pin 16
short segC = 2; //Display pin 13
short segD = 3; //Display pin 3
short segE = 4; //Display pin 5
short segF = 5; //Display pin 11
short segG = 6; //Display pin 15

short segA_OUT = 110;
short segB_OUT = 110;
short segC_OUT = 110;
short segD_OUT = 110;
short segE_OUT = 110;
short segF_OUT = 110;
short segG_OUT = 110;

short segA_IN = 90;
short segB_IN = 90;
short segC_IN = 90;
short segD_IN = 90;
short segE_IN = 90;
short segF_IN = 90;
short segG_IN = 90;

int TIME = 2000;

DateTime datePast;
DateTime dateNow;

//house keeping
void setup() {
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  RTC.adjust(DateTime(__DATE__, __TIME__));
  datePast = RTC.now();
}

//main loop
void loop() {
  dateNow = RTC.now();
  if(!(datePast.hour() == dateNow.hour() && datePast.minute() == dateNow.hour() ))
  {
    displayNumber(dateNow.hour()*100+dateNow.minute());
    datePast = dateNow;
  }
}

//Given a number, we display 10:22
//After running through the 4 numbers, the display is left turned off
void displayNumber(int toDisplay) {
  for(int digit = 4 ; digit > 0 ; digit--) {
    lightNumber(toDisplay % 10, digit);
    toDisplay /= 10;
  }

  //start movement
  Serial.print(" T");Serial.println(TIME);
}

void move(int servo, int position) {
  Serial.print("#");
  Serial.print(servo);
  Serial.print(" P");
  Serial.print(position);
}

//Given a number, turns on those segments
//If number == 10, then turn off number
void lightNumber(int numberToDisplay, int segment) {

  int offset = (segment - 1)*7;
  switch (numberToDisplay){

  case 0:
    move(segA + offset, segA_OUT);
    move(segB + offset , segB_OUT);
    move(segC + offset , segC_OUT);
    move(segD + offset , segD_OUT);
    move(segE + offset , segE_OUT);
    move(segF + offset , segF_OUT);
    move(segG + offset , segG_IN);
    break;

  case 1:
    move(segA + offset , segA_IN);
    move(segB + offset , segB_OUT);
    move(segC + offset , segC_OUT);
    move(segD + offset , segD_IN);
    move(segE + offset , segE_IN);
    move(segF + offset , segF_IN);
    move(segG + offset , segG_IN);
    break;

  case 2:
    move(segA + offset , segA_OUT);
    move(segB + offset , segB_OUT);
    move(segC + offset , segC_IN);
    move(segD + offset , segD_OUT);
    move(segE + offset , segE_OUT);
    move(segF + offset , segF_IN);
    move(segG + offset , segG_OUT);
    break;

  case 3:
    move(segA + offset , segA_OUT);
    move(segB + offset , segB_OUT);
    move(segC + offset , segC_OUT);
    move(segD + offset , segD_OUT);
    move(segE + offset , segE_IN);
    move(segF + offset , segF_IN);
    move(segG + offset , segG_OUT);
    break;

  case 4:
    move(segA + offset , segA_IN);
    move(segB + offset , segB_OUT);
    move(segC + offset , segC_OUT);
    move(segD + offset , segD_IN);
    move(segE + offset , segE_IN);
    move(segF + offset , segF_OUT);
    move(segG + offset , segG_OUT);
    break;

  case 5:
    move(segA + offset , segA_OUT);
    move(segB + offset , segB_IN);
    move(segC + offset , segC_OUT);
    move(segD + offset , segD_OUT);
    move(segE + offset , segE_IN);
    move(segF + offset , segF_OUT);
    move(segG + offset , segG_OUT);
    break;

  case 6:
    move(segA + offset , segA_OUT);
    move(segB + offset , segB_IN);
    move(segC + offset , segC_OUT);
    move(segD + offset , segD_OUT);
    move(segE + offset , segE_OUT);
    move(segF + offset , segF_OUT);
    move(segG + offset , segG_OUT);
    break;

  case 7:
    move(segA + offset , segA_OUT);
    move(segB + offset , segB_OUT);
    move(segC + offset , segC_OUT);
    move(segD + offset , segD_IN);
    move(segE + offset , segE_IN);
    move(segF + offset , segF_IN);
    move(segG + offset , segG_IN);
    break;

  case 8:
    move(segA + offset , segA_OUT);
    move(segB + offset , segB_OUT);
    move(segC + offset , segC_OUT);
    move(segD + offset , segD_OUT);
    move(segE + offset , segE_OUT);
    move(segF + offset , segF_OUT);
    move(segG + offset , segG_OUT);
    break;

  case 9:
    move(segA + offset , segA_OUT);
    move(segB + offset , segB_OUT);
    move(segC + offset , segC_OUT);
    move(segD + offset , segD_OUT);
    move(segE + offset , segE_IN);
    move(segF + offset , segF_OUT);
    move(segG + offset , segG_OUT);
    break;

  case 10:
    move(segA + offset , segA_IN);
    move(segB + offset , segB_IN);
    move(segC + offset , segC_IN);
    move(segD + offset , segD_IN);
    move(segE + offset , segE_IN);
    move(segF + offset , segF_IN);
    move(segG + offset , segG_IN);
    break;
  }
}


Other
You will also need to set you RTC clock the first time. this will give it a starting time equal to the one on your computer. YOu will need the RTC library to run the following code.

#include
#include "RTClib.h"

RTC_DS1307 RTC;

void setup () {
    Serial.begin(57600);

    Wire.begin();

    RTC.begin();

    if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    RTC.adjust(DateTime(__DATE__, __TIME__));
    }
}

Step 11: Finish

So that's it. I hope you've learned a lot through the process and that your clock turned out well. I will be updating this instructable as I make minor adjustments

If you like me please support this instructable by voting. Thank you for reading!

Arduino Contest

Grand Prize in the
Arduino Contest

I Could Make That Contest

Participated in the
I Could Make That Contest