User login

Powered by Drupal, an open source content management system

Theory and Practice of Tangible User Interfaces

Lab 8: Cuckoo Clock

Submitted by Seth Horrigan on Sat, 10/25/2008 - 17:03

Assignment: Simple Mechanics: Cuckoo Clock

Collaborators: katalene, agreiner

Description

In order to gain experience with simple mechanics and to get further experience working with servo actuation and converting between linear and rotational motion (or vice-versa), we created a Cuckoo clock. More precisely, we created a bird house with a door that opens, a bird that comes out, and a Piezo speaker that tries (poorly) to imitate the sound of a Cuckoo clock chiming.

 

Components Used

  • 1 Arduino board
  • 1 generic solderless breadboard
  • 2 rubber bands to secure the Arduino board to the breadboard
  • wires
  • electrical tape
  • fishing line
  • 1 servo motor
  • various pieces of balsa wood
  • 1 coffee stirrer
  • hot glue
  • 1 Piezo speaker
  • 1 Lego technic piece
  • fasteners and sewing pins

 

Images and Video

Cuckoo Clock in action

 

Just finished

Closed

Opening

The materials

 

Arduino Code

/*
* Open and close a cuckoo clock
* Theory and Practice of Tangible User Interfaces
* Oct 25, 2008
*
* Seth Horrigan
*/


long lastPulse = 0; // the time in millisecs of the last pulse
int refreshTime = 20; // the time in millisecs needed in between pulses
int pulseWidth = 500; // originally the servo is "closed"
//Used to make sound
byte names[] = {'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C'};
int tones[] = {1915, 1700, 1519, 1432, 1275, 1136, 1014, 956};

int servoOut = 7;
int speakerOut = 8;

void setup() {
pinMode(servoOut, OUTPUT); // Set servo pin as an output pin
pinMode(speakerOut, OUTPUT); // Set speaker pin as an output pin
Serial.begin(9600); // connect to the serial port
}

void loop() {
static int lastAction = 0;
int time = millis();

//close for ten seconds
if(pulseWidth == 500 && time - lastAction >= 10000){
/*
Serial.print("Setting to 1735 at time ");
Serial.print(time, DEC);
Serial.print(", with last action at ");
Serial.println(lastAction, DEC);
*/

lastAction = time;
pulseWidth = 1735;

//open for four seconds
}else if(pulseWidth == 1735 && time - lastAction >= 3000){
/*
Serial.print("Setting to 500 at time ");
Serial.print(time, DEC);
Serial.print(", with last action at ");
Serial.println(lastAction, DEC);
*/

lastAction = time;
pulseWidth = 500;
//Make the piezo cuckoo sound
int count = 0;
int i = 0;
for(i = 0; i < 2; i++){
for (count = 0; count < 64; count++) {
digitalWrite(speakerOut, HIGH);
delayMicroseconds(tones[6]);
digitalWrite(speakerOut, LOW);
delayMicroseconds(tones[6]);
}
delay(100);
for (count = 0; count < 64; count++) {
digitalWrite(speakerOut, HIGH);
delayMicroseconds(tones[0]);
digitalWrite(speakerOut, LOW);
delayMicroseconds(tones[0]);
}
delay(200);
}
}

updateServo();
}

// called every loop().
void updateServo() {
if (millis() - lastPulse >= refreshTime) {
// pulse the servo again if the refresh time (20 ms) has passed:
digitalWrite(servoOut, HIGH); // Turn the motor on
delayMicroseconds(pulseWidth); // Length of the pulse sets the motor position
digitalWrite(servoOut, LOW); // Turn the motor off
lastPulse = millis(); // save the time of the last pulse
}
}