SOS senza delay (torcia led)

Ciao a tutti,
sto cercando di costruire una torcia led con driver programmabile in 4 mode:100% 50% 10% SOS.
(usero un attiny85 per questioni di spazio). i primi tre nessun problema con un semplice analogWrite si risolve. il problema é con l'SOS in quanto volendo avere sempre il loop in funzione per poter leggere il pulsante non volevo usare un delay() ma sfruttare l'esempio blink without delay adattandolo a diversi tempi. a tentoni sono riuscito a superare anche questo scoglio: funziona alla perfezione ma dopo 2-3 cicli la funzione SOS si blocca lasciando il led sempre acceso. non capisco dove posso aver sbagliato.

Di seguito la parte di codice dell'SOS:

if(millis() - oldmillis > Delay[i]) {
    // save the last time you blinked the LED 
    oldmillis = millis();   
    i++;
    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(led, ledState);
    if(i==18) i=0;
  }

Grazie a tutti in anticipo

[EDIT] non usare tt-Tag ma code-TAG. Grazie Ciao Uwe [/EDIT]

il Delay nella funzione if iniziale é un valore di un array Delay dichiarato all'inizio, con indice i.

in sostanza dovrebbe essere scritto: Delay

Se non metti il codice tra i TAG code l'indice non viene visualizzato perche identificato come TAG per il carattere italico.
Regolamento punto 7 --> [REGOLAMENTO] Come usare questa sezione del forum - Italiano - Arduino Forum

Da quanti elementi è composto il vettore? 18?
Se si vanno da 0 a 17, altrimenti sono 19.

Grazie per la dritta.
Comunque è formato da 19 elementi e quindi quando arriva al 19esimo i=18 lo faccio ricominciare. All'inizio avevo sbagliato ma anche correggendolo la situazione non cambia

Pubblica il codice completo (fai copia/incolla) racchiudendolo negli appositi tag "CODE" (bottone # che vedi terzultimo da destra sulla seconda fila) ... così diamo un occhiata al tutto ...

Guglielmo

Ecco il codice completo:

int var;
int led=0;
int b=1;
int oldmillis;
int ledState=LOW;
int i=0;
int Delay[]={250,250,250,250,250,250,750,750,750,750,750,750,250,250,250,250,250,250,1750};

void setup(){
  pinMode(led,OUTPUT);
  pinMode(b,INPUT);
  oldmillis=0;
}
void loop(){
  if(digitalRead(b)==HIGH && var!=4){
    var++;
    i=0;
    delay(500);
    oldmillis=millis();
  }
  else if(digitalRead(b)==HIGH && var==4){
    var=0;
    i=0;
    delay(500);
  }
  if(var==0){
    digitalWrite(led,LOW);
  } else if(var==1){
    analogWrite(led,255);
  } else if(var==2){
    analogWrite(led,127);
  } else if(var==3){
    analogWrite(led,5);
  } else if(var==4){
    if(millis() - oldmillis > Delay[i]) {
    // save the last time you blinked the LED 
    oldmillis = millis();   
    i++;
    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(led, ledState);
    if(i==18) i=0;
  }   
  } 
  }

Attento ... non puoi dichiarare oldmillis di tipo int è a 16 bit (-32768 .. +32767) ... ci mette 32 secondi ad andare in overflow XD

La funzione millis(), come da reference (... che sarebbe buona cosa studiarsi bene) ritorna un unsigned long ... ovvero 32 bit !!!

Correggi e vedi come va ... :wink:

Guglielmo

Edit : Cortesemente, usa anche la funzione dell IDE ... Tools -> Auto Format ... almeno mette a posto il codice con le giuste indentature e le parentesi incolonnate come si deve ... che quelle tre parentesi in fila alla fine ... non si possono vedere ]:smiley:

Svelato l'arcano. Grazie mille.
ma una domanda: in teoria l'attiny85 non viene mai scollegato dalla batteria quindi la funzione millis() va avanti per chi sa quanto. non rischia comunque di andare in overflow prima o poi? se si non é possibile azzerarla ad esempio quando vien epremuto il pulsante?

ps non sopporto nemmeno io la formattazione cosi approssimativa. ora che conosco questo strumento i miei sketch saranno molto piú ordinati

jack7893:
ma una domanda: in teoria l'attiny85 non viene mai scollegato dalla batteria quindi la funzione millis() va avanti per chi sa quanto. non rischia comunque di andare in overflow prima o poi ?

Certo che va in overflow ... dopo circa 49 giorni se ben ricordo, ma .. per come hai fatto l'IF ... la cosa non è rilevante ... puoi capire meglio la questione QUI :wink:

Guglielmo

jack7893:
Svelato l'arcano. Grazie mille.
ma una domanda: in teoria l'attiny85 non viene mai scollegato dalla batteria quindi la funzione millis() va avanti per chi sa quanto. non rischia comunque di andare in overflow prima o poi? se si non é possibile azzerarla ad esempio quando vien epremuto il pulsante?

ps non sopporto nemmeno io la formattazione cosi approssimativa. ora che conosco questo strumento i miei sketch saranno molto piú ordinati

e perché devi continuare a farla andare avanti non te l'ha ordinato mica il dottore ]:smiley: ogni volta che millis () arriva a un ora o un giorno l'azzeri e tutto ricomincia

Millis non l'azzeri :wink:
Millis è una funzione e come tale è una routine che restituisce un valore. Casomai puoi azzerare il contatore nascosto che viene usato per conteggiare i millisecondi, indicandolo allo sketch di Arduino. Ma non è necessario se si fanno i confronti giusti.

intendevo una cosa così
http://forum.arduino.cc/index.php?topic=198388.msg1465282#msg1465282

Intendevo proprio quello.
NON azzeri la millis() ma il contatore che viene letto dalla funzione. :wink: