[RISOLTO]controllo accensione LED con pulsante

ciao a tutti sto imparando ad usare arduino e come esercizi ho iniziato da un semplice programma che premendo un pulsante (finchè il pulsate rimane premuto) si accende un LED, fino qui tutto bene.
poi ho provato a "trasformare" il pulsante in un interruttore, nel senso che quando premo il pulsante il LED deve rimanere acceso (anche se non lo tengo premuto), e quando ripremo il pulsante, il LED si deve spegnere.
ho scritto il programma e l'ho messo su arduino, solo che non funziona bene, nel senso che non sempre il LED si accende o si spegne appena premo il pulsante ma a volte è necessario premere il pulsante più volte, e poi funziona.
non so se mi sono spiegato, ora vi posto il sorgente, potete dargli un'occhiata?? per vedere se il sorgente funzionava l'ho riscritto anche in C simulando quello che facevo con arduino, e funzionava.

//accensione LED con pulsante

#define LED 13      //indica al compilatore che il LED è collegato al pin 13
#define PULSANTE 7  //indica al compilatore che il PULSANTE è collegato al pin 7

int val = 0;        //variabile per salvare lo stato del valore di input
int stato = 0;     //variabile per salvare stato 
int luce = 0;      //variabile per  indicare lo stato della luce

void setup() {
  pinMode(LED, OUTPUT);      //imposta il pin LED come output
  pinMode(PULSANTE, INPUT);  //imposta il pin PULSANTE come input
}

void loop() {
  val = digitalRead(PULSANTE);    //legge il valore in input e lo salva in val
  
  //se si preme il pulsante e la luce è spenta, stato diventa 1
  if ((val == HIGH)&&(luce == 0)) {
    stato = 1;
  }
  
  //se si preme il pulsante e la luce è accesa, stato diventa 0
  if ((val == HIGH)&&(luce == 1)) {
    stato = 0;
  }
  
  if (stato == 1) {
    luce = 1;
    val = 0;
    digitalWrite(LED, HIGH);     //accende il LED
  }
  
  else {
    luce = 0;
    val = 0;
    digitalWrite(LED, LOW);     //spegne il LED
  }

}

la variabile stato sarebbe come nel diagramma a stati finiti per indicare 2 stati (0/1) lo stato 0 spegne il LED lo stato 1 lo accende.
spero di essere stato chiaro, ma se non avete capito qualcosa chiedete pure
grazie.
potrebbe dipendere dal pulsante che ha qualche problema, magari essendo vecchio (e gli ho anche dovuto risaldare i cavi perchè non c'erano più), adesso non ho altri pulsanti da provare quindi intanto chiedo a voi se il programma funziona e se il problema può essere effettivamente il pulsante

per vedere se dipendesse dal pulsante o no, ho provato a toglierlo, e al posto suo ci ho messo 2 fili, e ho provato a simulare il pulsante facendo fare contatto ai 2 fili insieme ma fa uguale a prima, quindi non dovrebbe dipendere dal pulsante, allora da cosa può dipendere?? il programma va bene?? sennò può essere la breadboard con i contatti un po sporchi, visto che non so da quanti anni ce l'ho e non l'ho mai utilizzata??
grazie

Sembra un problema di debounce, o "antirimbalzo". Cioè, un problema di non gestione del rimbalzo. Per rimbalzo intendo i microcontatti che può fare il pulsantino se non viene premuto bene, e che fa fare delle letture errate al pin.
Cerca sul forum, si sono scritte centinaia di righe di codice ed analizzato il problema un sacco di volte.

grazie ora controllo e ti faccio sapere

Io lo ho fatto cosi'

 // ======== PROVE DifUp  ===============
 //    Rele ON OFF classico
  if (!digitalRead(Pulsante) && DifUp1 == false)
      {DifUp1 = true ;
      AuxRele = !AuxRele ;
      digitalWrite(LedTestDifUp, AuxRele); }
  DifUp1 = !digitalRead(Pulsante) ;

L'ingresso del pulsante e' impostato a HIGH e quindi il pulsante inserito fra PIN e GND ( logica NPN )
Giusto per giustificare il !digitalRead

Prova a vedere cosi'

ho risolto grazie... il problema era proprio il rimbalzo del segnale, non c'avevo pensato.
per risolvere il problema mi è bastato introdurre un ritardo quando premo il pulsante, vi posto il sorgente corretto

//accensione LED con pulsante

#define LED 13      //indica al compilatore che il LED è collegato al pin 13
#define PULSANTE 12  //indica al compilatore che il PULSANTE è collegato al pin 12

int val = 0;        //variabile per salvare lo stato del valore di input
int stato = 0;
int luce = 0;

void setup() {
  pinMode(LED, OUTPUT);      //imposta il pin LED come output
  pinMode(PULSANTE, INPUT);  //imposta il pin PULSANTE come input
}

void loop() {
  val = digitalRead(PULSANTE);    //legge il valore in input e lo salva in val
  
  //se si preme il pulsante e la luce è spenta, stato diventa 1
  if ((val == HIGH)&&(luce == 0)) {
    stato = 1;
    delay(250);  //introduco un ritardo per risolvere il problema del rimbalzo del segnale
  }
  
  //se si preme il pulsante e la luce è accesa, stato diventa 0
  if ((val == HIGH)&&(luce == 1)) {
    stato = 0;
    delay(250);  //introduco un ritardo per risolvere il problema del rimbalzo del segnale
  }
  
  //vecchio_val = val;
  
  if (stato == 1) {
    luce = 1;
    val = 0;
    digitalWrite(LED, HIGH);     //accende il LED
  }
  
  else {
    luce = 0;
    val = 0;
    digitalWrite(LED, LOW);     //spegne il LED
  }

}

ciao, è un ripiego mettere un ritardo di 250 ms detto anche "tappullo" :), quando ti ritrovi più pulsanti e più operazioni da fare ti perdi dei passaggi per strada, metti un condensatore ceramico 104 in parallelo al pulsante una resistenza di pull-down o up e non hai bisogno di nessun ritardo

