Pages: [1]   Go Down
Author Topic: Bug nell' esempio BlinkWithoutDelay  (Read 800 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Sr. Member
****
Karma: 0
Posts: 362
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nell' esempio "BlinkWithoutDelay" il codice originario e' :
Code:
currentMillis = millis()
if(currentMillis - previousMillis > interval)
    previousMillis = currentMillis;

Ma non va bene ! in quanto passano sicuramente dei ms per processare quell' if e poi settare il valore di previousMillis.


Il codice corretto dovrebbe essere:

Code:
currentMillis = millis()
if(currentMillis - previousMillis > interval)
    previousMillis = previousMillis + interval;




PS. Mi mettete una nota nel codice ? "modified 22 Lug 2012 by Alex Limbeck"  smiley-lol
Logged

Global Moderator
Milano, Italy
Offline Offline
Edison Member
*****
Karma: 15
Posts: 1163
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

L'unico modo per cui potrebbe verificarsi una differenza tra le due istanze è questo:
Code:
if(millis() - previousMillis > interval) {
    previousMillis = millis();
    //codice
}

quell'if ad essere processato ci mette infinamente meno di un millisecondo. Quindi di fatto anche se è concettualmente sbagliato, l'errore che produci non è sostanziale.

Un approccio sbagliato potrebbe essere:

Code:
if(millis() - previousMillis > interval) {
    //tanto codice
    previousMillis = millis();
}

dove aggiornando previousMillis come ultima istruzione, sicuramente hai lasciato passare del tempo, probabilmente anche nell'ordine dei millisecondi, tutto sta alla quantità e complessità di codice che viene eseguito prima.
« Last Edit: July 22, 2012, 03:50:07 am by Federico Vanzati » Logged

F

Offline Offline
Sr. Member
****
Karma: 0
Posts: 362
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No, perche':
il timer va sempre avanti ed il codice pure...
Code:
if(currentMillis - previousMillis > interval)
viene eseguito quando la differenza tra i due e' superiore a mille.
quindi
Code:
previousMillis = currentMillis
verra' eseguito ancora piu' tardi.

Quindi il ritardo sara' superiore a 1000.
Questo ritardo sara' tanto piu' grande, quanto piu' bassa e' la frequenza del microcontroller.



Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 362
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

quell'if ad essere processato ci mette infinamente meno di un millisecondo. Quindi di fatto anche se è concettualmente sbagliato, l'errore che produci non è sostanziale.
Il fatto e' che l' errore c'e' ed io lo voglio correggere  smiley-lol
Logged

0
Offline Offline
Faraday Member
**
Karma: 39
Posts: 5608
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

interessante concetto,
dipende sia dal tempo che impiega il codice interno all'if, come dice federico, sia dalla precisione che a te serve.

Nei casi in cui questo crea problemi, potresti usare il leOS di leo, dovresti essere immune da questi ritardi visto che lavora su un secondo timer del micro
Logged

- [GUIDA] IDE1.x - Nuove Funzioni - Sketch Standalone - Bootloader - VirtualBoard
http://arduino.cc/forum/index.php/topic,88546.0.html
- [LIBRERIA] ST7032i LCD I2C Controller Library
http://arduino.cc/forum/index.php/topic,96163.0.html

Offline Offline
Sr. Member
****
Karma: 0
Posts: 362
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

interessante concetto,
dipende sia dal tempo che impiega il codice interno all'if, come dice federico, sia dalla precisione che a te serve.
Io ho gia' risolto il problema.
Basta modificare il codice in:
Code:
previousMillis = previousMillis + interval;

Funziona con qualsiasi velocita' del micro...
Funziona indipendentemente dalla quantita' di codice...
Oltre ad essere concettualmente la soluzione giusta.
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 362
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ecco un esempio :
Il sottostante codice sballa di 1 o 2 ms su un Arduino UNO cloccato a 16MHz.
Da notare che il Serial.print l' ho messo dopo, per non indurre altri ritardi !
(guardare con il serial monitor l' effettivo delay)


Code:
  if(currentMillis - previousMillis > interval) {
    int diff = (currentMillis - previousMillis);
    previousMillis = currentMillis;
    Serial.println(diff); 
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 103
Posts: 6592
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Apri un "ticket" descrivendo il problema e la soluzione, in inglese. Gli sviluppatori valuteranno la questione e, se del caso, la inseriranno nella prossima release.
--> http://code.google.com/p/arduino/issues/list
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

BZ (I)
Online Online
Brattain Member
*****
Karma: 235
Posts: 20232
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

interessante concetto,
dipende sia dal tempo che impiega il codice interno all'if, come dice federico, sia dalla precisione che a te serve.
Io ho gia' risolto il problema.
Basta modificare il codice in:
Code:
previousMillis = previousMillis + interval;

Funziona con qualsiasi velocita' del micro...
Funziona indipendentemente dalla quantita' di codice...
Oltre ad essere concettualmente la soluzione giusta.

per dire una cattiveria: Il millis() viene aggiornato ogni millisecondo. Percui posso avere un errore fino a 0,999mS. Siccuramente questo no é preciso e percui non ammissibile smiley-wink smiley-wink smiley-wink smiley-wink

In poche parole:
@acik devi valutare la necessitá di precisone che devi ottenere.  Se un LED lampeggia con 1 Hz oppure con 1,001 Hz a nessuno frega qualcosa e nessuno si accorge.
Se hai necessitá di tempi piú precisi Ti consiglio di usare i timer del ATmega.

Ciao Uwe
Logged

Pages: [1]   Go Up
Jump to: