kub-kar-timer/src/main.cpp

154 lines
3.3 KiB
C++
Raw Normal View History

2016-02-12 00:47:57 +00:00
/*
* Blink
* Turns on an LED on for one second,
* then off for one second, repeatedly.
*/
#include "Arduino.h"
2016-02-12 01:37:26 +00:00
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
2016-02-12 01:44:25 +00:00
#define PIN_RESET 2
#define PIN_CAR1 3
2016-02-13 20:20:39 +00:00
#define PIN_LED LED_BUILTIN
2016-02-12 00:47:57 +00:00
2016-02-12 02:02:19 +00:00
typedef struct {
2016-02-12 02:12:45 +00:00
// input pin for this car
2016-02-12 02:02:19 +00:00
short pin;
2016-02-12 02:12:45 +00:00
// elapsed time for pin (0 means not finished)
2016-02-12 02:02:19 +00:00
unsigned int elapsedTime;
2016-02-12 02:12:45 +00:00
} Car;
2016-02-12 02:02:19 +00:00
2016-02-12 02:12:45 +00:00
// assume all cars are on sequential digital pins
2016-02-12 02:02:19 +00:00
#define PIN_CAR_STARTING 3
2016-02-12 02:12:45 +00:00
// number of cars (4 max)
2016-02-13 20:20:39 +00:00
#define CAR_COUNT 2
2016-02-12 02:12:45 +00:00
// array of cars
Car cars[CAR_COUNT];
2016-02-12 02:02:19 +00:00
// buffer for the LCD line
char buffer[40];
2016-02-12 00:47:57 +00:00
void setup()
{
2016-02-12 01:44:25 +00:00
2016-02-12 01:37:26 +00:00
Serial.begin(9600);
2016-02-12 01:44:25 +00:00
pinMode(PIN_RESET, INPUT_PULLUP);
2016-02-12 00:47:57 +00:00
pinMode(LED_BUILTIN, OUTPUT);
2016-02-12 01:44:25 +00:00
2016-02-12 02:02:19 +00:00
// initialize each car PIN
for(short i=0; i<CAR_COUNT; i++) {
cars[i].pin = PIN_CAR_STARTING + i;
pinMode(cars[i].pin, INPUT_PULLUP);
}
2016-02-12 02:12:45 +00:00
// initialize LCD
2016-02-12 01:49:25 +00:00
lcd.begin(20, 4);
2016-02-12 01:37:26 +00:00
lcd.backlight();
2016-02-12 02:21:28 +00:00
lcd.setCursor(1,1);
lcd.print("Jeff's Inept");
lcd.setCursor(6,2);
lcd.print("Kub Kar Timer");
2016-02-12 00:47:57 +00:00
}
2016-02-12 02:12:45 +00:00
void resetCars() {
2016-02-12 02:02:19 +00:00
for(short i=0; i<CAR_COUNT; i++) {
cars[i].elapsedTime = 0;
}
}
2016-02-12 01:37:26 +00:00
2016-02-12 02:02:19 +00:00
void displayTimers() {
2016-02-13 20:20:39 +00:00
short row = 0;
2016-02-12 02:02:19 +00:00
lcd.clear();
2016-02-13 20:20:39 +00:00
// keep track of cars that we've already printed a score for
bool seenCar[CAR_COUNT];
for (int i=0; i<CAR_COUNT; i++) {
seenCar[i] = false;
}
for(short place=0; place<CAR_COUNT; place++) {
// find which is the fastest car that hasn't already been processed
short currentCar = -1;
for (short i=0; i<CAR_COUNT; i++) {
if (!seenCar[i] && cars[i].elapsedTime != 0 && (currentCar == -1 || cars[i].elapsedTime < cars[currentCar].elapsedTime)) {
currentCar = i;
}
}
// mark car as seen so we don't show the same car again
seenCar[currentCar] = true;
if (cars[currentCar].elapsedTime != 0) {
// only print the score if this car finished
lcd.setCursor(0,row++);
sprintf(buffer, "%d%s: CAR%d @ %0.2fs", place+1, place==0?"st":(place==1?"nd":(place==2?"rd":"th")) , currentCar+1, cars[currentCar].elapsedTime/1000.0);
lcd.print(buffer);
2016-02-12 02:12:45 +00:00
}
2016-02-12 02:02:19 +00:00
}
}
2016-02-12 01:37:26 +00:00
2016-02-13 20:20:39 +00:00
#define MAX_TIME 5000
2016-02-12 02:12:45 +00:00
2016-02-12 05:26:21 +00:00
unsigned long startTime; // start time in ms
2016-02-12 01:44:25 +00:00
2016-02-12 02:03:42 +00:00
#define STATE_READY 1
#define STATE_RUNNING 2
#define STATE_DONE 3
short state = 0;
2016-02-12 00:47:57 +00:00
void loop()
{
2016-02-12 02:18:19 +00:00
2016-02-12 01:44:25 +00:00
if (digitalRead(PIN_RESET) == LOW) {
2016-02-12 02:03:42 +00:00
if (state != STATE_READY) {
state = STATE_READY;
lcd.clear();
lcd.setCursor(0,0);
2016-02-12 02:18:19 +00:00
lcd.print("Ready...");
2016-02-12 02:12:45 +00:00
resetCars();
2016-02-13 20:20:39 +00:00
digitalWrite(PIN_LED, HIGH);
2016-02-12 02:03:42 +00:00
}
2016-02-12 01:44:25 +00:00
} else {
2016-02-12 02:12:45 +00:00
if (state == STATE_READY) {
2016-02-13 20:20:39 +00:00
digitalWrite(PIN_LED, LOW);
2016-02-12 02:12:45 +00:00
state = STATE_RUNNING;
lcd.setCursor(0,0);
lcd.print("Running!");
2016-02-12 05:26:21 +00:00
startTime = millis();
2016-02-12 01:44:25 +00:00
}
2016-02-12 02:12:45 +00:00
if (state == STATE_RUNNING) {
// calculate elapsed time in ms
2016-02-12 05:26:21 +00:00
unsigned long elapsedTime = millis() - startTime;
2016-02-12 02:12:45 +00:00
bool allDone = true;
for(short i = 0; i<CAR_COUNT; i++) {
2016-02-12 02:18:19 +00:00
if (cars[i].elapsedTime == 0) {
2016-02-12 02:12:45 +00:00
if (digitalRead(cars[i].pin) == LOW) {
// car finished, record time
cars[i].elapsedTime = elapsedTime;
} else {
allDone = false;
}
2016-02-12 02:02:19 +00:00
}
}
2016-02-12 01:44:25 +00:00
2016-02-12 02:12:45 +00:00
// stop race if all cars are done or MAX TIME exceeded
if (allDone || elapsedTime > MAX_TIME) {
state = STATE_DONE;
displayTimers();
}
2016-02-12 01:44:25 +00:00
}
2016-02-12 01:37:26 +00:00
}
2016-02-12 01:44:25 +00:00
2016-02-12 00:47:57 +00:00
}