Starteruhr

Autor: Dipl.-Ing. Wilfried Klaas
Board: Inteaduino, Arduino Duemilanove

Für unsere 152VO Klasse brauchen wir natürlich auch eine Starteruhr für den für den standesgemässen (fliegenden) Rennbegin.

Im Schiffsmodell.net Forum entstand die Idee, hier der konstituierende Thread: www.schiffsmodell.net/showthread.php Meine Projektseite liegt hier: Projektseite

Hier möchte ich ein bisschen auf die Besonderheiten des Programms eingehen.

Uhr_152vo_2.ino
#include <RCReceive.h>
#define debug
#include <debug.h>
#include <makros.h>

/*
 Starter Uhr für Bootsrennen der 152vo'er Klasse.
 
 Version 0.2 - Änderung
    RC Receiver Bibliothek...
 
 Es ist ein Testprogramm integriert. Dieses wird aktiviert, wenn beim Einschalten der Uhr der Starttaster gedrückt wird.
 Zunächst werden die LED's der Reihe nach getestet. Dann der Lautsprecher und das RC System (Funksignal wird an den LED's ausgegeben.) 
 Zuletzt wird die Uhr mechanisch getestet. Erst 20 Schritte vorwärts dann 20 SChritte zurück und dann auf den Nullpunkt.
 
 Die Uhr ist aufgebaut mit 1 Schrittmotor für die Zeitanzeige. Weiterhin sind 5 LED-Strahler vorhanden,
 die die Zeit ab Start der Uhr anzeigen. Gestartet wird mit Hilfe einer Standartfernsteuerung.
 
 Reihenfolge 2 weiße LED's, 1 gelbe, 2 grüne
 
 Ablauf:
 Modus Normal:
 
 Reset: Alles auf null, 3x Beep, Schrittmotor aus
 Test auf Start, -> ja
 Zeiger auf null
 LED W1 geht an, Beep. Uhr läuft,
 nach 1 Minute: LED W1 geht aus, LED W2 geht an,
 nach 2 Minuten: LED W2 geht aus, LED Y3 geht an, letzte Minute Beep
 nach 3 Minuten: 2xLED Grün gehen an, Beep, 10 sec warten, Schrittmotor 20 zurück, reset.
 
 Modus Dragrace:
 Reset
 Test auf Start, -> ja
 Zeiger auf null, Uhr läuft
 15 Sekunden vor Ende, Beep.
 noch 3 Sekunden: Beep, LED W1 geht an
 noch 2 Sekunden: Beep, LED W2 geht an, LED W1 geht aus
 noch 1 Sekunde: Beep, LED Y3 geht an, LED W2 geht aus,
 Start: 2xLED Grün gehen an, Beep, 10 sec warten, Schrittmotor 20 zurück, reset.
 
 Hardware Pin Belegung
 LED Steuerung:
 LED W1 = 14 (A0)
 LED W2 = 15
 LED Y3 = 16;
 LED G4 = 17;
 LED G5 = 18; (A4)
 
 Schrittmotor mit EasyDriver 4.4, Halbschrittverfahren:
 SM_STEP = 8;    Schrittmotor Takt
 SM_DIR = 7;     Schrittmotor Richtung
 SM_SLEEP = 6;   Schrittmotor Ein/Aus
 SM_SWITCH = 5;  Schrittmotor Nullpunkt LS
 
 Standardfernsteuerung
 RC_PIN = 0;     RC Pin ist dann Pin 2, 1=> Pin 3 (ext. Interrupt 0/1)
 
 Kleiner Verstärker mit Druckkammersystem
 BEEP_PIN = 3;   Lautsprecherpin
 
 Kleiner Taster für den Testbetrieb
 SWITCH = 4;     Handstarttaster
 SW_CLOCK_MODE = 1; Schalter für den Uhrmodus.
 */
 
// Program im Debugmodus kompilieren, dann werden zus. Ausgaben auf die serielle Schnittstelle geschrieben.
//#define debug
 
/* Programmkonstanten */
// Pin Nummern LED's
const byte LED_W1 = 14;
const byte LED_W2 = 15;
const byte LED_Y3 = 16;
const byte LED_G4 = 17;
const byte LED_G5 = 18;
const byte LED_BOARD = 13;
 
// Pin Nummern für den Schrittmotor
const byte SM_STEP = 8;
const byte SM_DIR = 7;
const byte SM_SLEEP = 6;
const byte SM_SWITCH = 5;
 
