Digital/Analog Clock - Arduino + PaperCraft

by alstroemeria in Circuits > Clocks

368950 Views, 1702 Favorites, 0 Comments

Digital/Analog Clock - Arduino + PaperCraft

IMG_2645.jpg
D-A_clock2.jpg
IMG_2499.jpg
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.

Gather Your Materials

IMG_2483.JPG
IMG_2562.jpg
IMG_2560.jpg
IMG_2517.jpg
IMG_2502.jpg
IMG_2523.jpg
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)



Test the Electronic Parts

IMG_2560.jpg
IMG_2517.jpg
ssc32 arduino.jpg
images.jpg
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

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

Cut Out the Pieces

IMG_2562.jpg
IMG_2502.jpg
IMG_2520.jpg
IMG_2523.jpg
IMG_2525.jpg
IMG_2532.jpg
IMG_2535.jpg
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

Construction

IMG_2588.jpg
IMG_2580.jpg
IMG_2578.jpg
IMG_2573.jpg
IMG_2583.jpg
IMG_2585.jpg
IMG_2587.jpg
IMG_2590.jpg
IMG_2594.jpg
IMG_2612.jpg
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

Add the Digits

IMG_2614.jpg
IMG_2615.jpg
IMG_2617.jpg
IMG_2621.jpg
IMG_2624.jpg
IMG_2625.jpg
IMG_2626.jpg
IMG_2627.jpg
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

Add the Servos

IMG_2629.jpg
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.

Finish Contruction

IMG_2632.jpg
IMG_2637.jpg
IMG_2635.jpg
Add the last layer (the back shield)

Wire Up Electronics

IMG_2641.jpg
IMG_2546.jpg
download.jpg
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.

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__));
    }
}

Finish

IMG_2645.jpg
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!