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. 
Wiring diagram for Lightning Talk timer

/*
  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
  }
}

Tags »

Author:
Date: Sunday, 1. August 2010 1:55
Trackback: Trackback-URL Category: Uncategorized

Feed for the post RSS 2.0 Comment this post

6 comments

  1. 1

    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.

  2. 2

    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.

  3. 3

    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!?

  4. 4

    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

  5. 5

    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

  6. 6

    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

Submit comment