delay() is evil.

Arduino specifieke Software
Berichten: 287
Geregistreerd: 15 Apr 2021, 20:05

delay() is evil.

Berichtdoor ctunes » 20 Apr 2021, 22:57

delay() ...

het lijkt soms zo'n mooie oplossing, want: "Hé! Nu werkt het opeens wel!"

Vaak echter levert delay() meer problemen op dan het oplost.

Het is een soort van "goto" die je in basic ooit gebruikte, maar met ernstigere consequenties en bijwerkingen.


Voorbeeld:
Code: Alles selecteren
Serial.begin(2000000) // usb 2.0 kan dat aan, 115200 was vroeger ... de rs232 limiet.
delay(1000) // wacht op initialisatie
Serial.println();


Als de hardware nog niet klaar was met initialisatie kan er van alles mis gaan.

Het kan heus zijn dat na 1000ms de hardware klaar is, maar dit is niet gegarandeerd.
Zeker niet in embedded systemen.

Stel je voor een dat in een Tesla het bericht: "Stuur niet tegen de boom", naar de stuurcomputer werd gestuurd, maar de stuurcomputer helemaal nog niet klaar was om berichten te ontvangen?

Wat gebeurt er dan met het bericht?

Code: Alles selecteren
While ( !Serial.begin(2000000) );

Pas daarna is het "zeker", dat de interface bestaat.

En liggen de rest van de bugs tenminste niet aan een (foutief) gebruik van delay().
Laatst gewijzigd door ctunes op 20 Apr 2021, 22:59, in totaal 1 keer gewijzigd.

Advertisement

Berichten: 4064
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: delay() is evil.

Berichtdoor shooter » 21 Apr 2021, 08:47

Nou CT dit klopt dus echt niet de while met begin werkt dus totaal niet en delay is al helemaal geen goto. het is gewoon even niks doen. zelfs een software interupt stopt alleen een hardware interupt gaat kijken of het nodig is.
en ja delay is lastig, maar wordt door mij toch veel gebruikt, ipv een debugger.
Niet iedereen begrijpt blink without delay en dus is het een makkelijke oplossing,
goh zelfs het standaardprogramma dat op elke arduino zit als je hem koopt is met delay, het is toch een leeromgeving en dan kan delay al een aardige opdracht zijn.
paul deelen
shooter@home.nl

Berichten: 287
Geregistreerd: 15 Apr 2021, 20:05

Re: delay() is evil.

Berichtdoor ctunes » 04 Mei 2021, 20:34

Het gebruik van delay() in de voorbeeldcode is dan ook niet bijster slim, het moedigt immers aan het zelf ook te gebruiken.
(En niet veel "makers" komen ooit verder dan de voorbeeldcode.)

De arduino reference zelf moedigt nota bene dan ook het gebruik ervan af:
https://www.arduino.cc/reference/en/language/functions/time/delay/
Notes and Warnings
While it is easy to create a blinking LED with the delay() function and many sketches use short delays for such tasks as switch debouncing, the use of delay() in a sketch has significant drawbacks.



Zou delay() platformwijd hetzelfde werken dan hoorde je mij niet, maar dat doet het niet.*)


En alleen om die reden al geldt mijn titel.



Wie een delay() in zijn code "nodig" heeft, is "'t Kofschip" verkeerd aan het toepassen.
(Zonder te weten dat dit alleen op de stam van het werkwoord van toepassing is.)

Zodat je code kan krijgen als: "Auto verkeerd in goede staat".

Wat syntactisch volledig juist is (logisch wat minder): "De auto is verkeerd, maar (paradoxaal gezien) in goede staat".

Dergelijke caveats creëer je, als je niet precies uitlegt wat de delay() functie doet.

En wie wil nou energie verspillen door een microprocessor niets te laten uitvoeren?

Daar is immers de sleep() functie voor uitgevonden.

::

Wat ik eigenlijk bedoel: "Sommige van onze probeersels bereiken het verkoopstadium; hebben wij werkelijk met alles rekening gehouden?"
Slim/Juist programmeren is wat anders dan: "Hé het werkt! Verkopen die handel!"

