Millis

Ciao a tutti! ho una domanda apparentemente molto semplice ma che mi sta complicando notevolmente l'esistenza. devo accendere un led e dopo 5 secondi spengerlo usando il millis e nn il delay. Pensavo che come ho fatto io andasse bene ma non è così... spero in un vostro aiuto! posto il codice

#define LED 9

int stato;
int st;
int acceso=5000;
unsigned long tempo;
void setup() {
   pinMode(LED,OUTPUT);
   
   Serial.begin(9600); 
}

void loop(){
st=digitalRead(LED);
if(st==0)
{
  digitalWrite(LED,HIGH);
  tempo=millis();
  st=1;
  
}  
  if((millis()-tempo>=acceso)&&(st==1))
  {
 
    digitalWrite(LED,LOW);
   st=0;
  }

}

..e come si comporta? si accende e poi non si spegne più? oppure fa altro?

il led una volta che rimane acceso per 5 secondi si deve spengere perchè successivamente devo fare lo stesso lavoro con altri 8 led, e una volta che finisce l'ultimo di spengersi riaparte il ciclo con il primo!

ovvero:

1 led acceso per 5 secondi poi si spenge; quando si spenge il primo led si accende il secondo per 5 secondi e poi si spenge, e cos' via fino all'ottavo!!

Ma perché cerchi di aprire la comunicazione seriale se poi non la usi?
Non puoi leggere lo stato del LED usando digitalRead(LED): non ha senso, quel pin è impostato in uscita. E' lo stato del LED che deve cambiare in base alla variabile st, non viceversa.

La seriale l'avevo aperta perchè usavo il serial print di una variabile per vedere se mi entrava nel millis... non ho capito bene, in pratica cosa dovrei cambiare?

Come suggerito da Leo, poni:
int st =0;

e togli:
st=digitalRead(LED);

Ho provato ma non fa ugualemente! mi resta acceso il led ma non si spenge..

quale evento deve far scatenare l'accensione del led?

perché a parte quello che ha già detto leo72 mi sembra abbastanza giusto il codice.

una piccola nota: anche la variabile "acceso" dichiarala unsigned long

in teoria dovrebbe partire al caricamento del programma. deve essere tutto in automatico. è possibile? o serve per forza un input?

Anzi mi correggo! ho un input che se è zero deve fare il giro dei led come ho spiegato prima se invece 1 deve fare un altra cosa!

allora usa quello, no?

st=digitalRead(input);

:slight_smile:

ma non è lo stesso che mettere st=0?? cmq questa cosa dell'input è successiva. ora cm ora devo fare il "giochino" dei led in sequenza... hai per caso qlc idea a riguardo?

if((millis()-tempo>=acceso)&&(st==1))

quindi in pratica, il led si spegne se dopo almeno 5 secondi st diventa 1... e st lo leggi ogni loop() con st=digitalRead(LED);
Quindi a quanto pare st NON diventa mai 1

edit: controlla i valori con una serial.println(), eppoi non puoi fare una read su un pin in output...
semmai togli quella read, e il secondo controllo nell'if, ovvero &&(st==1), e a questo punto il led ti si spegne dopo 5 secondi

Ciao lesto! ho fatto cm dici te però nn funziona perchè il led rimane acceso. ti posto il codice

#define LED 9

int stato;
int st;
unsigned long acceso=5000;
unsigned long tempo;
void setup() {
   pinMode(LED,OUTPUT);
   
   Serial.begin(9600); 
}

void loop(){

if(st==0)
{
  digitalWrite(LED,HIGH);
  tempo=millis();
  st=1;
  Serial.print(st);
}  
  if(millis()-tempo>=acceso)
  {
 
    digitalWrite(LED,LOW);
   st=0;
  }

}

il led rimane sempre acceso perchè aggiorni millis() ad ogni ciclo entrando nel primo if, il problema non è tanto che st non diventa 1.

Poi usando solo 2 valori, piccolo consiglio: dichiarala booleana.

nel setup metti anche tempo = millis();

quoto, non mi ero accorto del particolare

Ciao! Ho messo la booleana, ho messo il millis nel setup ma il led rimane acceso!! Nn so veramente cm fare...

#define LED 9

int stato;
boolean st=false;
int acceso=5000;
unsigned long tempo;
void setup() {
   pinMode(LED,OUTPUT);
     tempo=millis();
   Serial.begin(9600); 
}

void loop(){
//st=digitalRead(LED);
if(st==false)
{
  digitalWrite(LED,HIGH);
 
  st=true;
  
}  
  if((millis()-tempo>=acceso)&&(st==true))
  {
    
    digitalWrite(LED,LOW);
   st=false;
  }

}

non aggiorni tempo all'interno degli if, però strano, il led dovrebbe accendersi una volta e poi rimanere spento

ps. ma ce l'hai messa la resistenza in serie al led?

No, ma perchè dovrei metterla? (scusa l'ignoranza).. cmq ho risolto mettendo millis nel setup con il led di partenza acceso e lo faccio spengere dopo 5 secondi.

ah se non vuoi fare che lampegga allora ok