Pulsanti
- Arduino partiamo da zero - n°5
Gestiamo più di un pulsante utilizzando un solo pin analogico.
Con questo post illustro come gestire più di un pulsante con un solo pin analogico vedremo i dettagli di tutto l'esperimento. Nel post n° 3 ho pubblicato una sintesi della "gestione pulsanti" utilizzata nel post del Luxmetro.
Questa versione dello sketch presenta una versione modificata per poterla utilizzare con un pin analogico.
E' semplice effettuare modifiche al programma per utilizzare più o meno pulsanti.
In questa prova ho utilizzato tre (3) pulsanti che comandano a titolo dimostrativo tre led di colore diverso.
Potreste aver bisogno di questa procedura per mancanza di pin digitali disponibili.
Per provare questo codice occorre:
Arduino Uno.
3 pulsanti normalmente aperti.
2 resistenze da 2.2 Kohm.
3 resistenze da 330 ohm.
1 resistenza da 4.7 Kohm.
1 resistenza da 47 Kohm.
3 led ( rosso, giallo, verde)
Per descrivere questo progetto dobbiamo aprire una parentesi di elettronica. ( chi sa può procedere oltre).
Il pin analogico di arduino accetta valori di tensione da 0 V fino ai 5 V della alimentazione, il convertitore interno di arduino converte i valori analogici in 1024 valori numerici interi compresi fra 0 e 1023.
Quindi per ogni numero avremo una risoluzione fra le letture di ( 5/1024) = 4,9 mV ( circa) per unità.
Realizzando un partitore resistivo si possono ottenere "N" tensioni per ogni nodo del partitore.
Partitore resistivo
La corrente I che scorre nelle resistenze è uguale Ir1 = Ir2 = I. ( le resistenze sono in serie).
La corrente I è data da I = Vin / ( R1 + R2).
Quindi Vout = R2 * I cioè Vout = R2 * V / ( R1 + R2)
Per approfondire consultate wikipedia
Nel nostro lavoro utilizzeremo 3 resistenze, con i seguenti valori:
Quindi con la formula vista vediamo le tensione che avremo in A, B, e C.
Vin = 5 V ( arduino)
In A = Vin = Vout A = 5 V
In B = Vin * (R2+R3) / ( R1+R2 + R3) = 5*(2200+4700) / (2200+2200+4700) = 3,79 V
In C = Vin * R3 / ( R1+R2 + R3) = 5* 4700 / (2200+2200+4700) = 2,58 V
Valori numerici e Volt sul pin analogico.
Come scritto più sopra per ogni valore numerico intero avremo ( 5/1024) = 4,9 mV ( circa).Di conseguenza ai 5 volt corrisponde n = 1023
per i 3,79 Volt del punto B avremo n = 3,79 / ( 5 /1024) = 776
per i 2.58 Volt del punto C avremo n = 2,58 / ( 5/1024) = 528
Facendo quindi riconoscere al nostro sketch il valore restituito individueremo anche il pulsante che è stato premuto.
I valori vanno considerati approssimati e possono variare per il valore di Vin e soprattutto per il valore delle resistenze.
Vediamo la realizzazione pratica
Questo è lo schema completo realizzato con FIDOCAD, ho riprodotto anche i collegamenti ad arduino stile Fritzing.
Ho aggiunto una resistenza da 47 Kohm fra il piedino A0 e la GND per stabilizzare la tensione a 0 V quando non vengono premuti i pulsanti.
Qui sotto lo schema di montaggio su BB.
Vediamo ora lo sketch
/* Sergio & Adriano Prenleloup 18 /04/ 2013 Pulsanti con Anolog Read V. 2.0 con questo sketch si utilizzano 3 pulsanti con un solo pin analogico. Si realizza un partitore di tensione con tre resistenze e con la pressione di un pulsante sul piedino analgico si presenterà una tensione diversa a seconda di quale pulsante è stato premuto Il programma quindi attiverà la funzione voluta dal pulsante premuto In questo caso accenderemo dei led diversi. E' possibile estendere il sistema a più pulsanti ed attivare funzioni diverse. */ // pin digitali per accendere i led int Led_Rosso = 2; int Led_Giallo = 1; int Led_Verde = 0; // pin analogico int analogPuls = A0; // pulsante numeri // i numeri sotto si riferiscono ai valori di tensione // previsti VPulsante/(5V/1024) = Numero compreso fra 0 e 1023 // I valori sono indicativi da aggiustare con i veri valori // dipendenti dalle tolleranze delle resistenze e dalla tensione // effettiva sul pin 5V. // valori centrali della tensione sul pin A0 int V_Rosso = 973; // circa 4.7 V (973+50= 1023) (973-50= 923) int V_Giallo = 776; // circa 3.8 V (776+50= 826) ( 776-50= 726) int V_Verde = 532; // circa 2.6 V (532+50= 582) ( 532-50= 482) //stato corrente dei bottoni int stato_bottoni[3]; // vettori per il controllo bottoni boolean stato_switch[3]; // variabili di controllo letture int PulsRosso = 0; int PulsGiallo = 0; int PulsVerde = 0; int val = 0; int dev = 50; // Valore che viene aggiunto e sottratto al valore // centrale di tensione dei singoli pulsanti // tale valore può essere più piccolo per aumentare // il numero dei pulsanti void setup () { // pin analogico che legge i 3 pulsanti pinMode( analogPuls, INPUT); // pin digitali dei led pinMode (Led_Rosso, OUTPUT); pinMode (Led_Giallo, OUTPUT); pinMode (Led_Verde, OUTPUT); stato_bottoni[0] = 0; stato_bottoni[1] = 0; stato_bottoni[2] = 0; digitalWrite (Led_Rosso, LOW); digitalWrite (Led_Giallo, LOW); digitalWrite (Led_Verde, LOW); } // questo codice sostituisce la "digitalRead" // dopo la lettura analogica si assegna // il valore 1 al pulsante che è stato premuto // e si mettono a 0 i pulsanti non premuti void LeggiPulsante() { val = 0; PulsRosso = 0; PulsGiallo = 0; PulsVerde = 0; val = analogRead (analogPuls); if ((val <= (V_Rosso + dev)) && (val > (V_Rosso - dev))) { PulsRosso = 1;} if ((val <= (V_Giallo + dev)) && (val > (V_Giallo - dev))) { PulsGiallo = 1;} if ((val <= (V_Verde + dev)) && (val > (V_Verde - dev))) { PulsVerde = 1;} } void aggiornaStato(int bottone, int& statoBottoneVecchio, boolean& statoSwitch) { //Si legge lo stato corrente del bottone (se premuto o no) int statoBottoneCorrente = bottone; // qui non si usa digitalRead in quanto i // pulsanti sono stati letti dalla LeggiPulsante //Se lo stato corrente del bottone è cambiato (diverso dal vecchio stato) //si deve gestire il nuovo stato if (statoBottoneCorrente != statoBottoneVecchio) { //se stiamo passando da rilasciato a premuto allora gestiamo la //logica antirimbalzo e attiviamo/disattiviamo lo swith if (statoBottoneCorrente == HIGH) { delay(15); statoSwitch = !statoSwitch; } //il nuovo stato diventa lo stato corrente statoBottoneVecchio = statoBottoneCorrente; } } void controllaPulsante() { aggiornaStato(PulsRosso, stato_bottoni[0], stato_switch[0]); aggiornaStato(PulsGiallo, stato_bottoni[1], stato_switch[1]); aggiornaStato(PulsVerde, stato_bottoni[2], stato_switch[2]); } void EseguiComandi() { //**** Gestione Led Rosso, con Pulsante Rosso if (stato_switch[0] == 1) { digitalWrite(Led_Rosso, HIGH); } else { digitalWrite(Led_Rosso, LOW); } //**** Gestione Led Giallo, con Pulsante Giallo if (stato_switch[1] == 1) { digitalWrite(Led_Giallo, HIGH); } else { digitalWrite(Led_Giallo, LOW); } //***** Gestione Led Verde con Pulsante Verde if (stato_switch[2] == 1) { digitalWrite(Led_Verde, HIGH); // accende il led } else { digitalWrite(Led_Verde, LOW); //spegne il led } } void loop() { LeggiPulsante(); controllaPulsante(); EseguiComandi(); delay (100); }
Altri sviluppi:
Io mi sono tenuto largo con le tensioni, 5V, 3.8V, 2.6V ma se occorre si possono avvicinare questi valori ed avere quindi la possibilità di utilizzare ulteriori pulsanti.nota:
La variabile " dev " nello sketch è fissata a 50 (valori numerici) corrispondono a circa 0,25V quindi rispetto al valore centrale avremo più o meno 0.25V quindi una distanza di 0.5V per ogni
pulsante ci permetterebbe di avere ben 8 pulsanti. ( da 5V fino a 1V )
Probabilmente è possibile abbassare ulteriormente questo intervallo avvicinando la distanza del voltaggio centrale dei bottoni, in questo caso occorre ridurre la variabile dev per non creare sovrapposizioni.
Scaricate qui sotto i file
sketch_Analog_pulsanti.ino
pulsantianalo.fzz
pulsantianalog.fcd
Qui sotto trovate un breve filmato dimostrativo
Attendo Vostri commenti.
Un saluto a tutti.
Sergio
Nessun commento:
Posta un commento
Vi ringrazio per la lettura e vi invito al prossimo post.
Se il post vi è stato utile, vi è piaciuto oppure no, scrivete un commento.
Un saluto a tutti.
Sergio
Copyright - Condizioni d’uso - Disclaimer
http://avventurarduino.blogspot.it/2012/10/inizia-lavventura-arduino-12-settembre.html