shooter schreef:maar wordt door mij toch veel gebruikt, ipv een debugger.


Ik begrijp dat niet, of half.

Je bedoelt dat je na toepassing van de delay() de fouten in je programma hebt gevonden en daarna door kan zonder delay()?
Ik zou liever een debugger gebruiken als ik op dat punt uit kwam.

*) Daarnaast, niet elke versie van de ide gebruikt dezelfde methode, niet iedere boardmanager ook.

Dus iets dat met delay() wel werkte op een Uno kan op een (Kloon-)Nano falen, door een ander implementatie van de delay() functie.

En dan heb ik het nog niet eens over temperatuur gehad.

Berichten: 5
Geregistreerd: 02 Jul 2021, 15:00

Re: delay() is evil. voorbeeld voor vervangen van Delay

Berichtdoor Boment » 07 Jul 2021, 12:58

Je hebt helemaal gelijk, ik gebruik delay nooit meer , delay is het zelfde als 'wachten' Delay legt gewoon ALLES stil en brengt een hoop ellende
Oke het standaard voorbeeld is niet echt goed , ik gebruik dit, een simpel voorbeeld

Voorbeeld puls van 1 minuut:
Code: Alles selecteren
 
 unsigned long time_1 = 0;

// boven in de loop dit plaatsen
 if (millis() >= time_1){
  time_1 = millis() + 60000;   / /dit is 1 minuut
  Klok();   //Om de 1 minuut kan je in de void Klok iets doen, bijvoorbeeld met een teller een digitale klok maken.
      }


Voorbeeld voor vertraging (delay) ik gebruik het voor magneet wissels te sturen

Dit in de loop :
Code: Alles selecteren
   if (millis() >= time_1){ //Wissel 1
    digitalWrite(Wis1L,LOW);  // maak spanning laag voor magneet af te schakelen
    time_1 = 0;  / zet timer op 0
}

En dit op de plek waar de wissel gestuurd wordt :
Code: Alles selecteren
             
digitalWrite(Wis1L,HIGH) // maak spanning hoog voor magneet in schakelen
 time_1 = millis() + Tpuls; //of Tpuls = 250 ofwel 250 ms tijd van magneet aansturen
 

Berichten: 287
Geregistreerd: 15 Apr 2021, 20:05

Re: delay() is evil.

Berichtdoor ctunes » 10 Jul 2021, 23:10

Kudos!


Je kunt ook gewoon een timer gebruiken.

Die zijn hard- en softwarematig aanwezig.

https://github.com/contrem/arduino-timer

Berichten: 287
Geregistreerd: 15 Apr 2021, 20:05

Re: delay() is evil.

Berichtdoor ctunes » 19 Dec 2021, 22:34

Dank voor je reaktie, maar je zag iets over het hoofd:

Ook de millis() functie schakelt interrupts uit:

https://github.com/arduino/ArduinoCore- ... o/wiring.c

Code: Alles selecteren
unsigned long millis()
{
   unsigned long m;
   uint8_t oldSREG = SREG;

   // disable interrupts while we read timer0_millis or we might get an
   // inconsistent value (e.g. in the middle of a write to timer0_millis)
   cli();
   m = timer0_millis;
   SREG = oldSREG;

   return m;
}


Dat wil zeggen dat er geen interrupts mogelijk zijn terwijl de teller loopt.


Het nadeel hiervan is dat de "arduino-filosofie" totaal ongeschikt is voor commerciële projecten, en dat de "enthousiastelingen" hier vaak te laat achter komen.

(Een consequentie hiervan, is dat indien het project toch doorgang vindt, er altijd gezocht wordt naar "Mel".)

En bovendien is het niet "groen": terwijl de cpu staat te wachten, had hij ook taakonafhankelijke zaken kunnen uitvoeren.

delay() is evil.

Ik blijf erbij, met deze kanttekening.

Soms is een NOP nodig, omdat de documentatie dat aangeeft.

Als je bijvoorbeeld een i/o-pin van tri-state naar in- of output wil veranderen, heb je een NOP nodig, voor propagatiedoeleinden.

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 26 gasten