Il mistero dello 0

0=zero :)

1) uso millis per un pwm che mi incrementa di uno i 255 step 2) se faccio il confronto con il valore UNO (if millis - x > 1 ) la luminosita' arrivera' a 255 dopo 255 ms 3) volendo velocizzare il raggiungimento della max luminosita' uso micros() ad esempio a 500, tutto ok

Test

1) Ho provato a togliere il millis, giustamente la velocita' e' elevatissima (e' facile calcolare in questa situazione quanto dura un unico step ?) 2) Ho poi provato ad usare LO ZERO (if millis - x > 0 ), mi aspettavo che non cambiasse nulla rispetto al non averlo, al massimo qualcosina in meno come velocita' visto che e' pur sempre un IF in piu' da valutare, ma per il micro credevo fossero bazzecole (e lo credo ancora), INVECE con lo ZERO ricevo solo circa il doppio di velocita' rispetto all'UNO (Cosa succede internamente, un IF in piu' puo' influenzare cosi' tanto, cioe' aumenta solo di 120ms la velocita' di incremento ?)

Non ho capito niente. Puoi mettere i due esempi di codice?

Mi piacciono i misteri…

Ma cosa è x?

if (millis - x > 1) è come dire if (millis > x + 1)

if (millis - x > 0) è come dire if (millis > x)

la differenza è di 1, ma quanto questa differenza sia “importante” dipende dal valore di x

O forse ho capito male tutto il discorso.

Mi pare che voglia dire che if millis - x > 1 sia eseguito con una velocità e che if millis - x > 0 sia eseguito con un'altra, ma non con la doppia velocità. Perché, Testato, ti aspettavi la doppia velocità nell'esecuzione di un test con 0?

Ah... io invece ho capito che ha avuto la doppia velocità e se ne aspettava un'altra.

Ehm... FORSE sarebbe il caso di chiarire meglio :grin:

Testato:
2) Ho poi provato ad usare LO ZERO (if millis - x > 0 ), mi aspettavo che non cambiasse nulla rispetto al non averlo, al massimo qualcosina in meno

Non capisco cosa intendi. Avere l’IF con confronto 0 o 1 dovrebbe essere uguale come tempo, di sicuro diverso dal non averlo.
Perciò questa non la capisco: “non cambiasse nulla rispetto al non averlo”

Ah
Forse ho capto…

Forse ha fatto qualcosa come:
IF (currentmillis - previousmillis > interval)
con interval pari ad 1 ms nel primo caso e 0 ms nel secondo caso, per cui si aspettava, mettendo 0 ms come intervallo, che dovesse essere “istantaneo”.

YES :slight_smile:
parlo del classico uso di millis per sostituire il delay bloccante e quindi “X” serve solo per “resettare” il contatore:

if (millis() - x > 1)   {
      x=millis();
 //Qui Variabile Pippo da incrementare
  • Con questo codice per incrementare di 255 Pippo impieghero’ 255ms
  • Se elimino del tutto il millis Pippo si incrementera’ alla velocita’ massima possibile (talmente veloce che a malapena vedo l’incremento)
  • Se sostituisco UNO con ZERO mi aspetterei la stessa condizione di quando non c’e’ proprio il millis, cioe’ velocissimo, invece e’ si’ piu’ veloce di UNO, ma di solo il doppio

Riepilogo

Con UNO per incrementare Pippo fino a 255 impiego 255ms
Con ZERO per incrementare PIppo impiego sui 120ms
Senza il millis per incrementare Pippo impiego sui 10ms

Parlo senza aver visto l'assembly che genera il compilatore, ma quasi sicuramente la maggior velocità derivata dall'uso dello zero nell'if è data dal fatto che tutte le CPU hanno un'operazione particolare per comparare un numero con lo zero, che non è come fare un confronto con un altro numero. Quando si compara una variabile con un altro valore, la CPU carica il dato in un registro (la faccio breve) e poi preleva dalla memoria il valore della variabile. A questo punto esegue il cofronto e poi controlla se il numero è maggiore o minore. Nel caso del confronto con lo zero, salta il passaggio relativamente al caricamento del valore da confrontare perché, appunto, esistono alcune istruzioni che comparano un valore con zero, quindi la CPU deve solo prelevare il dato dalla RAM. Ecco perché l'operazione è più veloce. Ma non può essere istantanea, perché ci sono sempre delle operazioni da eseguire.

Testato: YES :) parlo del classico uso di millis per sostituire il delay bloccante e quindi "X" serve solo per "resettare" il contatore:

if (millis() - x > 1)   {
      x=millis();
 //Qui Variabile Pippo da incrementare
  • Con questo codice per incrementare di 255 Pippo impieghero' 255ms
  • Se elimino del tutto il millis Pippo si incrementera' alla velocita' massima possibile (talmente veloce che a malapena vedo l'incremento)
  • Se sostituisco UNO con ZERO mi aspetterei la stessa condizione di quando non c'e' proprio il millis, cioe' velocissimo, invece e' si' piu' veloce di UNO, ma di solo il doppio

Riepilogo

Con UNO per incrementare Pippo fino a 255 impiego 255ms Con ZERO per incrementare PIppo impiego sui 120ms Senza il millis per incrementare Pippo impiego sui 10ms

Hmm, il tuo codice, per incrementare di 255 volte pippo impiegherà 510 ms quando testi per millis() -x >1 , e 255 quando testi per millis() -x > 0 e la massima velocità del processore se non testi:

millis() -x >1: 0ms: x=0, millis = 0 => 0 >1 : falso 1ms: x=0, millis = 1 => 1 >1 : falso 2ms: x=0, millis = 2 => 2 >1 : true

millis() -x >0: 0ms: x=0, millis = 0 => 0 >0 : falso 1ms: x=0, millis = 1 => 1 >0 : true

Testato:
parlo del classico uso di millis per sostituire il delay bloccante e quindi “X” serve solo per “resettare” il contatore:

if (millis() - x > 1)   {

x=millis();
//Qui Variabile Pippo da incrementare




- Con questo codice per incrementare di 255 Pippo impieghero' 255ms

NO! ogni 2!
millis() -x > 1, entraimo a millis() = 10, quindi x = 10
ciclo successivo, il millis() deve ancora scattare (vale ancora 10);
millis() - 10 == 0 che è NON è > 1, quindi NON si entra
ciclo successivo, il millis() scatta a 11;
millis() - 10 == 1 che NON è > 1, quindi NON si entra ← quì la secondo te si entrava
ciclo successivo, il millis() scatta a 12;
millis() - 10 == 2 che è > 1, quindi si entra e cambia il PWM

Testato:

  • Se elimino del tutto il millis Pippo si incrementera’ alla velocita’ massima possibile (talmente veloce che a malapena vedo l’incremento)

errore numero 1: se “vedi”, immagino passi da seriale. Il che ti rallenta tantissimo, in particolare, una volta che hai riempito il buffer di scrittura la velocità write diventa bloccante. La velocità di svuotamento del buffer in byte è baudrate/10. Finchè lavori con la millis() nessun problema

Testato:

  • Se sostituisco UNO con ZERO mi aspetterei la stessa condizione di quando non c’e’ proprio il millis, cioe’ velocissimo, invece e’ si’ piu’ veloce di UNO, ma di solo il doppio

no, come detto sopra se usi > con 1 hai un incremento ogni 2 millis, quindi con 0 lo hai ogni 1 millis. Devi mettere un numero negativo per entrare sempre, oppure usare >=

edit: preceduto da madmatt71
nota bene: la micros() rende le cose più difficili prchè si incrementa di 4, e la seriale influenza la velocità tantissimo.

ho trovato un attimo per andare avanti sul discorso, si, avete ragione sul >=, chiarissimo, grazie

posto i risultati misurati con millis, il valore in se poco importa perche' dipendera' da altri elementi nello sketch, forse usando uno sketch pulito e vedere se per incrementare 255step ad 1ms di distanza impiega veramente 255ms ? guardando il valore senza millis, 248, significa cmq che l'intero mio loop impiega circa 1ms a giro ?

2 1021 =2 764 1 764 =1 506 0 506 =0 249 no if 248

Lo so, troppe domande, io provo a farle poi si vede :sweat_smile: