Go Down

Topic: [RISOLTO] millis su fade led rgb (Read 1 time) previous topic - next topic

LeoTer01

Nov 15, 2018, 06:08 pm Last Edit: Nov 22, 2018, 08:12 pm by LeoTer01
Ciao a tutti, io ho questo codice:
Code: [Select]
for( int i = 0 ; i < 255 ; i += 1 ){
       analogWrite( G, 0 + i );
       analogWrite( R, 255 - i );
       delay(tempo);
    }
    for( int i = 0 ; i < 255 ; i += 1 ){
      analogWrite( B, 0 + i );
      analogWrite( G, 255 - i );
      delay(tempo);
    }
    for( int i = 0 ; i < 255 ; i += 1 ){
      analogWrite( R, 0 + i );
      analogWrite( B, 255 - i );
      delay(tempo);
      }

che mi permette di effettuare un fade incrociato di un led rgb. Il mio problema è che devo sostituire il delay con un millis perchè non posso far fermare il programma. Nonostante ho provato ad inserire il millis mi vengono fuori risultati compleatmente differenti da quelli sperati.
Ecco una delle tante prove (che però non va bene):
Code: [Select]
for( int i = 0 ; i < 255 ; i += 1 ){
      zero = millis();
       if(millis() - zero < tempo){
       analogWrite( G, 0 + i );
       analogWrite( R, 255 - i );
       //delay(tempo);
      }
      else{
        zero = millis();
      }
    }
    for( int i = 0 ; i < 255 ; i += 1 ){
      int zero1 = millis();
      if(millis() - zero1 > tempo){
      analogWrite( B, 0 + i );
      analogWrite( G, 255 - i );
      zero1 = millis();
      //delay(tempo);
      }
      else{
        zero1 = millis();
      }
    }
    for( int i = 0 ; i < 255 ; i += 1 ){
      int zero2 = millis();
      if(millis() - zero2 > tempo){
      analogWrite( R, 0 + i );
      analogWrite( B, 255 - i );
      zero2 = millis();
      //delay(tempo);
      }
      else{
        zero2 = millis();
      }
    }

Qualcuno può darmi una mano?

Grazie
Leo

Claudio_FF

***** IF e SWITCH non sono cicli !!! *****
** Una domanda ben posta è già mezza risposta **
*** La corrente si misura in mA, la quantità di carica in mAh ***

LeoTer01

Grazie Claudio_FF per avermi linkato quei qost che mi hanno chiarito meglio l'utilizzo del millis(). Ho notato però che in quei post, alla funzione millis viene affiancata la funzione switch, ho l'impressione che non è ciò che serve a me, o sbaglio?

Leo

Claudio_FF

#3
Nov 16, 2018, 05:26 pm Last Edit: Nov 16, 2018, 05:34 pm by Claudio_FF
Quote from: LeoTer01
in quei post, alla funzione millis viene affiancata la funzione switch, ho l'impressione che non è ciò che serve a me, o sbaglio?
Switch è solo una forma contratta di if/else if/else if/... quindi si può benissimo non usarla, basta che la sequenza logica delle operazioni svolte sia la stessa.
***** IF e SWITCH non sono cicli !!! *****
** Una domanda ben posta è già mezza risposta **
*** La corrente si misura in mA, la quantità di carica in mAh ***

LeoTer01

