Blink con millis e pulsante cosa sbaglio?

Ciao gruppo, sto provando un blink con millis.

Però non capisco cosa sbaglio, se creo il blink senza pulsate è tutto ok, il led lampeggia, ma e inserisco un pulsate, ottengo che il led resta fisso, mentre secondo me dovrebbe lampeggiare, non capisco perchè non lo fa cosa sbaglio?

Ho fatto anche la prova con 2 led, così da vedere un led che lampeggia ed uno che viene comandato dal pulsante, questo fa solo on ed off senza lampeggio.

#define pulsante 4
#define led 10
#define led2 6
#define intervallo 300

int stato = LOW;
int statoP = LOW;
int stato2 = LOW;
unsigned long t0, dt;

void setup(){
  pinMode(led, OUTPUT);
  pinMode(pulsante, INPUT);
  t0 = millis();
  Serial.begin(9600);
}

void loop(){
  prova_blink();
  prova_pulsante();
}
void prova_blink(){
  dt= millis() -t0;
      if( dt >= intervallo){
        t0 = millis();
        stato = !stato;
        digitalWrite(led, stato);
      }
}
void prova_pulsante(){
  while(digitalRead(pulsante)==HIGH){
    statoP=!statoP;
    delay(50);
    if(statoP == HIGH){
      dt= millis() -t0;
      if( dt >= intervallo){
        t0 = millis();
        stato2 = !stato2;
        digitalWrite(led2, stato2);
      }
    }
    }
  }

Grazie per il possibile aiuto.
Un buon week end a tutti :slight_smile:

Come è collegato il pulsante?

Guglielmo

  1. C'è una resistenza di pull down?
  2. Per tutto il tempo in cui il pulsante è premuto, statoP cambia ogni 50ms.

Vi allego il link di tinkercad, ovviamente ho fatto la prova su Arduino con basetta di prova ed ottengo lo stesso effetto, anche il led che emette pochissima luce (quello sotto pulsante), mentre l'altro fa una luce normale.

Rispetto allo sketch postato in precedenza, nel simulatore ho spostato il delay dopo la pressione del pulsante prima del cambio statoP, aumentandolo a 100ms

Dimenticavo resistenza in pullman-up da 10K

https://www.tinkercad.com/things/eLKNj4faPuJ

C'è un while(digitalRead(pulsante)==HIGH) che blocca il resto del codice, che altro dovrebbe fare? :wink: :wink:

Per quanto riguarda il led2, hai dimenticato di dichiararlo come uscita

Ho sostituito while con if, ma sempre lo stesso risultato ottengo :frowning:
Inoltre ho creato due variabili per il tempo, una per ogni led, sperando di risolvere, ma nulla non lampeggia il led2, ne con la sua variabile tempo, ne con quella in comune all'altro led

#define intervallo 250
#define intervallo2 250
#define led 10
#define led2 6
#define pulsante 4

int stato = LOW;
int statoP = LOW;
int stato2 = LOW;
unsigned long t0, dt;
unsigned long t1, dt1;

void setup() {
  pinMode(led, OUTPUT);
  pinMode(pulsante, INPUT);
  pinMode(led2, OUTPUT);
}
void loop(){
  dt = millis() - t0;
  dt1 = millis() -t1;
  if( dt >= intervallo){
    prova_blink();
    }
  prova_pulsante();
  }
    void prova_blink(){
        t0 = millis();
        stato = !stato;
        digitalWrite(led, stato);
      }

void prova_pulsante(){  
  if(digitalRead(pulsante)==HIGH){
    delay(100);
    statoP=!statoP;
    if(statoP==HIGH){
        stato2 = !stato2;
      if( dt1 >= intervallo2){
        t1=millis();
        digitalWrite(led2, stato2);
      }
      }
      }
    }

Non è mica chiaro cosa dovrebbe fare il pulsante.

1 Like

In pratica vorrei creare un lampeggio del led indipendente dal pulsante (quello chiamato led), poi un secondo led, led2, che dovrebbe lampeggiare comandato dal pulsante, quindi premo il pulsante e inizia il lampeggio del led2 finché non ripremo per spegnere.
Invece led2 rimane o spento o acceso fisso.

La tua descrizione non è esaustiva :

