Measuring CO₂
static uint32_t timer0 = 0;
static uint32_t timer1 = 0;
TIMER(timer0, 5000)
{
timer0 = millis();
PRINT_DEBUG(F("Measured CO2 "));
TIMER(timer1, GRAPH_UPDATE_TIME)
{
timer1 = millis();
globalVars.freshPPM++;
if(globalVars.freshPPM == WIDTH) globalVars.freshPPM = 0;
PRINT_DEBUG(F("and shifted array "));
}
globalVars.ppm[globalVars.freshPPM] = co2.getPPM();
if(globalVars.ppm[globalVars.freshPPM] > globalVars.maxPPM) globalVars.maxPPM = globalVars.ppm[globalVars.freshPPM];
if(globalVars.ppm[globalVars.freshPPM] < globalVars.minPPM) globalVars.minPPM = globalVars.ppm[globalVars.freshPPM];
PRINTLN_DEBUG(globalVars.ppm[globalVars.freshPPM]);
}
Reads PPM and writes it into the global array. To save time, it don't shifts array, but increments element counter that points to the fresh ppm value.
Notifications
static uint32_t timer2 = 0;
static uint8_t ppmFlag = false;
if(globalVars.ppm[globalVars.freshPPM] <= globalVars.maxPPM - CO2WINDOW) ppmFlag = true;
if(ppmFlag && (globalVars.ppm[globalVars.freshPPM] > globalVars.maxPPM - CO2WINDOW)) TIMER(timer2, HIGH_PPM_TIMEOUT)
{
globalVars.longBeep = true;
PRINTLN_DEBUG(F("Notified"));
}
Asks for a long beep.
Update time from RTC
static uint32_t timer3 = 0;
static DateTime DTtmp;
TIMER(timer3, 999)
{
PRINT_DEBUG(F("Time updated "));
DTtmp = rtc.getTime();
globalVars.hours = DTtmp.hour % TIME_FORMAT;
#if(OVERFLOW_WITHOUT_ZERO)
if(globalVars.hours == 0)
globalVars.hours = TIME_FORMAT;
#endif
globalVars.minutes = DTtmp.minute;
if(globalVars.seconds != DTtmp.second)
timer3 = millis();
globalVars.seconds = DTtmp.second;
PRINTLN_DEBUG(F("succesfuly"));
}
Every last millisecond it continuously updates time every cycle pass until seconds
variable changes. Also formats it to the defined time format.
Swipe panel poll
static uint32_t timer4 = 0;
TIMER(timer4, 10)
{
timer4 = millis();
PRINTLN_DEBUG(F("Buttons readed"));
buttons(0);
}
This timer call if spaghetti function. I'll be glad if someone will help me with tidying it. Function detects the event and writes it to the global variables. Screens have to null every event's boolean after reading (or rendering to ignore input).
Pomodoro
if(globalVars.pomodoroRunning) TIMER(globalVars.pomodoroTimer, 1000)
{
globalVars.pomodoroTimer = millis();
PRINT_DEBUG(F("Updated pomodoro "));
PRINT_DEBUG(globalVars.pomodoroMinutes);
PRINT_DEBUG(F(" "));
PRINT_DEBUG(globalVars.pomodoroSeconds);
if(globalVars.pomodoroSeconds == 0)
{
if(globalVars.pomodoroMinutes == 0)
{
globalVars.pomodoroState = !globalVars.pomodoroState;
globalVars.pomodoroMinutes = globalVars.pomodoroState ? globalVars.pomodoroSavedBreak : globalVars.pomodoroSavedWork;
globalVars.pomodoroSeconds = 0;
globalVars.shortBeep = true;
}
else
{
globalVars.pomodoroMinutes--;
globalVars.pomodoroSeconds = 59;
}
}
else globalVars.pomodoroSeconds--;
PRINT_DEBUG(F(" to "));
PRINT_DEBUG(globalVars.pomodoroMinutes);
PRINT_DEBUG(F(" "));
PRINTLN_DEBUG(globalVars.pomodoroSeconds);
}
Updates pomodoro timer every second and changes work/break states. Not depends on RTC.
Render
switch(globalVars.prepare)
{
case 1:
PRINTLN_DEBUG(F("Prepared"));
screens[globalVars.currentScreen].funcPrepare();
case 2:
PRINTLN_DEBUG(F("Animated"));
animate(50);
break;
case 0:
PRINT_DEBUG(F("Screen "));
PRINT_DEBUG(globalVars.currentScreen);
PRINT_DEBUG(F(" state "));
PRINT_DEBUG(globalVars.currentState);
screens[globalVars.currentScreen].func(&screens[globalVars.currentScreen].arg);
break;
}
matrix.show();
Calls current screen's function and updates display. Calls animate
in the transition. Currently there are no enough memory to store two matrix buffers, so animate
function just nulls prepare
.
millis()
reset
TIMER(0, 3456000000)
{
PRINTLN_DEBUG(F("Timers reset"));
noInterrupts();
timer0_millis = 0;
timer0_overflow_count = 0;
interrupts();
globalVars.timer = 0;
globalVars.pomodoroTimer = 0;
tb.resetTimers();
timer_debug0 = 0;
timer0 = 0;
timer1 = 0;
timer2 = 0;
timer3 = 0;
timer4 = 0;
buttons(1);
}
Classical timer realization implies that millis() always greater than last memorized time. But system timer0_millis
is not infinite, it nulls after UINT32_MAX, which means it will work 1 month 19 days 17 hours 2 minutes 47 seconds 295 milliseconds. This timer resets all timers every month.