Nou, ik ben blijkbaar niet de enige die problemen heeft (gehad) met de timerfunctie van blinkwithout delay.
Als je een klein applicatietje maakt, dat in de praktijk 24 op 24 uur moet werken, jaar in jaar uit, voldoet ie niet, of je moet heel erg uitkijken, hoe je m schrijft.
Er zijn mischien wel duizenden mensen dieproblemen met blink without delay gehad hebben.
Het komt wekelijks voor op het forum, mischien wel vaker.
En ja, voor alle applicaties geldt dat je uit moet kijken hoe je hem schrijft. Het algoritme om hoe op de juiste manier met de overflow van de millis() en micros() klok om te gaan is al jaren bekend, maar het is minder intuitief dat aftrekken wel werkt waar optellen faalt.
Er is mij op dit moment één probleem bekend met millis(), en dat is NIET de overflow. millis() heeft de eigenschap dat hij een getal kan overslaan, oorzaak, de ophoging van de interne teller gebeurt tegelijk met een foutcorrectie. DIt is een bekend probleem waarvoor geen goede oplossing bestaat zover ik weet. [ Een goede oplossing heeft vrijwel dezelfde code grootte en snelheid als de huidige millis().]
De enige manier om hiermee om te gaan is altijd ongelijkheden (> en < en >= en <= ) te gebruiken als je met millis() of micros() en tellers in het algemeen werkt. Als je namelijk == gebruikt en hij springt net met 2 omhoog (of je bent gewoon een paar millis te laat) dan faalt de IF.
Dus pas op hoe je dat opvangt, en druk vooral niet op je knopje (of watever) tijdens dat ie overloopt.
Afhankelijk van je timer kan dat een seconde, uur of dag beslaan, dat je niet op je knopje mag drukken.
Kun je een voorbeeld sketch posten waarin dit misgaat? Ik ben heel benieuwd.
Van de link die jij geeft
If you are just interested in a repeating timer then see http://arduino.cc/en/Tutorial/BlinkWithoutDelay for a simple reliable repeating timer which does not count down. The code below works because even if currentMillis overflows back to a small number, currentMillis – previousMillis still gives the correct result.
void loop() {
- unsigned long currentMillis = millis();*
- if(currentMillis - previousMillis> interval) {*
- // save the last time*
- previousMillis = currentMillis;*
- // do stuff here each interval (interval -- an unsigned long)*
- ...*
- }*
Er staat wel een fout op de pagina, hier wordt == gebruikt met millis(). - zie boven)
// the loop routine runs over and over again forever:
void loop() {
_ if (millis() == timeout) { // NOTE: the == only toggle led when millis() equals timeout_
- // time to toggle the Led*
- timeout += 1000;*
- if (digitalRead(led)) {*
- digitalWrite(led, LOW); // turn the LED off by making the voltage LOW*
- } else {*
- digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)*
- }*
- }*
}
This code works because when timeout + 1000 overflows, millis() will not equal it until millis() also overflows.
Deze code werkt niet als millis() net met 2 verspringt over de waarde van timeout heen,
Millis() zal ~50 dagen moeten ophogen voordat ie weer een kans heeft om gelijk aan timeout te zijn.
Een mijn insziens betere uitleg van hoe om te gaan met millis() - Gammon Forum : Electronics : Microprocessors : How to do multiple things at once ... like cook bacon and eggs -