giovedì 18 aprile 2013

Pulsanti /2

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