// Pin nummern Taster Start und schalter ClockMode
const byte SW_START = 4;
const byte SW_CLOCK_MODE = 12;
 
// Schrittmotor Konstanten
const byte S = 200; // Motor: Schritte pro Umdrehung
const byte F = 2; // Faktor der Motorkarte: 1,2,4,8 für Voll, Halb Viertel oder 1/8 Schritt
const byte G = 4; // Geschwindigkeit in U/min d.h. di emaximale Geschwindigkeit der Uhr soll das 4-fache 
// einer normalen Uhr betragen.
 
// Brechnugnen
const word Su = S * F; // Schritte pro Umdrehung an die SM-Karte
// word Ss = G * Su / 60; // Schritte pro Sekunde
// word Ps = 1000 / Ss; // Pausenzeit zwischen 2 Schritten in MSec
// word Ph = Ps / 2;
const word Ph = 30000 / (G * S * F );
const boolean SM_DIRECTION = false;
 
// Empirisch ermittelte Werte für den Empfänger, sind an den jeweiligen Empfänger anzupassen
const word StartRCValue = 170;
const word ResetRCValue = 90;
const byte PIN_RC = 2; 
 
// Einstellunge für die Hupe
const byte BEEP_PIN = 3;
const word BEEP_HZ = 500;
 
/* Konstanten zur Steuerung */
const word MIN = 600;
const word MIN_1 = MIN;
const word MIN_2 = MIN * 2;
const word MIN_3 = MIN * 3;
const word SEC_5 = MIN_3 - 50;
const word SEC_4 = MIN_3 - 40;
const word SEC_3 = MIN_3 - 30;
const word SEC_2 = MIN_3 - 20;
const word SEC_1 = MIN_3 - 10;
const word DO_RESET = MIN_3 + 200;
 
const word DRAG_SEC_5 = 550;
const word DRAG_SEC_4 = 560;
const word DRAG_SEC_3 = 570;
const word DRAG_SEC_2 = 580;
const word DRAG_SEC_1 = 590;
const word DRAG_SEC_0 = 600;
const word DRAG_RESET = 800;
 
/* Variablenbereich */
// uhr wurde gestartet.
boolean started;
// der 1 Minuten Beep wurde abgegeben
boolean oneBeep;
// der Start Beep wurde abgegeben
boolean longBeep;
// ein Reset soll ausgelöst werden.
boolean doReset;
 
// Starttime ist in 1/10 sekunden
word startTime;
 
byte RcStart;
byte RcReset;
unsigned long nexttime;
word deltaTime;
word steps;
word done;
boolean firstStep;
//word saveDelta;
word lastStepUsed;
boolean doTestSystem;
boolean dragMode; 
 
boolean lastBeeps[5];
 
RCReceive rcReceiver;
 
void setup() {                
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  pinMode(LED_BOARD, OUTPUT);    
  pinMode(LED_W1, OUTPUT);    
  pinMode(LED_W2, OUTPUT);    
  pinMode(LED_Y3, OUTPUT);    
  pinMode(LED_G4, OUTPUT);    
  pinMode(LED_G5, OUTPUT);    
 
  // Ausgang für die Hupe
  pinMode(BEEP_PIN, OUTPUT);    
 
  // Ausgänge und Eingang für die Motorelektronik
  pinMode(SM_STEP, OUTPUT);    
  pinMode(SM_DIR, OUTPUT);    
  pinMode(SM_SLEEP, OUTPUT);
  pinMode(SM_SWITCH, INPUT);
  digitalWrite(SM_SWITCH, HIGH);
 
  // Eingang für Starttaster
  pinMode(SW_START, INPUT);     
  digitalWrite(SW_START, HIGH);
 
  // Eingang für den Modusschalter
  pinMode(SW_CLOCK_MODE, INPUT);     
  digitalWrite(SW_CLOCK_MODE, HIGH);
 
  // RC Receiver in Interruptvariante
  rcReceiver.attachInt(PIN_RC);
 
  // Serielle Schnittstelle einstellen
  initDebug();
//   while (!Serial) ;
  delay(100);
 
  // prints title with ending line break 
  dbgOutLn("152 Uhr V0.2");  
 
  // Uhr zurück stellen
  clockReset();
 
  doTestSystem = digitalRead(SW_START) == 0;
  dragMode = digitalRead(SW_CLOCK_MODE) == 0;
 
  // 1 kurzer Beep zum Anzeigen, das Uhr betriebsbereit
  beep();  
  if (doTestSystem) {
    // 3 Beeps zum Anzeigen des Testmoduses
    delay(350);
    beep();  
    delay(350);
    beep();  
  } 
  else if (dragMode) {
    // 2 Beeps Modus Dragrace
    delay(350);
    beep();  
  }
  delay(350);
}
 
