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
Images and Video
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
}
}