#include "FastLED.h"
#define NUM_LEDS_PER_STRIP 28
CRGB centis_digit[NUM_LEDS_PER_STRIP];
CRGB decis_digit[NUM_LEDS_PER_STRIP];
CRGB seconds_digit[NUM_LEDS_PER_STRIP];
CRGB decas_digit[NUM_LEDS_PER_STRIP];
// define states FSM
#define s_idle 0
#define s_idle_released 1
#define s_started 2
#define s_started_released 3
#define s_stopped 4
#define s_stopped_released 5
#define pushbutton 2 // drukknop pin 2
#define lightbarrier 19 // lichtsluit pin 19
const uint32_t digits[10] = {
// 7 segments – 4 leds per segment
// ggggffffeeeeddddccccbbbbaaaa
0b0000111111111111111111111111, // 0
0b0000000000000000111111110000, // 1
0b1111000011111111000011111111, // 2
0b1111000000001111111111111111, // 3
0b1111111100000000111111110000, // 4
0b1111111100001111111100001111, // 5
0b1111111111111111111100001111, // 6
0b0000000000000000111111111111, // 7
0b1111111111111111111111111111, // 8
0b1111111100001111111111111111 // 9
};
// global variables
byte centiseconds = 0;
byte deciseconds = 0;
byte seconds = 0;
byte decaseconds;
unsigned long previousMillis = 0;
unsigned long currentMillis;
// prototype functions
void chronmeter(void);
void showtime(byte centi, byte deci, byte sec, byte deca);
void setup() {
// one ledstrip for each digit
// data pins: pin 10, 11, 12 and 13
FastLED.addLeds<NEOPIXEL, 10>(centis_digit, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 11>(decis_digit, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 12>(seconds_digit, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 13>(decas_digit, NUM_LEDS_PER_STRIP);
Serial.begin(9600);
pinMode(pushbutton, INPUT);
pinMode(lightbarrier, INPUT);
}
void loop() {
int karakter = 0;
boolean received_char = 0;
boolean running = 0;
byte state = s_idle; // initiele toestand
Serial.println("Here we go!");
while(1) {
Serial.println (state);
switch (state)
{
case s_idle: // initiele toestand
if (!digitalRead(pushbutton)) // overgangsvoorwaarde: druknop losgelaten
{
state = s_idle_released; // Ga naar toestand s_idle_released
}
break;
case s_idle_released: // initiele toestand released
if(digitalRead(pushbutton) || (received_char && karakter == 'G')) // overgangsvoorwaarde: druknop ingedrukt OF karakter G ontvangen
{
running = 1; previousMillis = millis(); // start timer
if (received_char) received_char = 0;
Serial.write('g'); // karakter g sturen
state = s_started; // Ga naar toestand s_started
}
break;
case s_started: // start toestand
if(!digitalRead(pushbutton)) // overgangsvoorwaarde: druknop losgelaten
{
state = s_started_released; // Ga naar toestand s_started_released
}
break;
case s_started_released: // start toestand released
if(digitalRead(pushbutton) || (received_char && karakter == 'S') || digitalRead(lightbarrier) == 1 ) // overgangsvoorwaarde: druknop ingedrukt OF karakter S ontvangen OF lichsluis onderbroken
{
running = 0;
if (received_char) received_char = 0;
Serial.write('s'); // karakter s sturen
state = s_stopped; // Ga naar toestand s_stopped
}
break;
case s_stopped: // stop toestand
if (!digitalRead(pushbutton)) // overgangsvoorwaarde: druknop losgelaten
{
state = s_stopped_released; // Ga naar toestand s_stopped_released
}
break;
case s_stopped_released: // stop toestand released
if(digitalRead(pushbutton) || (received_char && karakter == 'R')) // overgangsvoorwaarde: druknop ingedrukt OF karakter R ontvangen
{
// Tijd resetten
centiseconds = 0; // hondersten
deciseconds = 0; // tienden
seconds = 0; // eenheden
decaseconds = 0; // tientallen
if (received_char) received_char = 0;
Serial.write('r'); // karakter r sturen
state = s_idle; // Ga naar toestand s_idle
}
break;
//default:
//break;
} // end of switch(state)
if(received_char && karakter == '?') // remote vraagt de huidige state van de main
{
received_char = 0;
Serial.write (state); // huidige state sturen
}
if (running) chronometer();
// display aansturen
showtime(centiseconds, deciseconds, seconds,decaseconds);
if (Serial.available() > 0) {
// read the incoming byte:
karakter = Serial.read();
received_char = 1;
}
}
}
void chronometer(void)
{
currentMillis = millis();
//If it is true, it means 1 centisecond had passed.
//Update centiseconds, deciseconds, seconds and decaseconds
if (currentMillis - previousMillis >= 10)
{
previousMillis = currentMillis;
centiseconds=centiseconds + 1;
if (centiseconds >= 10)
{
centiseconds = 0;
deciseconds = deciseconds + 1;
if (deciseconds >= 10)
{
deciseconds = 0;
seconds = seconds+1;
if (seconds >=10)
{
seconds = 0;
decaseconds = decaseconds +1 ;
if (decaseconds >= 10)
{
decaseconds = 0;
; // overflow
}
}
}
}
}
}
void showtime(byte centi, byte deci, byte sec, byte deca) {
for(int i=0;i<NUM_LEDS_PER_STRIP; i++){
if bitRead(digits[centi], i) centis_digit[i] = CRGB::Red;
else centis_digit[i] = CRGB::Black ;
}
for(int i=0;i<NUM_LEDS_PER_STRIP; i++){
if bitRead(digits[deci], i) decis_digit[i] = CRGB::Red;
else decis_digit[i] = CRGB::Black ;
}
for(int i=0;i<NUM_LEDS_PER_STRIP; i++){
if bitRead(digits[sec], i) seconds_digit[i] = CRGB::Red;
else seconds_digit[i] = CRGB::Black ;
}
for(int i=0;i<NUM_LEDS_PER_STRIP; i++){
if bitRead(digits[deca], i) decas_digit[i] = CRGB::Red;
else decas_digit[i] = CRGB::Black ;
}
FastLED.show();
// delay(100);
}