void loop() {
  if (!started) {
    boolean newDragMode = digitalRead(SW_CLOCK_MODE) == 0;
    if (newDragMode != dragMode) {
      // 1 kurzer Beep zum Anzeigen, das Uhr betriebsbereit
      beep();  
      dragMode = newDragMode;
      if (dragMode) {
        // 2 Beeps Modus Dragrace
        delay(350);
        beep();  
      }
      delay(350);    
    }
  }
  if (doTestSystem) {
    // hier geht's nur hin, wenn beim starten bereits die Start taste gedrückt wurde.
    testSystem();
    doTestSystem = digitalRead(SW_START) == 0;
  } 
  else {
    // Steppermotor evt. ausschalten;
    word now = getTime();
 
    // testen ob die starttaste oder per RC das Startsignal gegeben wurde. 
    testStart();
 
    // Uhr läuft ?
    if (started) {
      startStepper();
 
      deltaTime = getTime() - startTime;
#ifdef debug
      if ((deltaTime % 10) == 0) {
        dbgOut("d:");
        dbgOutLn(deltaTime);
      }
#endif

      // Lichter einstellen
      if (dragMode) {
        showDragLights();
      } 
      else {
        showLights();
      }
 
      if (firstStep) {
        // Zeiten einstellen
        if (dragMode) {
          nexttime = millis() + 60000;
          steps = Su;
        } 
        else {
          nexttime = millis() + 180000;
          steps = 3 * Su;
        }        
 
        done = 0;
        firstStep = false;
 
        dbgOut("first:");
        dbgOut(nexttime);
        dbgOut(",");
        dbgOut(steps);
        dbgOut(",");
        dbgOut(done);
        dbgOut(",");
        dbgOutLn(firstStep);
      }
 
      // Uhr stellen
      doSteps();
 
      // Beeps ausgeben
      if (dragMode) {
        doDragBeeps();
        if (deltaTime >= DRAG_RESET) {
          doReset = true;
        }
      }
      else {
        doBeeps();
        if (deltaTime >= DO_RESET) {
          doReset = true;
        }      
      }
    }
 
    // evt. Reset ausführen
    if(doReset) {
      clockReset();
    }
  }
}
 
/* 
 Beeps im normalen Modus
 */
void doBeeps() {
  if(!oneBeep) {
    if (deltaTime >= MIN_2) {
      beep();
      oneBeep = true;
    }
  }
  // letzten 5 Sekunden
  if(!lastBeeps[4]) {
    if (deltaTime >= SEC_5) {
      beep();
      lastBeeps[4] = true;
    }
  }
  if(!lastBeeps[3]) {
    if (deltaTime >= SEC_4) {
      beep();
      lastBeeps[3] = true;
    }
  }
  if(!lastBeeps[2]) {
    if (deltaTime >= SEC_3) {
      beep();
      lastBeeps[2] = true;
    }
  }
  if(!lastBeeps[1]) {
    if (deltaTime >= SEC_2) {
      beep();
      lastBeeps[1] = true;
    }
  }
  if(!lastBeeps[0]) {
    if (deltaTime >= SEC_1) {
      beep();
      lastBeeps[0] = true;
    }
  }
  // Start des Rennfeldes
  if (!longBeep) {
    if (deltaTime >= MIN_3) {
      longbeep();
      longBeep = true;
    }
  }   
}
/*
Beeps im Deragmodus
 */
void doDragBeeps() {
  // letzten 5 Sekunden
  if(!lastBeeps[4]) {
    if (deltaTime >= DRAG_SEC_5) {
      beep();
      lastBeeps[4] = true;
    }
  }
  if(!lastBeeps[3]) {
    if (deltaTime >= DRAG_SEC_4) {
      beep();
      lastBeeps[3] = true;
    }
  }
  if(!lastBeeps[2]) {
    if (deltaTime >= DRAG_SEC_3) {
      beep();
      lastBeeps[2] = true;
    }
  }
  if(!lastBeeps[1]) {
    if (deltaTime >= DRAG_SEC_2) {
      beep();
      lastBeeps[1] = true;
    }
  }
  if(!lastBeeps[0]) {
    if (deltaTime >= DRAG_SEC_1) {
      beep();
      lastBeeps[0] = true;
    }
  }
  // Start des Rennfeldes
  if (!longBeep) {
    if (deltaTime >= DRAG_SEC_0) {
      longbeep();
      longBeep = true;
    }
  }   
}
 
