| 140 | } |
| 141 | |
| 142 | void Timer::loop() { |
| 143 | unsigned long startMillis = millis(); |
| 144 | unsigned long lastUpdateMillis = 0; |
| 145 | |
| 146 | int lastSeconds = -1; // Track last displayed value to avoid unnecessary redraws |
| 147 | char timeString[12]; |
| 148 | |
| 149 | tft.fillScreen(bruceConfig.bgColor); |
| 150 | |
| 151 | // Countdown loop |
| 152 | while (true) { |
| 153 | unsigned long currentMillis = millis(); |
| 154 | |
| 155 | // Calculate elapsed time (handles millis() overflow correctly) |
| 156 | unsigned long elapsedMillis = currentMillis - startMillis; |
| 157 | |
| 158 | // Check for ESC/BACK button - exit timer |
| 159 | if (check(EscPress)) { break; } |
| 160 | |
| 161 | // Check if timer has completed |
| 162 | if (elapsedMillis >= duration) { |
| 163 | // Play alarm pattern only if enabled |
| 164 | if (playSoundOnFinish) { playAlarmPattern(); } |
| 165 | break; |
| 166 | } |
| 167 | |
| 168 | // Update display only once per second to reduce flicker and CPU usage |
| 169 | if (currentMillis - lastUpdateMillis >= DISPLAY_UPDATE_INTERVAL) { |
| 170 | unsigned long remainingMillis = duration - elapsedMillis; |
| 171 | |
| 172 | int seconds = (remainingMillis / 1000) % 60; |
| 173 | int minutes = (remainingMillis / 60000) % 60; |
| 174 | int hours = (remainingMillis / 3600000) % 100; |
| 175 | |
| 176 | // Only redraw if the seconds value changed |
| 177 | if (seconds != lastSeconds) { |
| 178 | snprintf(timeString, sizeof(timeString), "%02d:%02d:%02d", hours, minutes, seconds); |
| 179 | |
| 180 | // Calculate optimal font size based on display width |
| 181 | uint8_t f_size = 4; |
| 182 | for (uint8_t i = 4; i > 0; i--) { |
| 183 | if (i * LW * 8 < (tftWidth - BORDER_PAD_X * 2)) { |
| 184 | f_size = i; |
| 185 | break; |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | drawMainBorder(false); |
| 190 | tft.setTextSize(f_size); |
| 191 | tft.setTextColor(bruceConfig.priColor, bruceConfig.bgColor); |
| 192 | tft.drawCentreString(timeString, timerX, timerY, 1); |
| 193 | |
| 194 | lastSeconds = seconds; |
| 195 | } |
| 196 | |
| 197 | lastUpdateMillis = currentMillis; |
| 198 | } |
| 199 |
no test coverage detected