ciao

pablos:
ciao, è un ripiego mettere un ritardo di 250 ms detto anche "tappullo" :slight_smile: , metti un condensatore ceramico 401 in parallelo al pulsante una resistenza di pull-down o up e non hai bisogno di nessun ritardo

ciao

Giorni fa ci fu una discussione di alcune pagine sulle tecniche antirimbalzo, aperta dalla Dany.... alla fine ha risolto con un antirimbalzo di tipo software come questo. Per piccole cose va bene anche un delay, senza stare a complicarsi tanto la vita... o no? :smiley:

Ho cercato di rileggere il post con attenzione
Visto che leggi lo stato alto del pin lo hai chiuso a GND con una resistenza ??

Il pin flottante senza una resistenza di pulldown secondo me e' deleterio
Intercetta anche le sco.... e
Nel mio esempio ho lavorato al contario sfruttando il pullup interno mettendo High il pin interessato
Ma siccome il pulldown interno non c'e ( almeno per la mia ancora scarsa conoscenza di arduino ) se si usa la logica PNP ovvero il pulsante collegato al positivo che quando premuto fornisce il positivo all'ingresso , e' indispensabile farlo esternamente

Pardon ho replicato in contemporanea a pablos

grazie pablo del consiglio adesso guardo se a casa ho un condensatore ceramico 104, sennò per ora lascio così.

ho cercato di ottimizzare un po il codice, ora è un po più pulito

//accensione LED con pulsante

#define LED 13      //indica al compilatore che il LED è collegato al pin 13
#define PULSANTE 2  //indica al compilatore che il PULSANTE è collegato al pin 2

int val = 0;        //variabile per salvare lo stato del valore di input

boolean stato = false;

void setup() {
  pinMode(LED, OUTPUT);      //imposta il pin LED come output
  pinMode(PULSANTE, INPUT);  //imposta il pin PULSANTE come input
}

void loop() {
  val = digitalRead(PULSANTE);    //legge il valore in input e lo salva in val
  
  //se si preme il pulsante e la luce è spenta, stato diventa 1
  if (val == HIGH) {
    stato = not(stato);
    delay(250);     //introduco un ritardo per risolvere il problema del rimbalzo del segnale
  }
  
  if (stato) {
    digitalWrite (LED, HIGH);     //accende il LED
  }
  
  else {
    digitalWrite (LED, LOW);     //spegne il LED
  }
}

.

Ciao a tutti gli appassionati di Arduino.
Riguardo all'uso del pulsante come interruttore, ho scritto uno sketch che permette di fare ciò in modo molto semplice.

#define led 13
#define button 2
int statoled=0;
int oldval = 0;
int newval = 0 ;
 void setup()
 {
   pinMode(led,OUTPUT);
   pinMode(button,INPUT);
 }
 void loop()
{ 
  statoled=digitalRead(button);
  if(statoled==HIGH)
  
  { 
    delay(250);
    newval=1 - oldval; 
  }

          
 if( newval==1)
{ digitalWrite(led,HIGH);
   oldval=1;}
   else {
     digitalWrite(led,LOW);
       oldval= 0 ; 
      }
      }