/*
Uhr zurück auf Anfang stellen
 */
void clockReset() {
  dbgOut("reset");
  doReset = false;
  started = false;
  firstStep = true;
 
  digitalWrite(LED_W1, LOW);
  digitalWrite(LED_W2, LOW);
  digitalWrite(LED_Y3, LOW);
  digitalWrite(LED_G4, LOW);
  digitalWrite(LED_G5, LOW);
 
  digitalWrite(SM_STEP, LOW);
  digitalWrite(SM_DIR, LOW);
 
  SteppStepper(50,true);
 
  oneBeep = false;
  longBeep = false;
 
  dbgOutLn("Stepper sleep");    
  digitalWrite(SM_SLEEP, LOW);
  //  calibStepper();
  RcStart = 3;
  RcReset = 3;
 
  for (int i = 0; i < 5; i++) {
    lastBeeps[i] = false;
  }
}
 
/*
Wir warten etwas auf den RC Empfänger
 */
void syncRC() {
  dbgOut("wait on RC");
  digitalWrite(LED_BOARD, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  dbgOut("off");
  digitalWrite(LED_BOARD, LOW);    // set the LED off
  delay(1000);              // wait for a second
}
 
/*
Diese Routine testet darauf, ob ein Start oder Reset ausgelöst worden ist.
 */
void testStart() {
  int switchIn = digitalRead(SW_START);
  //  switchIn = 0;
  byte RcValue = rcReceiver.getValue();
  byte smSwitch = digitalRead(SM_SWITCH); 
 
  dbgOut("rc:");
  dbgOut(RcValue);
  dbgOut(", in:");
  dbgOut(switchIn);
  dbgOut(", LS:");
  dbgOutLn(smSwitch);
 
  if ((RcValue > StartRCValue) || (switchIn == 0)) {
    // entprellen
    RcReset = 3;
    if ((RcStart > 3) && !started) {
      startStepper();
 
      started = true;
      startTime = getTime();
      // WKLA: Änderungen wegen Dragmode
      // digitalWrite(LED_W1, HIGH);
      digitalWrite(LED_W1, LOW);
      digitalWrite(LED_W2, LOW);
      digitalWrite(LED_Y3, LOW);
      digitalWrite(LED_G4, LOW);
      digitalWrite(LED_G5, LOW);
      beep();    
 
      dbgOut("started at ");
      dbgOutLn(startTime);
    } 
    else {
      // entprellen
      RcStart -= 1;
    }
  }   
  else if ((RcValue > 1000) && (RcValue < ResetRCValue)) {
    // entprellen
    RcStart = 3;
    if (RcReset > 3) {
      beep();
      delay(500);
      beep();
      delay(500);
      beep();
      delay(500);
      clockReset();
    } 
    else {
      // entprellen
      RcReset -= 1;
    }
  } 
  else {
    RcStart = 3;
    RcReset = 3;
  }
} 
 
void showLights() {
  if ((deltaTime > 0) && (deltaTime <= MIN_1)) {
    // 1. Minute
    digitalWrite(LED_W1 , HIGH);
  }
  if ((deltaTime > MIN_1) && (deltaTime <= MIN_2)) {
    // 2. Minute 
    digitalWrite(LED_W1 , LOW);
    digitalWrite(LED_W2 , HIGH);
  }
  if ((deltaTime > MIN_2) && (deltaTime <= MIN_3)) {
    // 3. Minute
    digitalWrite(LED_W2 , LOW);
    digitalWrite(LED_Y3 , HIGH);    
  }
  if ((deltaTime > MIN_3) && (deltaTime <= DO_RESET)) {
    // Start
    digitalWrite(LED_Y3 , LOW);    
    digitalWrite(LED_G4 , HIGH);
    digitalWrite(LED_G5 , HIGH);
  }
  if (deltaTime > DO_RESET) {
    // Reset
    digitalWrite(LED_W1 , LOW);
    digitalWrite(LED_W2 , LOW);
    digitalWrite(LED_Y3 , LOW);
    digitalWrite(LED_G4 , LOW);
    digitalWrite(LED_G5 , LOW);
  }
}
 
void showDragLights() {
  if ((deltaTime > 0) && (deltaTime <= DRAG_SEC_3)) {
    // 1. Minute
    digitalWrite(LED_W1 , LOW);
  } 
  if ((deltaTime > DRAG_SEC_3) && (deltaTime <= DRAG_SEC_2)) {
    // 3 Sekunden 
    digitalWrite(LED_W1 , HIGH);
  }
  if ((deltaTime > DRAG_SEC_2) && (deltaTime <= DRAG_SEC_1)) {
    // 2 Sekudnen
    digitalWrite(LED_W1 , LOW);
    digitalWrite(LED_W2 , HIGH);    
  }
  if ((deltaTime > DRAG_SEC_1) && (deltaTime <= DRAG_SEC_0)) {
    // 1 Sekunde
    digitalWrite(LED_W2 , LOW);
    digitalWrite(LED_Y3 , HIGH);    
  }
  if ((deltaTime > DRAG_SEC_0) && (deltaTime <= DRAG_RESET)) {
    // Start
    digitalWrite(LED_Y3 , LOW);    
    digitalWrite(LED_G4 , HIGH);
    digitalWrite(LED_G5 , HIGH);
  }
  if (deltaTime > DRAG_RESET) {
    digitalWrite(LED_G4 , LOW);
    digitalWrite(LED_G5 , LOW);
  }
}
 
/*
aktuelle Zeit in 1/10 Sekunde
 */
word getTime() {
  long temp = millis();
  // Starttime ist in 1/10 sekunden
  return temp / 100;
}
 
/*
Kurzer Ton.
 */
void beep() {
  dbgOutLn("B");  
  tone(BEEP_PIN, BEEP_HZ, 250);
}
 
/*
Langer Ton.
 */
void longbeep() {
  dbgOutLn("LB");  
  tone(BEEP_PIN, BEEP_HZ, 1000);
}
 
/*
Uhr stellen. Hier wird jetzt der Zeiger nach der Uhr gestellt. 
 Zunächst wird die vergangene Zeit gemessen, dann die Anzahl der Schritte berechnet, und diese dann ausgeführt. 
 */
void doSteps() {
  if (millis() < nexttime) {
 
    unsigned long misTime = nexttime - millis();
    unsigned long missingSteps = (misTime * Su) / 60000 ;  
    word offset = steps - missingSteps;
 
    // Wenn's was zutun gibt, dann die Uhr jetzt stellen
    if (offset > 0) {
      SteppStepper(offset, SM_DIRECTION);
    }
 
    steps -= offset;
    done += offset;
 
    dbgOut("su: ");  
    dbgOut(Su);  
    dbgOut("m: ");  
    dbgOut(misTime / 1000);  
    dbgOut(", o: ");  
    dbgOut(offset);  
    dbgOut(", d: ");  
    dbgOut(done);  
    dbgOut(", m: ");  
    dbgOutLn(missingSteps);  
  }
}
 
/*
Schrittmotor um die Anzahl an Schritte laufen lassen.
@param steps 
          Anzahl der Schritte
@param: forward 
          vorwärts oder rückwärts
 */
void SteppStepper(byte steps, boolean forward) {
  digitalWrite(SM_DIR, forward);
  while (steps > 0) {
    digitalWrite(SM_STEP, HIGH);
    delay(20);
    digitalWrite(SM_STEP, LOW);
    steps -= 1;
    if (steps > 0) {
      //delay(Ph-50);
      delay(Ph);
    }
  }
}
 
/*
Starten des Schrittmotortreibers
 */
void startStepper() {
  dbgOutLn("start stepper");
  lastStepUsed = getTime();
  // Wenn ausgeschaltet, 
  if (digitalRead(SM_SLEEP) == 0) {
    // einschalten 
    digitalWrite(SM_SLEEP, HIGH);
    // und auf null stellen
    calibStepper();
  }
  //digitalWrite(SM_SLEEP, HIGH);
}
 
/*
Uhr zurück laufen lassen, bis die Lichtschranke anspricht. Dann 1 Sekunde warten.
 */
void  calibStepper() {
  dbgOutLn("calib stepper");  
  byte smSwitch = digitalRead(SM_SWITCH); 
  while (smSwitch == 1) {
    SteppStepper(1, !SM_DIRECTION);
    delay(Ph);
    smSwitch = digitalRead(SM_SWITCH); 
  }  
  delay(1000);
}
 
/*
Systemtest ausführen.
*/
void testSystem() {
  dbgOutLn("Testing clock");
 
  dbgOut("Su: ");  
  dbgOutLn(Su);
  dbgOut("Ph:");
  dbgOutLn(Ph);  
 
  testLED();  
 
  testBeep();
 
  testStepper();
 
  testRC();
 
  delay(500);
 
}
 
/*
Schrittmotor testen.
*/
void testStepper() {
  dbgOutLn("Step Test");
  dbgOutLn("wakeup");
  digitalWrite(SM_SLEEP, HIGH);
 
  dbgOutLn("100 for");
  SteppStepper(100, true);
 
  delay(500);
  dbgOutLn("100 back");
  SteppStepper(100, false);
 
  delay(2000);
 
  dbgOutLn("test NP");
  int i = 0;
 
  byte smSwitch = digitalRead(SM_SWITCH); 
  while (smSwitch == 1) {
    SteppStepper(1, !SM_DIRECTION);
    delay(Ph);
    smSwitch = digitalRead(SM_SWITCH); 
  }  
 
  delay(500);
  dbgOutLn("100 back");
  SteppStepper(100, false);
 
  smSwitch = digitalRead(SM_SWITCH); 
  while (smSwitch == 1) {
    SteppStepper(1, !SM_DIRECTION);
    delay(Ph);
    smSwitch = digitalRead(SM_SWITCH); 
  }  
 
  SteppStepper(50,true);
 
  dbgOutLn("sleep");
  digitalWrite(SM_SLEEP, LOW);
}
 
/*
RC Verbindung testen.
*/
void testRC() {
  dbgOutLn("RC Test");
 
  tone(BEEP_PIN, BEEP_HZ, 100);
  delay(200);
 
  tone(BEEP_PIN, BEEP_HZ, 100);
  delay(100);
 
  digitalWrite(LED_W1, LOW);
  digitalWrite(LED_W2, LOW);
  digitalWrite(LED_Y3, LOW);
 
  int i = 0;
  while ( i < 10) {
 
    digitalWrite(LED_BOARD, HIGH);   // set the LED on
    int RcValue = rcReceiver.getValue();
 
    if (rcReceiver.hasError()) {
      dbgOutLn("kein RC");
      delay(100);
      digitalWrite(LED_BOARD, LOW);    // set the LED off
      delay(900);              // wait for a second
    } 
    else if (RcValue < ResetRCValue) {
      dbgOutLn("Reset RC");
      delay(500);
      digitalWrite(LED_Y3, HIGH);
      digitalWrite(LED_BOARD, LOW);    // set the LED off
      delay(500);              // wait for a second
    } 
    else if (RcValue < StartRCValue) {
      dbgOutLn("RC Null");
      delay(500);
      digitalWrite(LED_W1, HIGH);
      digitalWrite(LED_BOARD, LOW);    // set the LED off
      delay(500);              // wait for a second
    } 
    else if (RcValue > StartRCValue) {
      dbgOutLn("RC Start");
      delay(500);
      digitalWrite(LED_W2, HIGH);
      digitalWrite(LED_BOARD, LOW);    // set the LED off
      delay(500);              // wait for a second
    }
    digitalWrite(LED_BOARD, LOW);    // set the LED off
    digitalWrite(LED_W1, LOW);
    digitalWrite(LED_W2, LOW);
    digitalWrite(LED_Y3, LOW);
    i++;
  }
}
 
void testLED() {
  dbgOutLn("LED Test");
  dbgOutLn("LED W1");
  digitalWrite(LED_W1, HIGH);
  delay(250);
  digitalWrite(LED_W1, LOW);
  delay(500);
 
  dbgOutLn("LED W2");
  digitalWrite(LED_W2, HIGH);
  delay(250);
  digitalWrite(LED_W2, LOW);
  delay(500);
 
  dbgOutLn("LED Y3");
  digitalWrite(LED_Y3, HIGH);
  delay(250);
  digitalWrite(LED_Y3, LOW);
  delay(500);
 
  dbgOutLn("LED G4");
  digitalWrite(LED_G4, HIGH);
  delay(250);
  digitalWrite(LED_G4, LOW);
  delay(500);
 
  dbgOutLn("LED G5");
  digitalWrite(LED_G5, HIGH);
  delay(250);
  digitalWrite(LED_G5, LOW);
 
  clockReset();
}
 
void testBeep() {
  dbgOutLn("Beep Test");
  dbgOutLn("long");
  longbeep();
  delay(1200);  
  dbgOutLn("beep");
  beep(); 
  delay(500);
  dbgOutLn("Beep Test ready");
}