La cadenza dei lanpeggi dei due led è uguale?

E la loro fase

A seconda delle risposte il problema puo essere risolto facilmente o difficilmente

Ciao, sto cercando di capire meglio come funziona millis(), la mia idea era questa:
un led lampeggia sempre, il secondo deve lampeggiare quando premo il pulsante e spegnersi quando lo ripremo (il pulsante deve avere uno stato).
Volevo solo capire come fare, a prescindere se devono avere la stessa cadenza o no, se ho capito bene se uso dt, t0 e stato per entrambi dovrebbero avere la stessa frequenza di lampeggio, viceversa se aggiungo altre due variabili per millis(), quindi dt1 e t1 posso avere due lampeggi indipendenti ovviamente dovrei aggiungere anche una seconda variabile stato per il secondo led.
Correggimi se sbaglio.

Non capisco però perchè sotto pulsante non avviene il lampeggio, non capisco dove sbaglio.

Fai una funzione che seleziona lo stato e un'altra che accende e spegne il LED ogni volta che è trascorso il tempo dipendente dallo stato. Nel loop ci saranno solo queste due funzioni.

A quel punto puoi facilmente fare le verifiche opportune per stabilire dov'è l'errore, per esempio forzando lo stato a un valore fisso, oppure facendo in modo che il LED non lampeggi, ma si accenda o si spenga a ogni pressione del tasto.

Potresti anche fare due o tre funzioni diverse per il pilotaggio del LED, che possono anche avere lo stesso nome mettendo come commento quelle disattivate.

Bene, e questo l'hai fatto.

il secondo deve lampeggiare quando premo il pulsante e spegnersi quando lo ripremo (il pulsante deve avere uno stato).

Esatto ci sono due diverse fasi di funzionamento, e il pulsante fa passare da una all'altra.

Non capisco però perchè sotto pulsante non avviene il lampeggio, non capisco dove sbaglio.

Il cambio di stato avviene, ma poi se rilasci il pulsante la parte di codice che dovrebbe controllare il timeout per il lampeggio del secondo led non viene più eseguita, perché è scritta dentro l'if del pulsante.

Grazie ragazzi, seguendo i vostri consigli ho capito l'errore, almeno spero :sweat_smile:
Ho riscritto da zero il codice seguendo i consigli ed adesso funziona, quindi credo di averlo scritto in maniera corretta oppure ho avuto fortuna :joy:

Ho inserito led3, per capire pure la differenza di funzione con e senza else, in pratica il led3 rimane all'ultimo stato che ha alla pressione del pulsante, mentre led2 essendo dentro else ritorna in LOW.

Grazie ancora per i consigli :slight_smile:

#define intervallo 250
#define led 10
#define led2 6
#define led3 5
#define pulsante 4
int stato = LOW;
int statoP = LOW;
unsigned long t0, dt;

void setup() {
  pinMode(led, OUTPUT);
  pinMode(pulsante, INPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

void loop(){
  dt = millis() - t0;
  if( dt >= intervallo){
    t0 = millis();
    stato = !stato;
  }
  prova_lampeggio();
  prova_pulsante();
}
  void prova_lampeggio(){
        digitalWrite(led, stato);
  }
    
  void prova_pulsante(){  
    if(digitalRead(pulsante)== HIGH){
    delay(300);
    statoP=!statoP; 
    }
    if(statoP == HIGH){
      digitalWrite(led2, stato);
      digitalWrite(led3, !stato);
    }
    else (statoP == LOW);
      digitalWrite(led2, LOW); 
  }

Resta quel blocco iniziale nel loop che serve solo per far lampeggiare il LED, quindi andrebbe nella funzione relativa:

  void prova_lampeggio(){
    if(millis()-t0 >= intervallo){
      t0 = millis();
      stato = !stato;
      digitalWrite(led, stato);
    }
  }

Neanche questo ho capito

Sì... else (statoP == LOW); non significa nulla. Basta else, dato che LOW è l'unica alternativa.

Poi, in caso di else, led3 rimane paralizzato...

Anche quel delay(300) è veramente brutto... Se proprio vuoi fare l'antirimbalzo software, prendi il tempo in uint32_t t_antirimb e leggi il pulsante solo se millis()-t_antirimb è maggiore di 300ms.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.