#include "Pomodoro.h"
|
|
#include "Timer.h"
|
|
#include "SegmentDisplay.h"
|
|
#include "SegmentCharacter.h"
|
|
#include "NTPSynchronisation.h"
|
|
#include <Arduino.h>
|
|
|
|
#define serialSpeed 115200
|
|
|
|
uint32_t isrCount=0;
|
|
uint32_t isrTime=0;
|
|
|
|
enum PomodoroStatus{status_work,status_shortBreak,status_longBreak,status_workAfterLongBreak};
|
|
PomodoroStatus pStatus=status_work;
|
|
uint32_t timeBeforeTransition=0;
|
|
uint32_t timeBeforeTransitionMinutes=0;
|
|
uint32_t timeBeforeTransitionSeconds=0;
|
|
|
|
enum DisplayMode{dMode_clockHourMinute,dMode_clockDayMonth,dMode_pomodoro};
|
|
DisplayMode dMode=dMode_pomodoro;
|
|
const int pinDisplayMode=4;
|
|
uint32_t debounceTime=0;
|
|
const uint32_t debounceWait=10;
|
|
|
|
bool wifiIssue=false;
|
|
bool ntpIssue=false;
|
|
|
|
TaskHandle_t taskHandleAnnouncer;
|
|
|
|
void taskAnnouncer(void * param){
|
|
switch(pStatus){
|
|
case status_work:
|
|
displayWork(false);
|
|
break;
|
|
case status_workAfterLongBreak:
|
|
displayWork(true);
|
|
break;
|
|
case status_shortBreak:
|
|
displayShortRest();
|
|
break;
|
|
case status_longBreak:
|
|
displayLongRest();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if(taskHandleAnnouncer!=NULL){
|
|
vTaskDelete(taskHandleAnnouncer);
|
|
}
|
|
}
|
|
|
|
void startTaskAnnouncer(){
|
|
xTaskCreatePinnedToCore(taskAnnouncer,"taskAnnouncer",1024,NULL,1,&taskHandleAnnouncer,0);
|
|
}
|
|
|
|
void IRAM_ATTR displayModeInterrupt(){
|
|
if(xTaskGetTickCount()-debounceTime>debounceWait){
|
|
switch(dMode){
|
|
case dMode_clockHourMinute:
|
|
if(wifiIssue||ntpIssue){
|
|
dMode=dMode_pomodoro;
|
|
}else{
|
|
dMode=dMode_clockDayMonth;
|
|
}
|
|
break;
|
|
case dMode_clockDayMonth:
|
|
dMode=dMode_pomodoro;
|
|
break;
|
|
default:
|
|
dMode=dMode_clockHourMinute;
|
|
break;
|
|
}
|
|
debounceTime=xTaskGetTickCount();
|
|
}
|
|
}
|
|
|
|
void setup(){
|
|
Serial.begin(115200);
|
|
setupTimer();
|
|
setupPomodoro();
|
|
setupSegmentDisplay();
|
|
|
|
sDisplayDigitValue[0]=SC_H;
|
|
sDisplayDigitValue[1]=SC_E;
|
|
sDisplayDigitValue[2]=SC_L;
|
|
sDisplayDigitValue[3]=SC_O;
|
|
|
|
wifiIssue=!connectWifi(500,10);
|
|
if(!wifiIssue){
|
|
ntpIssue=!synchroniseTimeNTP(false,true,500,10);
|
|
}
|
|
|
|
pinMode(pinDisplayMode,INPUT_PULLUP);
|
|
attachInterrupt(pinDisplayMode, displayModeInterrupt, RISING);
|
|
|
|
startTaskAnnouncer();
|
|
}
|
|
|
|
void loop() {
|
|
powerSegmentDisplay();
|
|
delay(20);
|
|
if (xSemaphoreTake(timerSemaphore, 0) == pdTRUE){
|
|
isrCount=0;
|
|
isrTime=0;
|
|
|
|
// Read the interrupt count and time
|
|
portENTER_CRITICAL(&timerMux);
|
|
isrCount = isrCounter;
|
|
isrTime = lastIsrAt;
|
|
portEXIT_CRITICAL(&timerMux);
|
|
|
|
//Avoid garbage display when isrTime is bigger than the
|
|
//waiting time resulting in timeBeforeTransition overflow
|
|
if(isrTime>(timerLastValue+currentWait)){
|
|
timeBeforeTransition=0;
|
|
}else{
|
|
timeBeforeTransition=((timerLastValue+currentWait)-isrTime)/1000;
|
|
}
|
|
|
|
switch(dMode){
|
|
case dMode_clockHourMinute:
|
|
case dMode_clockDayMonth:
|
|
if(wifiIssue){
|
|
sDisplayDigitValue[0]=SC_W;
|
|
sDisplayDigitValue[1]=SC_I;
|
|
sDisplayDigitValue[2]=SC_F;
|
|
sDisplayDigitValue[3]=SC_I;
|
|
break;
|
|
}
|
|
if(ntpIssue){
|
|
sDisplayDigitValue[0]=SC_N;
|
|
sDisplayDigitValue[1]=SC_T;
|
|
sDisplayDigitValue[2]=SC_P;
|
|
sDisplayDigitValue[3]=SC_BLANK;
|
|
break;
|
|
}
|
|
getLocalTime(&timeinfo);
|
|
if(dMode==dMode_clockHourMinute){
|
|
setNumberToDisplay(timeinfo.tm_hour*100+timeinfo.tm_min);
|
|
}else{
|
|
setNumberToDisplay(timeinfo.tm_mday*100+timeinfo.tm_mon+1);
|
|
}
|
|
sDisplayDigitValue[1]=sDisplayDigitValue[1]+SC_DOT;
|
|
sDisplayDigitValue[3]=sDisplayDigitValue[3]+SC_DOT;
|
|
break;
|
|
default:
|
|
timeBeforeTransitionMinutes=timeBeforeTransition/60;
|
|
timeBeforeTransitionSeconds=timeBeforeTransition%60;
|
|
sDisplayDigitValue[0]=SC_NUMBER[timeBeforeTransitionMinutes/10];
|
|
sDisplayDigitValue[1]=SC_NUMBER[timeBeforeTransitionMinutes%10]+SC_DOT;
|
|
sDisplayDigitValue[2]=SC_NUMBER[timeBeforeTransitionSeconds/10];
|
|
sDisplayDigitValue[3]=SC_NUMBER[timeBeforeTransitionSeconds%10];
|
|
break;
|
|
}
|
|
|
|
// Pomodoro calculation
|
|
if(isrTime>=(timerLastValue+currentWait)){
|
|
timerLastValue=isrTime;
|
|
if(work){
|
|
work=false;
|
|
workDone++;
|
|
if(workDone>=workBetweenLongBreak){
|
|
currentWait=timeLongRest;
|
|
workDone=0;
|
|
//displayLongRest();
|
|
pStatus=status_longBreak;
|
|
}else{
|
|
currentWait=timeShortRest;
|
|
//displayShortRest();
|
|
pStatus=status_shortBreak;
|
|
}
|
|
}else{
|
|
currentWait=timeWork;
|
|
work=true;
|
|
if(workDone==0){
|
|
//displayWork(true);
|
|
pStatus=status_workAfterLongBreak;
|
|
}else{
|
|
//displayWork(false);
|
|
pStatus=status_work;
|
|
}
|
|
}
|
|
startTaskAnnouncer();
|
|
}
|
|
}
|
|
}
|