Arduino Lightning Talk timer
The regional Python conference for Texas is coming up soon and I was asked to make a timer for the lightning talk events. Here is what I came up with and I am interested in comments on improving it.

/*
Lightning Talk Timer
Show green light during bulk of talk. Show yellow in the last
10 seconds. Show red when the time is up.
The circuit:
* Green LED connected from digital pin 9 to ground.
* Red LEDs connected from digital pins 12,13 to ground.
* Yellow LEDs connected from digital pins 10,11 to ground.
* Note: On most Arduino boards, there is already an LED on the board
connected to pin 13, so you don't need any extra components for this example.
Created 29 July 2010
By Ralph Green
based on an orginal by H. Barragan for the Wiring i/o board
*/
int switchPin = 2; // Switch connected to digital pin 2
int redLedPin1 = 12; // LED connected to digital pin 12
int redLedPin2 = 13; // LED connected to digital pin 13
int yellowLedPin1 = 10; // LED connected to digital pin 10
int yellowLedPin2 = 11; // LED connected to digital pin 11
int greenLedPin = 9; // LED connected to digital pin 9
int which, CounterState;
int pause;
int killLoopCounter;
unsigned long startTime, newTime, nextStepTime;
unsigned long TalkLengthSeconds = 300;
unsigned long WarningTimeSeconds = 10;
// The setup() method runs once, when the sketch starts
void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
pinMode(switchPin, INPUT); // sets the digital pin as input to read switch
// initialize the digital pin as an output:
pinMode(greenLedPin, OUTPUT);
pinMode(redLedPin1, OUTPUT);
pinMode(redLedPin2, OUTPUT);
pinMode(yellowLedPin1, OUTPUT);
pinMode(yellowLedPin2, OUTPUT);
digitalWrite(greenLedPin, LOW); // set the LED off
digitalWrite(redLedPin1, LOW); // set the LED off
digitalWrite(redLedPin2, LOW); // set the LED off
digitalWrite(yellowLedPin1, LOW); // set the LED off
digitalWrite(yellowLedPin2, LOW); // set the LED off
digitalWrite(greenLedPin, HIGH); // set the LED on
delay(400); // wait for a bit
digitalWrite(greenLedPin, LOW); // set the LED of
digitalWrite(yellowLedPin1, HIGH); // set the LED on
digitalWrite(yellowLedPin2, HIGH); // set the LED on
delay(400); // wait for a bit
digitalWrite(yellowLedPin1, LOW); // set the LED off
digitalWrite(yellowLedPin2, LOW); // set the LED off
digitalWrite(redLedPin1, HIGH); // set the LED on
digitalWrite(redLedPin2, HIGH); // set the LED on
delay(400); // wait for a bit
digitalWrite(redLedPin1, LOW); // set the LED off
digitalWrite(redLedPin2, LOW); // set the LED off
delay(400); // wait for a bit
which = 1;
CounterState = 0;
killLoopCounter = 0;
}
// the loop() method runs over and over again,
// as long as the Arduino has power
void loop()
{
// Serial.println(CounterState);
switch (CounterState) {
case 0: // Initial state. Blink to tell the world you are alive
if (digitalRead(switchPin) == 1) {// Read the pin
CounterState = 1;
startTime = millis();
nextStepTime = (TalkLengthSeconds - WarningTimeSeconds) * 1000;
pause = 0;
}
else {
if (--killLoopCounter < 1) {
killLoopCounter = 80;
digitalWrite(greenLedPin, HIGH); // set the LED on
}
else if (killLoopCounter < 78) {
digitalWrite(greenLedPin, LOW); // set the LED on
}
delay(40); // wait for a bit
}
break;
case 1: // Start countdown for the main part of the talk
newTime = millis();
if (digitalRead(switchPin) == 1) {// Read the pin
if (pause == 0) {
pause = 1;
nextStepTime -= (newTime - startTime);
}
digitalWrite(greenLedPin, LOW); // set the LED off
break;
}
else {
if (pause == 1) { // we must be coming off a pause
pause = 0;
newTime = startTime = millis();
}
digitalWrite(greenLedPin, HIGH); // set the LED on
delay(20); // wait for 20 milliseconds
}
if ((newTime - startTime) > nextStepTime) {
CounterState = 2;
startTime = millis();
nextStepTime = WarningTimeSeconds * 1000;
}
break;
case 2: // Warn that the time for the talk is almost over
newTime = millis();
digitalWrite(greenLedPin, LOW); // set the LED off
digitalWrite(yellowLedPin1, HIGH); // set the LED on
digitalWrite(yellowLedPin2, HIGH); // set the LED on
if ((newTime - startTime) > nextStepTime) {
CounterState = 3;
}
break;
case 3: // Show that time is up until button signals another round
digitalWrite(yellowLedPin1, LOW); // set the LED off
digitalWrite(yellowLedPin2, LOW); // set the LED off
digitalWrite(redLedPin1, HIGH); // set the LED on
digitalWrite(redLedPin2, HIGH); // set the LED on
if (digitalRead(switchPin) == 1) // Read the pin and display the value
CounterState = 4;
else
delay(20); // wait for a bit
break;
default: // Reset variables for another lightning talk round
digitalWrite(greenLedPin, LOW); // set the LED off
digitalWrite(redLedPin1, LOW); // set the LED off
digitalWrite(redLedPin2, LOW); // set the LED off
digitalWrite(yellowLedPin1, LOW); // set the LED off
digitalWrite(yellowLedPin2, LOW); // set the LED off
which = 1;
CounterState = 0;
killLoopCounter = 0;
delay(250); // wait for a quarter second
}
}
Friday, 13. August 2010 14:31
I’d like to suggest that a 10 second warning after a 5 minute talk isn’t much warning. My suggestion is to add a 1-minute warning. You can do a lot more with the LEDs you’ve already got, so I suggest flashing green when one minute remains. Or perhaps, since you’ve got 2 yellow LEDs, flashing yellow in opposite phases, so one yellow is always on.
Wednesday, 18. August 2010 23:09
I’m a bit concerned about how you have your switch wired up. 18K ohms is awfully high for a pull-down resistor. Thus it will be more subject to noise than you want. Also with this arrangement there is no current limiting resistor. The chip will try to pull down all the current it can. If something fails in the chip then it will sink everything that supply can provide and things go poof.
I would recommend using a pull-up to the 5V supply. Or even better, invert the polarity of that pin and use a pull-up to 5V on the inside of the switch and ground the outside of the switch. Without examining the DC specs for the chip, I think a 1K or 4.7K pull-up should be fine.
Monday, 30. August 2010 8:10
Ralph,
It’s not clear to me how you’ll be able to enter variable speaking times? (or are the times not variable at all – everyone get’s an hour?)
Also – depending how which LED’s you select, the Arduino might not have enough current to light the LED/light. In that case, you can replace the LED in your circuits with relays (which can handle much higher current and use the Ardino just for control).
Hope that helps – and hope to see it when it’s done!?
Thursday, 9. December 2010 18:34
David,
Times are not variable. The formula for speaking times is decided ahead of time. The conference organizer had me change the warning time to 30 seconds.
Ralph
Thursday, 9. December 2010 18:41
Mark,
I have read on Lady Ada’s site that the pull down resistors range from 5k to 100k, with 10k being most common. I wanted to use huge power resistors, because the values on them are easy to read. I could have gone lower. I think there were 8k or 9k resistors available. What difference would it make to use lower values? Would my battery last longer? I thought the bigger resistor was more efficient, but maybe I got that wrong. I am powering the circuit from a 9V battery, so power surges seem unlikely.
Ralph
Thursday, 9. December 2010 18:47
Gordon,
I did change the time to 30 seconds. The extra LEDs are for redundancy. I wanted to minimize the risk of a blown LED or resistor making the circuit unusable. I know there are several single points of failure left, but I at least eliminated a few. I think you are right that the circuit can do more. There are lots of unused pins on the Arduino. I need to think about revision 2 of this circuit.
Ralph