Buon giorno a tutti!
Per un progetto che sto sviluppando sto avendo la necessità di collegare dei pulsanti ad Arduino Uno tramite un ingresso analogico, come nello schema seguente:
In questo modo risparmio parecchi pin digitali che utilizzerò per altri collegamenti.
Fin quì tutto bene, ma ho anche la necessità che ogni volta che premo il primo pulsante 1, che come valore analogico restituisce 0, il relè1 si accenda, e se ripremo il pulsante il relè si spenga.
Questo significa che ho bisogno di un sistema che memorizzi lo stato del pulsante, lo stato del relè, e gli stati precedenti di entrambi, altrimenti avrò un relè che si accende e spegne in continuazione.
Per questo ho utilizzato il seguente codice di prova, ispirato da quello scritto da Michele Mafucci per una funzione analoga, ma non funziona come dovrebbe e dopo mille prove non so più dove sbattere la testa..
Potreste darmi una mano ad individuare il problema?
Grazie mille a chi potrà aiutarmi
// Esempio 02: accendi il led appena è premuto il pulsante mantenendolo acceso quando si rilascia
// premendo una seconda volta il pulsante spegne il led
#define relay1 11 // relè collegato al pin 11
#define pin_buttons A2 // pin analogico di input dove è collegato il pulsante
int val = 0; // si userà val per conservare lo stato del pin di input
int vecchio_val = 0; // si userà vecchio_val per conservare lo stato del pin di input al passo precedente
int stato = 0; // ricorda lo stato in cui si trova il relè, stato = 0 relè spento, stato = 1 relè acceso
void setup() {
pinMode(relay1, OUTPUT); // imposta il pin digitale come output
digitalWrite(relay1, HIGH); // spengo il relè
}
void loop() {
///////////////////////// SEZIONE PULSANTI E CONTATTI
int read_buttons = analogRead(pin_buttons);
Serial.println(read_buttons);
// controlla se è accaduto qualcosa
if ((read_buttons == 0) && (vecchio_val == LOW)){
stato = 1 - stato;
delay(15); // attesa di 15 millisecondi
}
vecchio_val = val; // ricordiamo il valore precedente di val
if (stato == 1) {
digitalWrite(relay1, LOW); // accende il led
}
else {
digitalWrite(relay1, HIGH); //spegne il led
}
}
Leggi e stampa la variabile 'read_button', osserva come varia in base alla pressione del pulsante.
Considera anche che una variazione della tensione di alimentazione si riflette sul valore di 'read_button'.
Prima di tutto, personalmente ti consiglierei di usare lo schema che ti allego, non quello che hai postato ... perche' i pulsanti, per quanto buoni siano, tendono sempre a generare rimbalzi, a meno di non usare pulsanti con contatti in gomma (che pero' in quella configurazione non puoi usare, perche' la loro resistenza di contatto varia in funzione dell'intensita' della pressione), quindi la resisitenza da 100 ohm ed il condensatore da 10nF tendono ad eliminare il piu possibile i rimbalzi ...
Seconda cosa, consiglierei di effettuare una lettura ritardata, per evitare di leggere la rampa di carica e scarica del condensatore, per quanto veloce sia (dovrebbe bastare un delay di 2 o 3 ms, che non dovrebbe influire sul funzionamento dello sketch) ... oppure campionare per variazione (quando il valore cambia, accetta il dato solo se almeno due o tre delle letture consecutive sono simili)
Per poi fare in modo che lo stesso rele' risponda allo stesso pulsante, devi usare delle variabili flag (o segnaposto), una diversa per ogni rele' ovviamente, che puoi chiamare come vuoi ed alle quali cambi stato insieme ai rele', cosi lo sketch sa in che stato e' il rele', ed il relativo ciclo if di controllo risponde solo al pulsante associato a quella flag ...
Grazie ad entrambi per avere risposto!
Non avevo pensato ai rimbalzi che potrebbero essere generati...
diciamo che mi sono chiarito un po le idee e grazie alle vostre precisazioni sono riuscito a risolvere, ecco il codice di base funzionante:
// Esempio 04: antirimbalzo2 - accendi il led appena è premuto il pulsante mantenendolo acceso quando si rilascia
// premendo una seconda volta il pulsante spegne il led
#define LED 11 // LED collegato al pin digitale 13
#define BUTTON A2 // pin di input dove è collegato il pulsante
int val = 0; // si userà val per conservare lo stato del pin di input
int vecchio_val = 1023; // si userà vecchio_val per conservare lo stato del pin di input al passo precedente
int stato = 0; // ricorda lo stato in cui si trova il led, stato = 0 led spento, stato = 1 led acceso
void setup() {
Serial.begin(9600);
pinMode(LED, OUTPUT); // imposta il pin digitale come output
pinMode(BUTTON, INPUT); // imposta il pin digitale come input
}
void loop() {
val = analogRead(BUTTON);
Serial.print(val);
Serial.print("\n");
// controlla se è accaduto qualcosa
if ((val == 0) && (vecchio_val == 1023)){
stato = 1 - stato;
delay(15); // attesa di 15 millisecondi
}
vecchio_val = val; // ricordiamo il valore precedente di val
Serial.print("VECCHIO VAL 1:");
Serial.print(vecchio_val);
if (stato == 1) {
digitalWrite(LED, LOW); // accende il led
}
else {
digitalWrite(LED, HIGH); //spegne il led
}
}