Hallo Zusammen,
ich möchte für meinen Vater eine Schachuhr mit dem Arduino Uno bauen und habe daher gerade einen Testcode geschrieben, der über die Funktion "millis()" jede Sekunde 1 von einem int (im Code: counter) abzieht und diesen dann auf dem Serialmonitor ausgibt. Allerdings wird nach einer Sekunde zwar counter im Serialmonitor ausgegeben, jedoch immer mit dem Wert 10 (in der Ausgabe sieht es dann mit Zeit so aus:16:42:50.050 -> 10 16:42:51.046 -> 10 16:42:52.068 -> 10 16:42:53.049 -> 10 16:42:54.067 -> 10 16:42:55.067 -> 10 16:42:56.065 -> 10 16:42:57.083 -> 10 16:42:58.079 -> 10
)
Kann mir jemand sagen, warum der Wert von counter nicht sinkt und wie ich das Problem lösen kann? (Der Code ist hier:
`
long lastTime;
int counter = 10;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println(counter);
lastTime = millis();
}
void loop() {
// put your main code here, to run repeatedly:
if(millis() >= lastTime + 1000){
counter - 1;
Serial.println(counter);
lastTime = millis();
}
}
`
)
Vielen Dank schonmal für die Antworten!
VG AiT
Das fällt Dir auf die Füße.
Lege Dir ein Intervall an, merke Dir die letzte Zeit und subtrahiere den letzten gemerken Wert von der aktuellen Zeit und reagiere dann da drauf und merke Dir den neuen Wert.
Niemals vorwärts addieren! Das führt zu einem Überlauf, den Du nicht abfangen kannst.
@Ait
da hätte ich etwas älteres, zwei Stoppuhren die sich gegenseitig starten lassen.
sollte sich auch auf "Abwärtszählen" umbauen lassen.
/*
Several stop watches linked together
only one stop watch can run at the same time - the others are paused
by noiasca
2021-06-06 version with 3 timers. https://forum.arduino.cc/t/track-amount-of-time-spend-on-office-tasks/869752/7
2021-05-01 initial version. https://forum.arduino.cc/t/millis-timer-pausieren-und-wieder-starten/855936
*/
class Timer {
protected:
const byte buttonPin; // pin to GND starts timer
uint32_t previousMillis = 0; // last active millis of this timer
uint32_t myMillis = 0; // accumlated millis for this timer
static int8_t activeTimer; // stores the active Timer ID
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();
activeTimer = id;
Serial.print(F("Button pressed ")); Serial.println(id);
}
uint32_t getMillis() // returns the accumulated millis of one timer
{
if (activeTimer == id) // update millis before return
{
uint32_t currentMillis = millis();
myMillis += currentMillis - previousMillis; // add passed time to old millis
previousMillis = currentMillis; // remember the timestamp of the last millis update
}
return myMillis;
}
byte getId()
{
return id;
}
uint8_t getActiveTimer()
{
return activeTimer;
}
void pauseTimer(uint32_t currentMillis = millis()) // pause an active timer, either with parameter or actual millis() will be used
{
if (activeTimer == id) // update myMillis before return
{
myMillis += currentMillis - previousMillis; // add passed time to old millis
previousMillis = currentMillis; // remember the timestamp of the last millis update - optional
activeTimer = -1;
}
}
};
byte Timer::total = 0; // declare inside class, but define outside = 0 (leave it 0!)
int8_t Timer::activeTimer = -1; // declare inside class, but define outside. -1 no timer is running
Timer timer[] { // create several timers, each one needs a "start" button
{A0}, // buttonPin
{A1},
};
const byte pausePin = A3; // this button will pause an active running timer
void setup() {
Serial.begin(115200);
Serial.println(F("Several dependend Stopwatches"));
for (auto &i : timer) i.begin();
pinMode(pausePin, INPUT_PULLUP);
}
void loop() {
for (auto &i : timer) i.read(); // read button
readPause(); // check if pause was pressed
updateSerial(); // output current values to serial
}
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(timer[0].getActiveTimer());
previousMillis = currentMillis;
}
}
void readPause()
{
if (digitalRead(pausePin) == LOW)
{
uint32_t currentMillis = millis();
for (auto &i : timer) i.pauseTimer(currentMillis);
}
}
Muss ich dann einfach ein "unsigned" vor das Long schreiben oder wie mach ich das?
Das wollte ich später auch so machen, aber bis jetzt habe ich für Timer und Stoppuhren immer "delay()" genutzt und hatte jetzt den Eindruck dass für die Schachuhr "millis()" besser ist, was ich erstmal ausprobieren wollte.