Dopo tante prove sono riuscito a scrivere un codice che, secondo me è il più corretto, però continua a non funzionare. Il led rimane acceso rosso e controllando da seriale i valori di fadeR, fadeG, fadeB non cambiano ma rimangono quelli di partenza, ovvero rispettivamente 255, 0, 0. Qualcuno sa dirmi dove sto sbagliando?
(Ricordo che il mio intento è quello di creare una dissolvenza incrociata dei tre colori di un led rgb, senza l'uso del delay)
Ecco il codice:
Code: [Select]

int R = 5;
int G = 6;
int B = 3;
int fadeR = 255;
int fadeG = 0;
int fadeB = 0;
long zero = 0;
long tempo;
void setup(){
pinMode(R, OUTPUT);
  pinMode(G, OUTPUT);
  pinMode(B, OUTPUT);
}
void loop(){
    analogRead(A5);
    pR = map(analogRead(A5), 0, 1023, 1, 20);
    tempo = pR;
    if(millis() - zero > tempo){
      if(fadeR >= 0 && fadeG <= 255){
        fadeR--;
        fadeG++;
        analogWrite(R, fadeR);
        analogWrite(G, fadeG);
        zero = millis();
      }
      if(fadeG >= 0 && fadeB <= 255){
        fadeG--;
        fadeB++;
        analogWrite(G, fadeG);
        analogWrite(B, fadeB);
        zero = millis();
      }
      if(fadeB >= 0 && fadeR <= 255){
        fadeB--;
        fadeR++;
        analogWrite(B, fadeB);
        analogWrite(R, fadeR);
        zero = millis();
      }
    }
delay(10);
}


Grazie
Leo

Datman

Consideri che millis() è in millisecondi, vero?
Hi,I'm Gianluca from Roma.I play&work with electronics since I was16(1984).
After 25yrs of maintenance on cameras&video mixers,since 2013myJob is HDTVstudios design.
Since Jan2015 IPlayWith Arduino:bit.ly/2F3LPWP
Thanks 4 a Karma if U like my answer

fabpolli

#6
Nov 20, 2018, 03:57 pm Last Edit: Nov 20, 2018, 03:58 pm by fabpolli
la variabile tempo quando la inizializzi?
Poi tutte le variabili legate a millis devono essere unsigned long e non solamente long
Più precisamente tempo può essere long basta che il valore che vuoi controllare stia nei limiti del long, ma zero deve essere unsigned long

LeoTer01

Consideri che millis() è in millisecondi, vero?
Esatto.


Poi tutte le variabili legate a millis devono essere unsigned long e non solamente long
Più precisamente tempo può essere long basta che il valore che vuoi controllare stia nei limiti del long, ma zero deve essere unsigned long
Provveduto a modificare da long a unsigned long entrambe, potresti spiegarmi il motivo di ciò, perchè altre parti del programma (che ho omesso) funzionavano lo stesso anche con long, grazie.



la variabile tempo quando la inizializzi?
In che senso "inizializzi" ?

Leo

passo88

#8
Nov 20, 2018, 04:14 pm Last Edit: Nov 20, 2018, 04:16 pm by passo88
ciao io inizializzo millis() cosi':
Code: [Select]
unsigned long previousMillis1 = 0; //will store last time LED was updated
unsigned long interval1 = 10000;  //tempo aggiornamento 10 secondi


poi nel loop () ho cosi:

Code: [Select]
if (millis() - previousMillis1 > interval1) {
    previousMillis1 = millis();
}


in questo modo se sono passati 10 secondi continua il codice dopo if senno continua il loop()

ciao

fabpolli

Esatto.

Provveduto a modificare da long a unsigned long entrambe, potresti spiegarmi il motivo di ciò, perchè altre parti del programma (che ho omesso) funzionavano lo stesso anche con long, grazie.


In che senso "inizializzi" ?

Leo
Quello è un errore mio non avevo notato la riga
Code: [Select]

tempo = pR;

che valorizza la variabile.
Funzionavano con long per pura fortuna  :)
A parte gli scherzi le variabili long ti fanno funzionare il tutto  finché millis() non restituisce un valore superiore al limite di long quindi per per esempio facendo prove riprogrammi/resetti arduino spesso tutto sembra funzionare, quando invece arduino resta acceco per più di 2,147,483,647 mS allora assegnano un valore troppo grande per il logn questo assumerà un valore negativo (Es. un mS dopo il limite indicato una variabile long varrà -2,147,483,648) e si incasina il tutto.
Non è però detto che in questo caso specifico sia quello a creare l'anomalia di funzionamento

fabpolli

Nello specifico ti consiglio di "rivedere" la richista di @Datman perché hai risposto di si ma mi sa che la tua map "sbugiarda" :) la tua affermazione

LeoTer01

che valorizza la variabile.
Funzionavano con long per pura fortuna  :)
A parte gli scherzi le variabili long ti fanno funzionare il tutto  finché millis() non restituisce un valore superiore al limite di long quindi per per esempio facendo prove riprogrammi/resetti arduino spesso tutto sembra funzionare, quando invece arduino resta acceco per più di 2,147,483,647 mS allora assegnano un valore troppo grande per il logn questo assumerà un valore negativo (Es. un mS dopo il limite indicato una variabile long varrà -2,147,483,648) e si incasina il tutto.
Non è però detto che in questo caso specifico sia quello a creare l'anomalia di funzionamento
Capito grazie, però non era quello il problema  :(



Nello specifico ti consiglio di "rivedere" la richista di @Datman perché hai risposto di si ma mi sa che la tua map "sbugiarda" :) la tua affermazione
E come faccio a saperlo? Io credevo che fosse in millisecondi. Il map ce l'ho messo perchè volevo che girando il potenziometro "pR" mi cambiasse il valore di "tempo" quindi la velocità della dissolvenza.

Leo

fabpolli

E come faccio a saperlo? Io credevo che fosse in millisecondi. Il map ce l'ho messo perchè volevo che girando il potenziometro "pR" mi cambiasse il valore di "tempo" quindi la velocità della dissolvenza.

Leo
Guarda bene i valori che usi. Il valore minimo e massimo che ti ritorna la map qual'è?

LeoTer01

Da serial monitor leggendo "pR" leggo valori da 1 a 20 in base a com'è posizionato il potenziometro.

Leo

fabpolli

#14
Nov 20, 2018, 04:35 pm Last Edit: Nov 20, 2018, 04:37 pm by fabpolli
ok e ti sembrano tanti 20 millisecondi? :)

Considerando che la persistenza retinica si aggira attorno a 18/20 mS ::)


Go Up