I have a serious. SERIOUS problem. I have this code:
/*
CHANGELOG
1.3.18
Fixed button debounce.
1.3.19
Added hours.
1.3.20
Because of hard time doing proper hour-minute-second-us measurement, hours were removed. Also, the display is blinking, when it's paused.
1.3.20.1
Quick fix, display stayed off if you reset the stopwatch while it's blinking, now it does not.
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Пины RS, E, D4, D5, D6, D7
const int startStopButtonPin = 8; // Пин кнопки старта/стопа
const int resetButtonPin = 7; // Пин кнопки сброса
enum State { STOPPED, RUNNING, PAUSED };
State state = STOPPED;
unsigned long long startTime = 0;
unsigned long long elapsedTime = 0;
unsigned long long totalElapsedTime = 0;
unsigned long long previousElapsedTime = 0;
unsigned long long lastBlinkTime = 0;
bool displayOn = true;
bool buttonPressed = false;
// Function declaration
void updateDisplay();
void setup() {
lcd.begin(16, 2);
Serial.begin(9600);
pinMode(startStopButtonPin, INPUT_PULLUP);
pinMode(resetButtonPin, INPUT_PULLUP);
// Выводим верхнюю строку один раз при запуске
lcd.setCursor(0, 0);
lcd.blink();
animateText("v1.4 Stable", 50);
lcd.setCursor(0, 1);
animateText("[ ]0%", 15);
lcd.setCursor(0,1);
animateText("[# ]13%", 15);
lcd.setCursor(0, 1);
animateText("[### ]36%", 15);
lcd.setCursor(0, 1);
animateText("[###### ]62%", 15);
lcd.setCursor(0, 1);
animateText("[######### ]99%", 15);
lcd.setCursor(0, 1);
animateText("[##########]100%", 15);
lcd.setCursor(0,1);
lcd.setCursor(0,0);
animateText("START/STOP-GREEN", 25);
lcd.setCursor(0, 1);
animateText("RESET-RED ", 25);
lcd.setCursor(15,1);
delay(5000);
lcd.setCursor(0,0);
animateText(" ", 25);
lcd.setCursor(0, 1);
animateText(" ", 25);
lcd.clear();
lcd.setCursor(0,0);
animateText("m:ss.us", 25);
delay(10);
}
void animateText(const char* text, int delayTime) {
int len = strlen(text);
for (int i = 0; i < len; ++i) {
lcd.print(text[i]);
delay(delayTime);
}
delay(500); // Задержка после завершения анимации
}
void loop() {
if (digitalRead(startStopButtonPin) == LOW) {
delay(10); // Антидребезг
buttonPressed = true;
} else {
if (buttonPressed) {
handleButtonPress();
buttonPressed = false;
}
}
if (digitalRead(resetButtonPin) == LOW) {
delay(10); // Антидребезг
resetStopwatch();
}
if (state == RUNNING) {
elapsedTime = micros() - startTime;
// Проверка изменения значения перед обновлением экрана
if (elapsedTime != previousElapsedTime) {
updateDisplay();
previousElapsedTime = elapsedTime;
}
}
// Мигание экрана при остановленном секундомере
if (state == PAUSED && millis() - lastBlinkTime >= 500) {
lastBlinkTime = millis();
displayOn = !displayOn;
if (displayOn) {
lcd.display(); // Включаем экран
} else {
lcd.noDisplay(); // Выключаем экран
}
}
}
void handleButtonPress() {
switch (state) {
case STOPPED:
startStopwatch();
break;
case RUNNING:
pauseStopwatch();
break;
case PAUSED:
resumeStopwatch();
break;
}
}
void startStopwatch() {
state = RUNNING;
startTime = micros();
lcd.display(); // Включаем экран при запуске
}
void pauseStopwatch() {
state = PAUSED;
totalElapsedTime += elapsedTime; // Накопление времени перед паузой
lcd.display(); // Включаем экран при паузе
}
void resumeStopwatch() {
state = RUNNING;
startTime = micros();
lcd.display(); // Включаем экран при продолжении
}
void resetStopwatch() {
state = STOPPED;
startTime = 0;
elapsedTime = 0;
totalElapsedTime = 0;
previousElapsedTime = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.blink();
lcd.display();
lcd.print("m:ss.us");
}
void updateDisplay() {
// Не перерисовываем верхнюю строку, если секундомер работает
if (state == PAUSED) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.blink();
lcd.print("m:ss.us");
}
unsigned long long minutes = (totalElapsedTime + elapsedTime) / 60000000ULL;
unsigned long long seconds = ((totalElapsedTime + elapsedTime) / 1000000ULL) % 60;
unsigned long long microseconds = ((totalElapsedTime + elapsedTime) % 1000000ULL) / 1;
// Вывод времени с ведущими нулями
// Вывод времени с ведущими нулями
lcd.setCursor(0, 1);
lcd.print(static_cast<unsigned long>(minutes)); // Явное приведение к unsigned long
lcd.print(":");
if (seconds < 10) lcd.print("0");
lcd.print(static_cast<unsigned long>(seconds)); // Явное приведение к unsigned long
lcd.print(".");
if (microseconds < 10) lcd.print("0");
lcd.print(static_cast<unsigned long>(microseconds)); // Явное приведение к unsigned long
}
And i have a prob with the micros() counter overflow. I need to fix this thing. I would like to change this globally in the Arduino's code. I know that micros is a
unsigned long micros(void)
thing. I would like to make it 64-bit (unsigned long long), so it doesn't reset every ~70 minutes. I am making a decently accurate stopwatch, which shouldn't go to all 0 after just above 1 hour of work. If you can give me a fix in this code - go ahead, but changes to Arduino's core lib (or whatever it's called) so i won't have to worry about doing this again will be more appreciated. Thank you. ![]()