Aumentare precisione con analogRead

Non sapendo se rientra in software oppure hardware... scrivo qui.

Ho letto da qualche parte che a causa di come e' stato implementato il ADC, la tecnica software per aumentare la precisione di analogReader e' di aggiungere un delay. Io mi sono scritto una nota tra i miei documenti: analogread;delay;analogread;

Non trovando pero' il sito originario, vorrei chiedere conferma se il codice sottostante e' corretto, ma sopratutto il perche'. (serve eventualmente un' ulteriore delay dopo il secondo analogread ?

  a = analogRead(0);
  delay (10);
  a = abalogRead(0);

Parli di anologread e poi scrivi nel code digitalread :)

comunque se dovessi leggere 16 analog con un delay per ogni porta morirei dalla noia quello che dici tu io non l'ho mai visto, piuttosto ho visto campionamenti nel loop, ad ogni passaggio viene preso il valore di tutte le analog che ti servono, si piazzano in un array e ogni 10 o 20 loop analizzi i dati, fai la media dei valori registrati e svuoti l'array, ricominciando da capo

oppure altro metodo perditempo, sempre meno del tuo, usando un for registrando sempre in un array, la differenza da quello sopra è che viene fatto nello stesso ciclo loop

Ho corretto l'errore !

Io sto parlando di un problema dovuto a come e' stato implementato l' ADC per colpa del quale la prima lettura, viene sballata.

Ho dato uno sguardo alla reference e da lì non risulta che la prima lettura di analogRead() non sia affidabile. Ciò che dici potrebbe capitare se si cambia il riferimento della tensione tramite analogReference() e solo per le prime letture.

Se dai uno sguardo allo schematico http://tinyurl.com/6o5socv, noterai un capacitore da 100nF collegato al pin Aref che serve per stabilizzare (solo un po’) la tensione. Quando cambi il valore della tensione di riferimento, questo capacitore dovrà caricarsi o scaricarsi e per farlo impiegherà un certo tempo. Qui (http://tinyurl.com/cj5gk7z) trovi una discussione con i grafici con le simulazioni per una variazione di Aref da 5V a 1.1V. Tenendo conto che sul pin Aref c’è un resistore da 32K e facendo i conti vien fuori che per scaricare C4 e arrivare ad Aref = 1.1V partendo da 5V ci vorranno 4.8ms.

Inoltre in quella stessa discussione millis scriveva che arduino non cambia Aref fino a che non viene chiamata analogRead().

analogReference(INTERNAL); //cambia da 5 a 1.1
analogRead(); //comincia la scarica
delayMicroseconds(50000); //attendi che la tensione si stabilizzi

Occhio comunque che in tutto questo discorso non si tratta né di accuratezza né di precisione della misura mentre la risoluzione, ovviamente, varia con Aref.

acik:
Io sto parlando di un problema dovuto a come e’ stato implementato l’ ADC per colpa del quale la prima lettura, viene sballata.

la tecnica del sovracampionamento è comunque raccomandata dalla stessa Atmel per gli AVR:

http://www.atmel.com/Images/doc8003.pdf

acik: Non sapendo se rientra in software oppure hardware... scrivo qui.

Ho letto da qualche parte che a causa di come e' stato implementato il ADC, la tecnica software per aumentare la precisione di analogReader e' di aggiungere un delay. Io mi sono scritto una nota tra i miei documenti: analogread;delay;analogread;

Non trovando pero' il sito originario, vorrei chiedere conferma se il codice sottostante e' corretto, ma sopratutto il perche'. (serve eventualmente un' ulteriore delay dopo il secondo analogread ?

  a = analogRead(0);
  delay (10);
  a = analogRead(0);

