einfach mal so runtergeschrieben:
// Schachuhr
// https://forum.arduino.cc/t/millis-timer-pausieren-und-wieder-starten/855936
// by noiasca
// 2021-05-01
int8_t activeTimer = -1; // which timer is currently active
struct Timer {
const byte buttonPin; // pin to GND starts timer
uint32_t previousMillis; // last active millis of this timer
uint32_t millis; // millis
};
Timer timer[] {
{A0, 0, 0}, // buttonPin, previousMillis, millis
{A1, 0, 0},
};
const byte noOfTimer = sizeof(timer) / sizeof(timer[0]); // calculate number of timers
void setup() {
Serial.begin(115200);
Serial.println(F("Schachuhr"));
for (auto &i : timer)
pinMode(i.buttonPin, INPUT_PULLUP);
}
void loop() {
// read button
for (size_t i = 0; i < noOfTimer; i++)
{
if (digitalRead(timer[i].buttonPin) == LOW && activeTimer != (int8_t)i) activateTimer(i); // if different button, activate timer
}
// output
updateSerial();
}
void activateTimer(byte i) // sets timer i to active
{
timer[i].previousMillis = millis();
Serial.print(F("Button pressed ")); Serial.println(i);
activeTimer = i;
}
uint32_t getMillis(byte i) // returns the accumulated millis of one timer
{
if (activeTimer == i) // update millis before return
{
uint32_t currentMillis = millis();
timer[i].millis += currentMillis - timer[i].previousMillis; // add passed time to old millis
timer[i].previousMillis = currentMillis; // remember the timestamp of the last millis update
}
return timer[i].millis;
}
void updateSerial() // demo output to serial
{
static uint32_t previousMillis = 0;
uint32_t currentMillis = millis();
if (millis() - previousMillis > 500)
{
for (size_t i = 0; i < noOfTimer; i++)
{
Serial.print(F("Timer")); Serial.print(i); Serial.print(" "); Serial.print(getMillis(i)); Serial.print("\t");
}
Serial.print(F(" active=")); Serial.println(activeTimer);
previousMillis = currentMillis;
}
}
mit getMillis(i) bekommt man die jeweiligen millis retour.
ergibt:
10:44:15.334 -> Timer0 0 Timer1 0 active=-1
10:44:15.836 -> Timer0 0 Timer1 0 active=-1
10:44:16.338 -> Timer0 0 Timer1 0 active=-1
10:44:16.825 -> Timer0 0 Timer1 0 active=-1
10:44:17.142 -> Button pressed 0
10:44:17.342 -> Timer0 200 Timer1 0 active=0
10:44:17.844 -> Timer0 701 Timer1 0 active=0
10:44:18.300 -> Timer0 1202 Timer1 0 active=0
10:44:18.802 -> Timer0 1703 Timer1 0 active=0
10:44:19.304 -> Timer0 2204 Timer1 0 active=0
10:44:19.806 -> Timer0 2705 Timer1 0 active=0
10:44:20.308 -> Timer0 3206 Timer1 0 active=0
10:44:20.826 -> Timer0 3707 Timer1 0 active=0
10:44:21.312 -> Timer0 4208 Timer1 0 active=0
10:44:21.761 -> Button pressed 1
10:44:21.815 -> Timer0 4208 Timer1 46 active=1
10:44:22.317 -> Timer0 4208 Timer1 547 active=1
10:44:22.834 -> Timer0 4208 Timer1 1048 active=1
10:44:23.321 -> Timer0 4208 Timer1 1549 active=1
10:44:23.824 -> Timer0 4208 Timer1 2050 active=1
10:44:24.327 -> Timer0 4208 Timer1 2551 active=1
10:44:24.829 -> Timer0 4208 Timer1 3052 active=1
10:44:25.331 -> Timer0 4208 Timer1 3553 active=1
10:44:25.833 -> Timer0 4208 Timer1 4054 active=1
10:44:26.334 -> Timer0 4208 Timer1 4555 active=1
10:44:26.784 -> Button pressed 0
10:44:26.837 -> Timer0 4244 Timer1 4555 active=0
10:44:27.339 -> Timer0 4745 Timer1 4555 active=0
10:44:27.852 -> Timer0 5246 Timer1 4555 active=0
edit:
damit man nicht in Versuchung gerät, die Variablen direkt anzusprechen, mal die Timer als Objekte:
// Schachuhr OOP
// https://forum.arduino.cc/t/millis-timer-pausieren-und-wieder-starten/855936
// by noiasca
// 2021-05-01
int8_t activeTimer = -1; // stores the active Timer ID
class Timer {
protected:
const byte buttonPin; // pin to GND starts timer
uint32_t previousMillis = 0; // last active millis of this timer
uint32_t _millis = 0; // millis
const byte id; // give each object an ID
static byte total; // keep track of the number of timer objects
public:
Timer (byte buttonPin): buttonPin(buttonPin), id (total++)
{}
void begin()
{
pinMode(buttonPin, INPUT_PULLUP);
}
void read() // read button and if different button, activate timer
{
if (digitalRead(buttonPin) == LOW && activeTimer != id) activateTimer();
}
void activateTimer() // sets timer i to active
{
previousMillis = millis();
Serial.print(F("Button pressed ")); Serial.println(id);
activeTimer = id;
}
uint32_t getMillis() // returns the accumulated millis of one timer
{
if (activeTimer == id) // update millis before return
{
uint32_t currentMillis = millis();
_millis += currentMillis - previousMillis; // add passed time to old millis
previousMillis = currentMillis; // remember the timestamp of the last millis update
}
return _millis;
}
byte getId()
{
return id;
}
};
byte Timer::total=0; // declare inside class, but define outside = 0 (leave it 0!)
Timer timer[] {
{A0}, // buttonPin
{A1}
};
void setup() {
Serial.begin(115200);
Serial.println(F("Schachuhr"));
for (auto &i : timer) i.begin();
}
void loop() {
// read button
for (auto &i : timer)
i.read();
// output
updateSerial();
}
void updateSerial() // demo output to serial
{
static uint32_t previousMillis = 0;
uint32_t currentMillis = millis();
if (millis() - previousMillis > 500)
{
for (auto &i : timer)
{
Serial.print(F("Timer")); Serial.print(i.getId()); Serial.print(" "); Serial.print(i.getMillis()); Serial.print("\t");
}
Serial.print(F(" active=")); Serial.println(activeTimer);
previousMillis = currentMillis;
}
}