Andrea, Carlos, Ian, John and Kilian built a cuckoo clock that appears at 12am. The door mechanism resembles a draw-bride, the bird sits on top of a four bar linkage.
See our video here: http://www.youtube.com/watch?v=iGilCUJ5uRM
The code:
/*
Cuckoo Clock
Tangible User Interfaces 2011
Andrea Hsieh, Ian Leighton, Kilian Moser, John Parayno, Carlos Sandoval
Credits: Thx Chelsy for the awesome bird song
*/
//PIN SETUP
const int potPin = A5; //Input pin for the clock
const int doorPin = 2; //Servo output pin for the door mechanism
const int birdPin = 3; //Servo output pin for the bird mechanism
const int peepPin = 5; //Output pin for the piezo speaker / bird peeping
//SERVO VARIABLES
int pulseWidth = 0; // Amount to pulse the servo
long lastPulse = 0; // the time in millisecs of the last pulse
int refreshTime = 20; // the time in millisecs needed in between pulses
//VARIABLES TO CYCLE THROUGH CUCKOO STATES
boolean cycle_check = false; //true if cuckoo cycle is running, false is completed
int potVal = 0; //Value of the potentiometer clock
long lastCycle = 0; // the time in millisecs of the last cycle
int mov_state = 0; // controls cuckoo states from 1 to 6
const int cycleTime = 1000; // Set the cycle time for the servos
int servoPulse = 0; // Varibale to switch Servo Pulse
int servoPin = 0; // Varibale to switch Servo Pin
//SETUP FOR TIME TRIGGER AND SERVOS
const int minClock = 340; //lower barrier of the clock trigger
const int maxClock = 380; //upper barrier of the clock trigger
const int doorDown = 1860; //position of servo for door down
const int doorUp = 780; //position of servo for door up
const int birdIn = 2338; //position of servo for bird inside the house
const int birdOut = 1200; //position of servo for bird outside the house
void setup() {
pinMode(doorPin, OUTPUT); // Set servo pin as an output pin
pinMode(birdPin, OUTPUT); // Set servo pin as an output pin
pinMode(peepPin, OUTPUT); // Set peep pin as output pin
Serial.begin(9600); // connect to the serial port
Serial.println("Cuckoo Clock is ready");
}
void loop() {
potVal = analogRead(potPin); // read the value of the potentiometer to get the time
Serial.println(potVal);
if(cycle_check) { // if cuckoo clock is in a cycle
cuckoo_switch(); // Run the cuckoo sequence
} else {
if(potVal >= minClock && potVal <= maxClock) { //trigger cuckoo cycle if the "time" is correct
cycle_check = true;
}
}
// Update Servo position
if (millis() - lastPulse >= refreshTime) {
servo(servoPulse, servoPin); // Update Servo position
lastPulse = millis(); // save the time of the last pulse
}
}
void cuckoo_switch() {
if(millis() - lastCycle >= cycleTime) {
mov_state = mov_state + 1;
switch(mov_state) {
case 1: // Door comes down
servoPin = doorPin;
servoPulse = doorDown;
break;
case 2: // Bird goes out
servoPin = birdPin;
servoPulse = birdOut;
break;
case 3: // Bird peeps
beep();
beep();
beep();
break;
case 4: // Bird goes in
servoPin = birdPin;
servoPulse = birdIn;
break;
case 5: // Door goes up
servoPin = doorPin;
servoPulse = doorUp;
break;
case 6: // Reset cycle after door is up again
mov_state = 0;
cycle_check = false;
break;
default:
mov_state = 0;
cycle_check = true;
break;
}
lastCycle = millis();
Serial.println(mov_state+1, DEC);
}
}
void beep() {
tone (peepPin, 2794,25);
delay (25);
tone (peepPin, 3136, 25);
delay (25);
tone (peepPin, 4435, 25);
delay (100);
tone (peepPin, 3322,25);
delay (25);
tone (peepPin, 3136, 25);
delay (25);
tone (peepPin, 2637, 25);
delay (100);
tone (peepPin, 2794,25);
delay (25);
tone (peepPin, 3136, 25);
delay (25);
tone (peepPin, 4435, 25);
delay (2000);
noTone(peepPin);
}
void servo(int cur_pulseWidth, int pin) {
digitalWrite(pin, HIGH); // Turn the motor on
delayMicroseconds(cur_pulseWidth); // Length of the pulse sets the motor position
digitalWrite(pin, LOW); // Turn the motor off
}
Pictures