Ci sono 2 effetti distinti. 1) Il convertitore analogico-digital che é nel ATmega ha circuito sample and hold che carica un condensatore per un certo intervallo di tempo per fare la conversione della tensione del condensatore. Se la impedenza della sorgente del segnale da misurare é troppo alta (parliamo di 10kOhm) il condensatore non viene caricato del tutto nella prima conversione. Per questo ripetendo la misura piú volte (caricando il condensatore piú volte una dopo l'altra) si riesce a caricare il condensatore alla tensione finale e percui misurare la tensione giusta.

2) il oversampling Si misura piú volte il segnale e poi si divide non per il numero di misure ma di un numero minore: Esempio: 16 misure e si divide per 4 e si ottiene un risultato da 12 bit.

Ciao Uwe

Uwe, una cortesia, puoi spiegare in modo più approfondito questa cosa, non l'ho capita bene, di solito faccio 10 misure, le sommo e le divido x10, quindi calcolo una media pura, immagino di restare sempre nei 10 bit dell'ADC. Non ho capito invece questa tua tecnica e non ho capito come diventano 12 bit. Ricordo che moltissimo tempo fa Astro parlò di una tecnica per portare la precisione dell'ADC a 12 o anche a 14 bit, è quello di cui parli o è qualcosa di diverso? Grazie

Oggi nella reference ho trovato un' altro esempio...

http://arduino.cc/en/Reference/DoWhile (// wait for sensors to stabilize)

Potrebbe benissimo essere la capacita' sull' ingresso dell ADC nel caso in cui la tensione da misurare arriva da una uscita ad alta impedenza...

Cercando "analog sample and hold" qualcosa si trova, ma prendere 16 campioni e dividere per 4, non l'ho capita nemmeno io. Spiegaci spiegaci uwefed.

bye

[quote author=Michele Menniti link=topic=115362.msg869894#msg869894 date=1343078147] Ricordo che moltissimo tempo fa Astro parlò di una tecnica per portare la precisione dell'ADC a 12 o anche a 14 bit, è quello di cui parli o è qualcosa di diverso? [/quote]

Application note AVR121 di Atmel e trovi tutti i dettagli della cosa e i limiti in cui è applicabile.

EL34: la tecnica del sovracampionamento è comunque raccomandata dalla stessa Atmel per gli AVR:

Non è raccomandata da Atmel, e da nessun produttore, è solo una tecnica matematica applicabile a qualunque ADC a patto che il segnale rispetti certe condizioni e solo nel caso in cui non sia possibile utilizzare un ADC con risoluzione maggiore, quel documento spiega in modo abbastanza dettagliato come funziona e quali sono i prerequisiti. L'utilizzo del oversampling e decimazione richiede un pesante prezzo in termini di banda e tempo cpu, è da usare solo se non ci sono altri modi e solo dopo aver ben valutato pro e contro. Da notare che tale tecnica permette solo di aumentare la risoluzione del ADC, la precisione rimane invariata.

Grazie Astro, me lo vado a cercare questo documento, mi interessa capire bene la tecnica, i pro ed i contro; mi è chiaro che è solo un miglioramento della risoluzione, che a volte si confonde con la precisione.

penso di aver capito: se mantenessi il segnale con tensione costante,e misurassi Xes due volte,potrei avere : xxxxxxx0 e xxxxxxx0,quindi la tensione potrebbe essere nell'intorno di Xe 2volt xxxxxxx1 e xxxxxxx1,quindi la tensione potrebbe essere nell'intorno Xes di 3 volt xxxxxxx1 e xxxxxxx0,quindi la tensione potrebbe essere nell'intorno Xes di 2.5 volt e se reiteri la misura x 2^N volte,ottieni una risoluzione di [risoluzione misura]+N ,no?

Xò aspetta: non sarebbe meglio mescolare all'ingresso un segnale,eventualmente pseudocasuale,equidistribuito?

Aggiungo una nota:

Nell' esempio AnalogInOutSerial, alla fine c'e':

// wait 10 milliseconds before the next loop // for the analog-to-digital converter to settle // after the last reading: delay(10);