/* Alessandro Lambardi 14/02/2009 Released under Creative Commons 3.0 license: Attribution, Share-alike, non commercial. */ #include // download from Arduino #include // download from Arduino playground #define Disp_secs 13 // display seconds short is on digital pin 13 #define Set_mins 12 // set minutes pushbutton is on digital pin 12 #define Set_hours 11 // set hours pushbutton is on digital pin 11 #define ServoOut 10 // Servo is on digital pin 10 #define LASER_cont 9 // short to keep LASER always on, is on digital pin 9 #define LASER 8 // LASER drive output is on digital pin 8 #define PWM_TOP F_CPU/60// TOP count for timer 0 (goes into OCR0A) //#define SERVO_MAX 2350 // full max rotation is at 2.35ms pulse //#define SERVO_MIN 700 // full min rotation is at 0.70ms pulse #define SERVO_MAX 1650 // want max rotation is at 1.65ms pulse #define SERVO_MIN 750 // want min rotation is at 0.75ms pulse // Variables that are set inside interrupt routines and watched outside must be volatile volatile uint8_t hour, mins, secs; // hold the time volatile uint16_t one50th; // increased every 1/50th of a second volatile float servo_pos; // servo position Servo myservo; // clock void clock() { // do time one50th++; if(one50th < 5) { // blink LASER for 1/5 of a sec unless digitalWrite(LASER,1); // digital input is shorted to zero } else { if(digitalRead(LASER_cont) == HIGH) { digitalWrite(LASER,0); } } if(one50th > 50){ // one second has passed one50th = 0; secs++; if(secs > 59){ secs = 0; mins++; if(mins > 59){ mins = 0; hour++; if(hour > 12){ hour = 1; } } } } // set time : // set minutes if((digitalRead(Set_mins) == LOW) && ((one50th == 0) || (one50th == 25))){ mins++; if(mins > 59) { mins = 0; } secs = 0; } // set hours if((digitalRead(Set_hours) == LOW) && ((one50th == 0) || (one50th == 25))){ hour++; if(hour > 12) { hour = 1; } mins = 0; secs = 0; } if(digitalRead(Disp_secs) == LOW){ // evaluate servo position and display time servo_pos = 180.0 - (secs*180.0)/59.0; // display seconds } else { servo_pos = 180.0 - (((hour-1)*60.0+mins)*180.0)/(11.0*60.0+59.0); } myservo.write(servo_pos); } void setup() { // Port directions pinMode(LASER, OUTPUT); pinMode(Disp_secs, INPUT); digitalWrite(Disp_secs, HIGH); // turn on pullup resistors pinMode(Set_mins, INPUT); digitalWrite(Set_mins, HIGH); // turn on pullup resistors pinMode(Set_hours, INPUT); digitalWrite(Set_hours, HIGH); // turn on pullup resistors pinMode(LASER_cont, INPUT); digitalWrite(LASER_cont, HIGH); // turn on pullup resistors myservo.attach(ServoOut, SERVO_MIN, SERVO_MAX); // attach RC servo MsTimer2::set(20, clock); // 20ms period MsTimer2::start(); // Set variables default hour = 1; mins = 0; secs = 0; one50th = 0; // sei(); // enable interrupts } void loop(){ for(;;); // eveything is driven by interrupt. Do nothing here. }