//#include <TLC591x.h>
//#include <OneButton.h>
#include <TM1637.h>
//#define Segments 5
const int CLK = 10;
const int DIO = 11;
TM1637 tm(CLK, DIO);
#define Segments 5
#define RELAY_PIN 2
#define MODE_PIN 3
#define COUNTER_DELAY_3S 3000000 //delay in us for regular ride
#define COUNTER_DELAY_2S 2000000 //delay in us for rotations training
#define COUNTER_DELAY_1S 1000000
#define DIMM_DELAY 30000 //dimm delay in miliseconds
#define CONTINUOUS_DISPLAY 2000 //contunuous mode display interval in ms
#define VCC_READ_DELAY 10000 //VCC read interval
#define LED_DIMMED_LEVEL 110
#define LED_NORMAL_LEVEL 0
#define BATT_LOW_LEVEL 2900
//unsigned long intervalStart = 0;
//unsigned long intervalEnd = 1;
unsigned long timeDim = 0;
unsigned long timeDimPrev = 0;
bool ledNormal = true;
bool battLow = false;
unsigned long timeVCC = 0;
unsigned long timeVCCPrev = 0;
//TLC591x myLED(1, 11, 13, 10); // OE pin hard-wired low (always enabled)
//TLC591x myLED(Segments, 10); //hardware
//TLC591x myLED(Segments, 10, MODE_PIN); //hardware
uint8_t displayArray[Segments];
int ledSegments[] = {125, 48, 91, 122, 54, 110, 111, 56, 127, 126};
int ledDot = 128; //code for displaying dot
unsigned long timePoint = 0;
unsigned long timePointPrev = 0;
unsigned long totalTime = 0;
bool timerPause = false; //short pause to display time
bool timerRun = false; //true- time counting, false- stopped
bool timerMode = true; //true - start/stop mode; false - continuous mode
void setup() {
Serial.begin(9600);
pinMode(RELAY_PIN, INPUT_PULLUP);
pinMode(MODE_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(RELAY_PIN), relayOn, FALLING);
tm.init();
tm.set(BRIGHT_TYPICAL);
}
void loop() {
//timerMode = modeSwitch(MODE_PIN);
if (debounce()) {
timerMode = !timerMode;
}
Serial.println(timerMode);
//timerMode = false;
if (timePoint - timePointPrev > COUNTER_DELAY_2S) {
totalTime = timePoint - timePointPrev;
timePointPrev = timePoint;
timerRun = !timerRun; //start/stop status switch
timerPause = true; //continuous run status switch to temporary show time
tm.set(BRIGHT_TYPICAL);
timeDimPrev = timeDim;
}
//Serial.print(timerPause);
switch (timerMode) {
case true:
if (timerRun) showTime(micros() - timePointPrev);
if (!timerRun) showTime(totalTime);
break;
case false:
nonBlockDelay(timerPause, CONTINUOUS_DISPLAY);
if (timerPause) {
showTime(totalTime);
} else {
showTime(micros() - timePointPrev);
}
break;
}
timeDim = millis();
if (timeDim - timeDimPrev > DIMM_DELAY) {
tm.set(LOW);
}
delay(15);
}
void relayOn() {
//grab time point when relay is ON
timePoint = micros();
}
void nonBlockDelay(bool &timerPause, unsigned long delayDuration) {
static unsigned long now = 0;
if (!timerPause) {
now = millis();
}
if ((millis() - now >= delayDuration)) {
timerPause = false;
}
}
bool debounce() {
static uint16_t state = 0;
state = (state<<1) | digitalRead(MODE_PIN) | 0xfe00;
return (state == 0xff00);
}
bool modeSwitch(const int buttonPin) {
static int lastButtonState = HIGH; // the previous reading from the input pin
static int buttonState = HIGH;
static unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 20;
static bool flipState = true;
static int reading;
reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (buttonState == HIGH && lastButtonState == LOW) {
flipState = !flipState;
}
buttonState = reading;
}
lastButtonState = reading;
return flipState;
}
void showTime(unsigned long counter) {
tm.display(0, (counter / 10000000) % 10);
tm.display(1, (counter / 1000000) % 10);
tm.display(2, (counter / 100000) % 10);
tm.display(3, (counter / 10000) % 10);
}