Misurare una batteria con Arduino e il partitore di tensione

Ciao a tutti!

Il post tratta di un argomento piuttosto semplice che però può tornare utile in vari progetti,
soprattutto se alimentati a batteria.
Infatti una funzione molto utile è monitorizzare lo stato della batteria per avvisarci in qualche modo del fatto che la batteria sta per terminare.



Come tutti ben saprete ogni ingresso analogico di Arduino può leggere un valore di tensione che va da 0 a 5 Volt, valore che poi viene convertito in digitale in un numero che va da 0 a 1023.
Sarà sufficiente una semplice proporzione con la funzione map per ricavare la tensione della batteria.




Quindi leggere con Arduino il valore di tensione di una batteria da 1.5 Volt è molto semplice in quanto la batteria potrà essere collegata direttamente ad un pin analogico.
Ma come facciamo a monitorare una batteria con una tensione maggiore di 5 Volt?


La risposta è anche qui semplice, è sufficiente realizzare un partitore di tensione.


Da Wikipedia:
"Un partitore di tensione è una tipologia di circuito costituito da due o più componenti passivi collegati in serie ai capi dei quali se viene applicata una tensione, essa si ripartirà sulle stesse componenti in base al loro valore."






Se le 2 resistenze hanno lo stesso valore, la tensione si ripartirà allo stesso modo su entrambe le resistenze, ad esempio:





Verifichiamo quanto detto sopra con questa formula:


Vout = Vin * R2 / (R1 + R2)


nell'esempio:

Vin = 9v
R1 = 10k
R2 = 10k

quindi:

9 * 10'000 / 20'000 = 4.5v  (valore di tensione accettabile dalle porte analog in di Arduino)

.
Da questa formula posso utilizzare anche la seguente formula inversa, necessaria ad esempio se volessi ottenere 4v da una batteria da 12v dovrei calcolare:


R2 = Vout / Vin * (R1 + R1)


Decidendo un valore di R1 + R2 = 20 kohm (valore che permette un passaggio di corrente ne troppo piccolo ne troppo grande) posso calcolare:

R2 = 4 / 12 * (20'000) = 6666.6 Ohm (approssimabile al valore commerciale 6.8 kOhm)

Quindi R1 = 20'000 - 6666.6 = 13333.4 Ohm (approssimabile a 12 kOhm)


Per ricalcolare ora quanta tensione cadrà con le resistenze che ho scelto:


V1 = I * R1

V2 = I * R2


dove:


I = Vin / (R1 + R2)


= 12 / 18'800

= 0.000638 Ampere (0.638 mA)


Quindi V1 = 0.000638 * 12000 = 7,656 V

e V2 = 0.000638 * 6800 = 4.338 V



Individuati i valori di resistenza da utilizzare vediamo finalmente come collegare il nostro circuito ad Arduino:




e questo è lo sketch da caricare:


  1. int PinBatt = A0;  
  2. int ValPinBatt;
  3. float Vpin_perc;
  4. float Vbatt;  
  5. float calc_res;
  6. float R1 = 10000; //modificare questi valori con i valori realmente utilizzati.
  7. float R2 = 10000;
  8. void setup()
  9. {
  10.   Serial.begin(9600);
  11.   pinMode (PinBatt, INPUT);
  12.   calc_res = (R1 + R2) / R2;
  13. }
  14. void loop()
  15. {
  16.   ValPinBatt = analogRead(PinBatt);
  17.   Vpin_perc = map (ValPinBatt, 0, 1023, 0, 500);
  18.   //leggerò 1023 quando ho 5 volt sul pin, quindi scalo 0-1023 in 0-500.
  19.   Vbatt = Vpin_perc * calc_res / 100 ;  
  20.   //ora divido tutto per 100 perchè sopra ho scalato da 0 a 500 anzichè da 0 a 5V
  21.   Serial.print("Tensione batteria:");
  22.   Serial.println(Vbatt);                
  23. }


Modificate i valori di R1 e R2 con quelli realmente utilizzati, poi aprite il Serial monitor per leggere la tensione della batteria.
Ricordate che una tensione maggiore di 5v potrebbe danneggiare il vostro Arduino, se avete dubbi misuratela prima con un voltmetro.

Se qualcosa non è chiaro lasciate pure un commento qui sotto,
Ciao!
Segui Daniele Alberti su Google+!

12 commenti:

  1. Innanzitutto grazie per le utilissime informazioni. Questo è il mio setup: Arduino uno con partitore di tensione 15kΩ e 6,8kΩ, per ottenere un Vin di massimo a 14.4V e un Vout di 4,5V, e un Vin di 11,8 con Vout di 3,7V. Ho impostato i valori di R1 e R2 e inizialmente il valore di Vin della batteria non corrisponde con il seriale. Ho percui cambiato nella mappatura il valore con cui scalare 0-1023 da 500 a 490 e adesso è perfetto.
    Avrei qualche domanda:
    1) perché cambiando il valore da 500 a 490 il risultato cambia?
    2) Vorrei poter attivare due pin a due determinati valori di voltaggio della batteria, che sono 11,8- high e 12,8 va in low. I pin dovrebbero comandare un semplice relay da 5v. Ho provato diversi metodi, ma non riesco a fa funzionare correttamente l'uscita dei pin.
    Se qualcuno può aiutarmi mi farebbe un enorme favore.

    RispondiElimina
    Risposte
    1. Ciao, grazie per il complimento!
      Per la prima domanda effettivamente Arduino si perde un decimo di volt, si dovrebbe riuscire a risolvere utilizzando il pin "Aref", oppure mappando a 490 come hai fatto tu. Il risultato cambia perché il "map" funziona come una semplice equazione, quando hai 1023 (diciamo 5v) il valore viene scalato a 500, se hai 4v il valore sarà circa 800. Ma se al posto di 500 metti 250 allora i valori di uscita verranno tutti dimezzati.
      Per la seconda domanda é sufficiente fare un if, se V é maggiore di 11.8 e minore di 12.8, porta alto il pin, se V é maggiore di 12.8 portalo basso.
      Ciao!

      Elimina
    2. Grazie mille per la spiegazione. Ho creato un if ottenuto da una media di 10 rilevazioni sulla tensione (in realtà sul pin analogico), ho aggiunto un delay che controlli che la tensione sia stabile prima di attivare il relay. Funziona tutto perfettamente. Non so se sia un codice ottimizzato ma funziona..
      Media A0 ottenuta tramite buffer.

      if (digitalRead(Relay))
      {
      if (Media_A0 < 594) // se media è minore di 594 che corrispondono a 11,8v.
      {
      if (millis() - delayTime > 10000) // per almeno 10 secondi
      digitalWrite(Relay, LOW); // stacca relay
      }
      else // altrimenti se tensione sopra soglia
      delayTime = millis(); // insegue contatore millis()
      }
      else
      {
      if (Media_A0 > 644) // se media è maggiore di 644 che corrispondono a 12,8v.
      {
      if (millis() - delayTime > 10000) // per almeno 10 secondi
      digitalWrite(Relay, HIGH); // attacca relay
      }
      else // se tensione sotto soglia
      delayTime = millis(); // insegue contatore millis()
      }

      Elimina
    3. Grazie mille a te per aver condiviso il tuo codice, sicuramente potrà tornare utile a molti.
      Ciao!

      Elimina
    4. Ciao ho un problema in cui mi sono bloccato. vorrei far suonare un buzzer in due momenti precisi. Il primo suono dovrebbe avvenire quando sul pin analogico c'è meno di 540 ( dovrebbe fare 3 suoni veloci di 500ms distanziati da 1000ms) e il secondo dovrebbe suonare quando sul pin analogico c'è meno di 490 (dovrebbe fare 5 suoni lenti da 800ms distanziati da 1200ms)
      Il buzzer l'ho impostato cosi:
      Tone(buzzer, 2000, 500);
      Il problema è che se anche riesco a farlo suonare ad un determinato momento di lettura del pin analogico non riesco a fargli fare 3 suoni. Sicuramente devo creare un if else per farlo suonare ad un determinata lettura dell'analogico, e lavorare con millis() per fargli fare i 3 suoni e poi farlo fermare, ma anche partendo da uno sketch nuovo simulando il pin analogico con un potenziometro, non riesco a fargli fare 3 suoni distinti, e se per caso ci riesco attraverso i millis() non riesco a farlo fermare dopo i 3 suoni e continua all'infinito, anche usando la funzione noTone()
      Qualche idea??

      Elimina
  2. Ciao e grazie! Sto cercando di usare questo progetto con arduino mega 2560 solo che mi riporta dei valori più alti, sai dirmi per caso se l'analogRead di arduino uno è diverso da arduino mega 2560? grazie in anticipo

    RispondiElimina
    Risposte
    1. Ciao, prova a misurare con un tester la tensione sul pin Analogico, e guarda se corrisponde. Ciao!

      Elimina
  3. Scrivo solo per ringraziarti delle guide, gira che ti rigira capito sempre quì a farmi un'idea chiara. Buon lavoro

    RispondiElimina
  4. Ciao Daniele,
    È già la seconda volta che "capito" sul tuo sito alla ricerca di informazioni...
    Intanto grazie per condividere in modo chiaro e dettagliato...
    Se posso vorrei chiederti aiuto per monitorare un pacco 3s formato da delle 18650...
    Se gentilmente puoi implementare quanto già scritto sopra con degli schemi e relativo codice...
    Spero di non averti chiesto troppo...
    Grazie mille Roberto

    RispondiElimina
    Risposte
    1. Ciao Roberto, una batteria al litio ha una tensione nominale di 3.7v, un pacco da 3 celle é quindi da 11.1 (3.7 x 3). Quindi sei fortunato perché rientri nel secondo esempio (R2 da 6.8k e R1 da 12k) sostituisci poi i valori nello sketch come spiegato nel tutorial. Ciao!

      Elimina
  5. Ciao Daniele,
    grazie mille per la veloce risposta...
    la mia intenzione sarebbe quella di "controllare" le 3 singole celle, dato che ho letto che può succedere (magari sono casi limite ma meglio essere cauti) che una cella si "sbilanci" e che si danneggi o peggio ancora...

    cosa ne pensi è una soluzione troppo "drastica"?
    grazie ancora
    Roberto

    RispondiElimina

Lascia un commento qui sotto, ti risponderò il prima possibile!

Related Posts Plugin for WordPress, Blogger...