Skip to content

Instantly share code, notes, and snippets.

@dustin
Created January 1, 2010 02:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dustin/267014 to your computer and use it in GitHub Desktop.
Save dustin/267014 to your computer and use it in GitHub Desktop.
My countdown timer as seen on TV: http://www.youtube.com/watch?v=Qv_ruj4lhXo
#include <Servo.h>
#define SERVO 11
byte leds[] = { 4, 5, 6, 7, 8, 9 };
#define NLEDS 6
// Manually placing the pointer since the actual labels
// ended up being slightly off.
// 5 4 3 2 1
byte positions[] = { 148, 119, 79, 52, 27, 0 };
Servo servo;
void setup() {
Serial.begin(9600);
// Initialize the countdown LEDS
for(int i = 0; i < NLEDS; i++) {
pinMode(leds[i], OUTPUT);
digitalWrite(leds[i], LOW);
}
// Point the servo at 0
servo.attach(SERVO);
setAndWait();
}
void setAndWait() {
servo.write(180);
Serial.println("hello");
// Turn off all the lights.
for(int i = 0; i < NLEDS; i++) {
digitalWrite(leds[i], LOW);
}
// Wait for my signal
bool readyToGo = false;
while(!readyToGo) {
byte b = Serial.read();
switch(b) {
case 'g': // GO!
readyToGo = true;
break;
case 's': // Synchronize
Serial.println("s");
// blink a sync pattern
for(int i = 0; i < NLEDS; i++) {
digitalWrite(leds[i], HIGH);
delay(10);
digitalWrite(leds[i], LOW);
}
break;
default:
delay(50);
}
}
for(int i = 0; i<NLEDS; i++) {
digitalWrite(leds[i], HIGH);
servo.write(positions[i]);
delay(1000);
digitalWrite(leds[i], LOW);
}
}
void blinkErratically() {
// Select a random light to blink.
int led = leds[random(0, NLEDS)];
digitalWrite(led, HIGH);
delay(random(20, 100));
digitalWrite(led, LOW);
delay(random(20, 100));
}
void loop() {
// If the control channel sends an 'r' command, reset state.
// This allows testing and stuff.
if (Serial.available() && Serial.read() == 'r') {
setAndWait();
}
blinkErratically();
}
#!/usr/bin/env python
# worse is better
import os
import sys
import time
import serial
def timeTilNearest(secondFactor):
t = int(time.time())
nearest = 10
nextT = (int(t / secondFactor) * secondFactor) + secondFactor
duration = nextT - t
return duration
def sync(ser):
print "Sending sync cmd..."
ser.write("s")
ser.flush()
print "Waiting for sync response."
b = ser.readline().strip()
print "Read", repr(b)
assert(b == 's')
if __name__ == '__main__':
ser = serial.Serial("/dev/tty.usbserial-A900acmg")
print ser.readline().strip()
sync(ser)
t = time.time()
duration = timeTilNearest(3600)
# duration = timeTilNearest(30)
nextT = t + duration
while t < nextT - 10:
# Compute the time on each iteration.
then = nextT - t - 10
duration = min(15, then)
print "It's now %s, flashing in %ds at %s" % (time.ctime(t),
then, time.ctime(nextT))
if nextT - t < 600:
sync(ser)
time.sleep(max(0, duration))
t = time.time()
t = time.time()
print "Counting down at %s (%f to go)" % (time.ctime(t), nextT - t)
for w in (10, 9, 8, 7):
# Do a vocal countdown. I recalculate the time duration on
# each request so I don't have to worry about how long it
# takes to issue the say command.
duration = nextT - w - time.time()
print "Sleeping at %d for %f" % (w, duration)
time.sleep(max(0, duration))
os.system("say %d" % w)
print "Adjusting volume and stuff at %s." % (time.ctime(time.time()))
os.system("""osascript -e 'tell application "iTunes" to pause'""")
os.system("""osascript -e 'tell application "iTunes" to set sound volume to 100' &""")
os.system("say 6")
time.sleep(max(0, nextT - time.time() - 5))
print "Executing at %s" % time.ctime(time.time())
ser.write("g\n")
ser.flush()
time.sleep(1)
print "Playing music"
os.system("""osascript -e 'tell application "iTunes" to play track named "Auld Lang Syne"'""")
# How long to do the light show.
time.sleep(108)
print "Sending an r"
ser.write("r\n")
ser.flush()
time.sleep(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment