Voltmetro con arduino e lettura su partitore di tensione

Salve a tutti ragazzi, voglio costruire un voltmetro 0-70 VDC con partitore resistivo,
dove R1 = 560Kohm e R2 = 27Kohm
quindi in andata all'input analogico di arduino avremo un'uscita che varia da 0V a 3,220V
ovviamente non utilizzo un partitore che mi faccia andare direttamente all'input analogico 5V ma mi mantengo al di sotto per garantirne la sicurezza in modo che se la tensione dovesse superare i 70 volt non brucio il pin dell'arduino, il problema adesso sta nella "decodifica" del valore letto
come faccio a far visualizzare su un lcd la tensione letta?...l'lcd lo so gestire...è la parte di conversione che non riesco a fare....chiedo aiuto a voi....vi ringrazio in anticipo per le risposte. un saluto

Devi usare l'analogRead per leggere la tensione sul pin e convertirla in un valore a 10 bit, cioè compreso fra 0 e 1023.
1023 equivale ovviamente alla lettura abbinata ai 5V dell'Arduino ma la tua lettura massima sarà inferiore visto che fornisci una tensione massima di 3,22V.
Letto il valore, devi fissare il massimo con dei test, fornendo al partitore il massimo di tensione (70V) e vedendo cosa ti "sputa" fuori la lettura analogica.
A quel punto, con una proporzione matematica converti la lettura in tensione.

C'è però il problema della risoluzione. Con 10 bit ed una tensione in ingresso compresa fra 0 e 3,22V hai una risoluzione minima non molto elevata. Se non ti interessa la precisione al millesimo di volt... :wink:

Visto che serve una certa corrente per caricare il condensatore sample and hold interno del convertitore analogico digitale del ATmega il Tuo partitore ha un impedenza troppo alta. Usa un operazionale come inseguitore di tensione per alzare l'impedenza di entrata.

Ciao Uwe

potrei anche ridurre l'impedenza mantenendo gli stessi valori di tensione in ingresso....ad esempio 56K e 2,7K o 560ohm e 27 ohm...sempre 3,22V erogano...il problema reale ce l'ho nella "proporzionale matematica"... :slight_smile: leo72, mi potresti far vedere qualche esempio utilizzando le resistenze del partitore come "resistenze ideali" e quindi esatte senza errori del 5% ecc...poi farò le varie prove confrontando con un multimetro per settare correttamente il tutto...a parte che in matematica non sono molto ferrato... XD comunque mi è più che sufficiente una lettura di xx,xx Volt anche se non è precisissima...ma in linea di massima...grazie intanto per l'aiuto...

La proporzione la devi fare sul valore letto, lascia stare le R :wink:
Devi leggere con l'analogRead il valore che corrisponde ai 70V, questo è il valore max di riferimento.
Mettiamo che sia 800 per convenienza.
A questo punto sai che la lettura 0-800 indica una tensione 0-70V.
Usa la map e risolvi:

tensione = map(lettura, 0, 800, 0, 70);

Ho letto il reference sulla map....non ho capito cos'è 800....forse ho intuito, ma preferisco una conferma da parte tua...dunque considerando sempre resistenze ideali 3,22V è il 64,4% di 5V quindi 775 è il 64,4% di 1024....intendevi questo con 800? quindi facendo:
tensione = map(lettura,0,755,0,3.22);
dovrei avere la corrispondente...adesso mi sorge un dubbio...così io sto specificando che il 3,22V è pari a 755 e 0 è pari a 0..giusto?...ma per la lettura di tensione come dovrei comportarmi? devo scrivere qualcosa che mi interpreti la lettura convertendomela nel mio valore in volts...in questo caso applicando la tensione di 3,22 all'input analogico avrei che la tensione fornita all'input fa valere la lettura analogica 755 e quindi il parametro lettura restituisce un valore di 3,22 giusto? ma se io utilizzassi
tensione = map(lettura0,755,0,70.00);
avendo la stessa tensione in ingresso (da 0 a 3,22 e quindi da 0 a 755), questa volta non avrei un valore che va da 0 a 70V?
intanto ho trovato anche questo che utilizza il partitore: http://arduinoprojects101.com/arduino-voltmeter/
grazie ancora per l'aiuto...

Sí, i 800 erano il valore letto dal convertitore presunto.

Se il partitore porta i 70V a 3,22 V puoi anche scrivere:

tensione = map(lettura0,755,0,70.00);

comunque sei consapevole che riesci solo a leggere i decimi di V?

Ciao Uwe

@peppe:
800 era un valore indicativo, l'avevo specificato :wink:
Invece hai ragione tu sui 3,22V. Dovevo mettere 70.0V perché tu vuoi la lettura nell'intervallo 0-70V.

si uwefed, ne sono consapevole, per l'applicazione in cui verrà utilizzato non sono importanti centesimi ecc... :slight_smile: quindi va benissimo così grazie 1000;)
leo grazie 1000 ancora per l'aiuto, e grazie soprattutto per avermi fatto scoprire la funzione map...a me ignota e a quanto pare ignota anche ai manuali su arduino letti fino ad ora... :wink: un saluto e un sincero grazie a tutti voi che mi avete aiutato... buonanotte.

su http://arduino.cc/en/Reference/HomePage trovi un bel po di funzioni C. Tanti altri sono del C e percui devi consultare un Tutorial o libro di C.

Ciao Uwe

salve ragazzi, ho quasi finito, ma ho un problema...mi sono accorto con il map che va con i numeri interi....ma io vorrei visualizzare almeno il mezzo volt ecc... quindi ho deciso di fare così ad esempio:

const int partitore = A0;
float voltage = 0.00;

void loop(){
lettura = analogRead(partitore);
voltage=(50/1024)*lettura //50 sono i volts di soglia che utilizzo...l'ho abbassata per aumentare la precisione
}

presumo sia corretto...ma non capisco perchè mi visualizza solo numeri interi con la virgola tipo 20.00 ....come posso fare per fargli visualizzare anche i decimali con una discreta precisione? grazie in anticipo...un saluto

edit by mod:
per favore usa gli appositi tag per includere il codice

Devi specificare espressamente i float:

voltage=(50.0/1024.0)*(float)lettura

Il ".0" dice che il numero è un float, mentre il casting di lettura lo fai da (float)

per una risoluzione maggiore ponticella 3V3 con AREF e metti nel setup()

analogReference(EXTERNAL)

La formula diventa:

const int partitore = A0;
float voltage = 0.00;

void loop(){
lettura = analogRead(partitore);
voltage = (3.3 * lettura / 1024.0); // restituisce i volt letti dall'ingresso analogico
voltage = voltage * (50 / 3.3) + 0; // scala il valore nell'intervallo 0-50V

Naturalmente i passaggi possono essere contratti e diventa:

voltage = lettura / 20.48; // restituisce i volt

Che diventa insensibile al riferimento usato ma in base ad esso aumenta la risoluzione della scala.

PaoloP:
per una risoluzione maggiore ponticella 3V3 con AREF e metti nel setup()

analogReference(EXTERNAL)

Non capisco come un cambio del riferimento potrebbe cambiare la risoluzione.
Se con un partitore resistivo porti i 50 V a 5 o a 3,3V e usi come riferimento 3,3V la risouzione non cambia.
Cambia la precisione perché i 3,3V sono piú precisi rispetto ai 5V e una sovvratensione puó essere maggior prima di rompere l'Arduino. L' entrata analogica resiste sempre fino a ca 5V. con un partitore 50/5 c'é poco gioco. Con un partitore 50/3,3 la tensione puó arrivare fino a 75V.

Ciao Uwe

Io intendo per risoluzione la minima differenza misurabile. Quindi se passi da un fondo scala di 5V ad un fondo scala di 3V3, sempre dividendo in 1024 step, avrai una maggiore risoluzione perché diventa più piccolo l'intervallo misurabile. Aumenti la sensibilità dello strumento.
La precisione, invece, indica quanto ci si avvicina al valore della misura, ovvero più preciso è una lettura minori saranno le differenze tra i vari valori misurati.

PaoloP:
Io intendo per risoluzione la minima differenza misurabile. Quindi se passi da un fondo scala di 5V ad un fondo scala di 3V3, sempre dividendo in 1024 step, avrai una maggiore risoluzione perché diventa più piccolo l'intervallo misurabile. Aumenti la sensibilità dello strumento.
La precisione, invece, indica quanto ci si avvicina al valore della misura, ovvero più preciso è una lettura minori saranno le differenze tra i vari valori misurati.

Ok, ma se comunque devi usare un partitore resistivo per arrivare ai 5V non cambia niente dal punto di vista della risoluzione se usi 3,3V perché usi giá tutto il range di misura del ADC.

Ciao Uwe

Consiglio di inserire uno zener da 5.1V in parallelo all'ingresso analogico per proteggerlo da eventuali falsi contatti del partitore.

Per la risoluzione è possibile aumentarla a 12 bit con la tecnica dell'oversampling + decimazione.

Come al solito non avete chiari i concetti di precisione e risoluzione, la prima è un valore percentuale e indica di quanto può discostarsi la misura dal valore reale, dipende esclusivamente da come è fatto l'ADC, la risoluzione non è la tensione minima misurabile, è il numero di bit che compongono la misura e di conseguenza in quanti step può essere divisa, una elevata risoluzione non significa necessariamente avere uno strumento molto preciso.
Cambiare il valore di riferimento del ADC non modifica in nessun modo ne la precisione ne la risoluzione, cambia solo il range di tensione entro il quale viene fatta la misura, semmai è possibile aumentare la risoluzione tramite oversampling, però è un metodo che ha anche dei contro e non sempre è applicabile.

astrobeed:
Cambiare il valore di riferimento del ADC non modifica in nessun modo ne la precisione ne la risoluzione, cambia solo il range di tensione entro il quale viene fatta la misura, semmai è possibile aumentare la risoluzione tramite oversampling, però è un metodo che ha anche dei contro e non sempre è applicabile.

Non sono del tutto d' accordo. Cambiare la fonte di riferimento dalla tensione di alimentazione a i 3,3V o 1,1V interni puó in certi casi migliorare la precisione e/o la risoluzione.

Visto che la tensione di alimentazione a secondo della fonte di alimentazione (PC, alimentatore esterno, Stabilzzatore 5V esterno, batteria con o senza convertitore DC/DC ecc) non é sempre precisamente 5V, ma puó discostarsi anche di 0,5V se misuro tensioni che non derivano con un partitore resistivo dall'alimentazione (per esempio tensioni che arrivano da un sensore e non dipendono dalla tensione di alimentazione esempio tipico un LM35 che da 10mV per °C) misuro dei valori sbagliati se presumo la tensione di riferimento 5V. In questo caso se la tensione del sensore lo permette aumento la precisione se uso i 3,3V o i 1,1V interni come riferimento. Al limite tenendo conto del l' impedenza interna del circuito sample and hold del ADC posso usare un partitore resistivo per abbassare la tensione del sensore. Posso sempre usare un operazionale con un guadagno minore di 1 per abbassare la tensione da misurare.

Nel caso che la tensione del sensore dipende dalla tensione di alimentazione (per esempio LDR o NTC/PTC con resistenza) usando una tensione di riferimento diversa dalla tensione di alimentazione perggioro la precisone, perche usando la tensione di alimentazione sia come riferiemnto che come alimentazione del sensore mi si cancella l' errore introdotto da una tensione di alimentazione variabile.

Posso aumentare la risoluzione (aumentare il numero di ADC per misurare una tensione) nel caso che la tensione da misurare é piccola. Posso usare un'alimentazione di riferimento minore (i 3,3V o 1,1V interni) e cosí ottenere un valore maggiore di ADC e percui un numero maggiore di passi intermedi. La stressa cosa ottengo se amplifico il segnale del ensore per esempio con un operazionale. In tutti i due casi diminuisco il range di misura.

La tensione di alimentazione del ATmega168/328 puoi misurarla con: http://code.google.com/p/tinkerit/wiki/SecretVoltmeter

Ciao Uwe

uwefed:
Non sono del tutto d' accordo. Cambiare la fonte di riferimento dalla tensione di alimentazione a i 3,3V o 1,1V interni puó in certi casi migliorare la precisione e/o la risoluzione.

Se per migliorare la precisione intendi che utilizzando il generatore interno hai una tensione di riferimento con meno rumore rispetto a Vdd, sopratutto se arriva da USB, sono d'accordo, ma solo perché riduci un fattore di disturbo esterno, non perché migliora la precisione del ADC, questa è una costante e dipende dalle caratteristiche del ADC stesso.

Visto che la tensione di alimentazione a secondo della fonte di alimentazione (PC, alimentatore esterno, Stabilzzatore 5V esterno, batteria con o senza convertitore DC/DC ecc)

Qui stai facendo confusione tra la precisione e il valore assoluto del riferimento, la prima non è in alcun modo legata alla seconda, va da se che per fare una conversione precisa tra count e tensione equivalente è indispensabile conoscere in modo preciso il valore di tensione di riferimento, ovvero o usi un generatore campione di precisione, esistono appositi componenti, oppure si misura con un multimetro il suo valore.

In questo caso se la tensione del sensore lo permette aumento la precisione se uso i 3,3V o i 1,1V interni come riferimento.

Se controlli sul data sheet scoprirai che il valore di tensione del riferimento interno ha una grossa tolleranza, molto difficilmente è 1.1 V esatti, idem vale per i 3.3 V che per giunta sono soggetti a fluttuazioni dovute ad un eventuale utilizzo come fonte di alimentazione.
Per farla breve, se vuoi fare una conversione precisa è sempre necessario misurare l'esatto valore di Aref e introdurlo come dato nel software, oppure utilizzare un riferimento di precisione.