Domanda:
Quale valore utilizzare per convertire il valore dell'ADC in tensione?
jparenas
2017-02-16 22:55:43 UTC
view on stackexchange narkive permalink

Mentre lavoravo al mio progetto, sono arrivato a un punto in cui non conosco la risposta.Ho un ADC a 10 bit (quello incorporato nell'ATMEGA328P) e restituisce valori fino a 1023 (2 10 - 1).

La documentazione ufficiale afferma che l'equazione per convertire i valori dall'ADC alla tensione corrispondente è:

$$ V = \ frac {V_ {in} \ cdot ADC} {2 ^ {10}} $$

Ma, se i valori salgono a 1023, non sarebbe meglio sostituire 2 10 con 2 10 - 1?

Grazie.

Non importa.Il poster è corretto.Oppure, se vuoi, il poster è corretto PERCHÉ uno dei 1024 valori ADC è zero.
@FakeMoustache Se 0 fosse diviso per 1023, restituirebbe 0, come se fosse diviso per 1024. Ma se 1023 (il valore massimo ottenibile) fosse diviso per 1024, sarebbe diverso dalla divisione per 1023. Se il valore massimoche può essere restituito è 1023, non sarebbe meglio essere diviso per 1023?
Cinque risposte:
Spehro Pefhany
2017-02-17 04:10:26 UTC
view on stackexchange narkive permalink

Ignorando la dura realtà delle prestazioni degli ADC che possono essere integrati a buon mercato negli MCU, nel caso ideale ogni conteggio di output rappresenta un possibile range di tensioni di ingresso ben definite.

Ecco un ADC a 3 bit ideale (secondo la definizione di Atmel).

enter image description here

Sono presenti \ $ 2 ^ N \ $ passaggi. Nell'esempio sopra, questo è 8. Con un ADC unipolare ideale, un input inferiore a \ $ \ frac {V_ {REF}} {2 ^ {N + 1}} \ $ darà un output di 0- come tu può vedere sopra, sotto 1/16 della tensione di riferimento 2V il codice di uscita sarà 0.

Tra \ $ \ frac {V_ {REF}} {16} \ $ e \ $ \ frac {V_ {REF}} {16} + \ frac {V_ {REF}} {8} \ $ il conteggio dell'output sarà 1 e così via, con ogni passaggio uguale.

Quando si arriva alla parte superiore dell'intervallo, un conteggio di \ $ 2 ^ N-1 \ $ (conteggio massimo) rappresenterà una tensione maggiore di \ $ V_ {REF} \ cdot \ frac {13} {16 } \ $.

Quindi, best guess (minimizzando l'errore) per un dato conteggio x (dove \ $ 0 \ lt x \ lt 2 ^ {N-1} \ $) è \ $ x \ frac {V_ {REF}} { 2 ^ {N}} \ $, come indicato nella domanda originale.


Di solito gli ADC MCU si saturano, quindi idealmente nel caso speciale di x = 0 si può dire che la tensione di ingresso è inferiore a \ $ 0,5 V_ {REF} \ cdot \ frac {1} {2 ^ N} \ $ = \ $ V_ {REF} \ cdot \ frac {1} {2 ^ {N + 1}} \ $ e se x = \ $ 2 ^ {N-1} \ $ la tensione di ingresso è maggiore di \ $ V_ {REF} \ cdot \ frac {2 ^ {N + 1} -3} {2 ^ {N + 1}} \ $


Ovviamente con un tipico MCU di 10 bit o superiore, l'errore e il rumore dell'ADC di solito supereranno 1 LSB, e Vref di solito non sarà accurato nemmeno a 1 LSB, quindi non importa molto.


TL; DR

Usa l'equazione originale.

Hahahha che TL; DR
Dirceu Rodrigues Jr
2017-02-18 22:26:51 UTC
view on stackexchange narkive permalink

jparenas, questa è una domanda che torna regolarmente, essendo fonte di confusione quando si lavora con gli ADC. È strettamente correlato alla classica confusione: Full Scale Voltage (FS) rispetto a Reference Voltage (Vref). Per mantenere le cose semplici, si prega di considerare un ipotetico ADC a 3 bit (\ $ N \ $ = 3), senza la compensazione comune di 0,5 LSB sull'ingresso (come, penso, si verifica su ATmega328p) - in tal caso, i risultati ottenuto qui non differisce molto. Tre parti:

(a) Vedere la funzione di trasferimento (a) nell'immagine sottostante, dove Va è la tensione analogica e Vd è il valore digitale convertito. FS è solo la tensione che corrisponde alla transizione al valore digitale massimo (7 o \ $ 2 ^ N-1 \ $). Inoltre, ci sono sette passaggi in orizzontale e sette in verticale, in cui ogni passaggio si verifica in multipli di 1/7 FS. Sia FS = 4,375 V, quindi ogni passo analogico è 0,625 V. Si noti che la linea tratteggiata inclinata che collega le coordinate (0; 000) a (FS; 111) rappresenta la conversione ideale che ogni ingegnere vorrebbe. Quindi:

$$ Vd = int \ left (\ frac {Va} {FS} \ times 7 \ right) $$

Qui possiamo isolare Va per trovare una semplice espressione it:

$$ Va = \ frac {Vd} {7} \ times FS $$

Ma aspetta! Le cose non sono così semplici: per essere più rigorosi, possiamo vedere che la tensione Va può effettivamente assumere qualsiasi valore all'interno di un intervallo. Applicando la definizione di \ $ int () \ $ funzione:

$$ \ frac {Vd} {7} \ times FS \ leq Va < \ frac {(Vd + 1)} {7} \ times FS $$

(b) Ora vedi la funzione di trasferimento mostrata in (b). Nota che se ci fosse un altro passo aggiuntivo di 1/7 FS, potremmo associarlo a un valore digitale completo di 8 (o \ $ 2 ^ N \ $). Ecco! Chiamiamolo Vref:

$$ Vref = \ frac {8} {7} FS $$

Nota che, per il nostro FS = 4.375 V \ $ \ Rightarrow \ $ Vref = 5 V. Vedi l'espressione \ $ FS = \ frac {7} {8} Vref \ $. È un altro modo per affermare che FS rimane 1 LSB sotto Vref. Non ha importanza qui, ma per ADC con compensazione in ingresso di 0,5 LSB, FS sarebbe 1,5 LSB sotto Vref.

(c) Infine riscrivi il tutto basandosi solo su Vref, rimuovendo quel passaggio aggiuntivo. Quindi, otteniamo la funzione di trasferimento mostrata in (c) - simile a quella trovata nei fogli dati, basata interamente sul fattore \ $ 2 ^ N \ $. Sono tutti felici! Ma nota che ci sono 7 passaggi in verticale e 8 passaggi in orizzontale. L'espressione per Vd viene sostituita con:

$$ Vd = int \ left (\ frac {Va} {Vref} \ times 8 \ right) $$

Inoltre:

$$ \ frac {Vd} {8} \ times Vref \ leq Va < \ frac {(Vd + 1)} {8} \ times Vref $$

Funzioni di trasferimento ADC:

Dirceu Rodrigues Jr.

Quindi, possiamo usare \ $ (2 ^ N-1) \ $ o \ $ 2 ^ N \ $, poiché sono correttamente associati rispettivamente ai valori FS o Vref. Secondo la trama (c) la cattiva notizia è che non possiamo "misurare" il valore Vref (anzi, identificare quando avviene il passaggio a questo valore). Certo, possiamo superare il problema usando divisori resistivi e amplificatore. operazioni sull'input dell'ADC per far corrispondere il valore che vogliamo. Ma questo potrebbe non valere la pena in pratica: oltre alle differenze molto piccole (per un ADC a 10 bit o superiore), ci sono anche le non idealità del convertitore AD. Infine, la tolleranza del resistore utilizzato potrebbe "rovinare" il tutto.

Un vantaggio nell'usare la divisione per \ $ 2 ^ N \ $ è che in microcontrollori semplici (in particolare a 8 bit) senza avere un'istruzione per la divisione: questo può essere sostituito da più turni a destra.La differenza è che l'arrotondamento per la divisione con segno è "verso zero" e per lo spostamento aritmetico a destra è "infinito negativo".Processori più sofisticati, come quello ARM (diverso dal Cortex-M0), incorporano già istruzioni per la divisione in pochi cicli e turni multipli a ciclo singolo attraverso il cambio barile nativo, con una differenza minima nelle prestazioni.

mic
2017-02-16 23:05:15 UTC
view on stackexchange narkive permalink

Hai ragione.Il valore digitale massimo (1023) rappresenta la tensione di riferimento dell'ADC.Pertanto la divisione per (2 ^ (numero di bit) - 1) è corretta.

Ma l'errore è molto probabilmente superiore a 1 conteggio, quindi taglialo con una costante di calibrazione se ne hai davvero bisogno.
carveone
2017-10-08 16:37:10 UTC
view on stackexchange narkive permalink

Senza nulla togliere alla risposta di Spehro, è così che mi piace pensarla. La maggior parte dei programmatori ha familiarità con una situazione simile con i pixel:

Prendi un monitor teorico di 1000 mm di diametro con 1000 pixel. Ogni pixel misura 1000/1000 = 1 mm. I pixel vengono indirizzati a partire da zero. Quindi il pixel più a sinistra è # 0 e le sue dimensioni su un righello si estenderanno da 0 mm a 1 mm. Il pixel più a destra è # 999 e le sue dimensioni vanno da 999 mm a 1000 mm.

Quindi, se vuoi prendere # 999 come 999 mm, hai una lettura che è scalata correttamente ma sempre arrotondata per difetto.

Tuttavia, se decidi che # 999 significa veramente "1000mm", forzi un ridimensionamento di ogni singolo pixel a 1000/999 = 1.001mm. Hai ancora il solito errore di arrotondamento 0,5 ma ora anche un errore di ridimensionamento !

Potresti essere in grado di tollerare questo errore se non ti dispiace che i valori più alti siano arrotondati per eccesso e i valori inferiori siano arrotondati per difetto.

Nota anche che la divisione di numeri interi causerà anche un arrotondamento per difetto al n più vicino.

E, come ha detto Spehro, l'errore e il rumore dell'ADC di solito superano comunque 1 LSB.

12Lappie
2017-02-17 00:30:37 UTC
view on stackexchange narkive permalink

Hai ragione a presumere entrambi i casi.Nell'equazione è possibile utilizzare 1023 o 1024 poiché anche 0 è rappresentato.Pertanto, ci sono 1024 diversi valori digitali per rappresentare il segnale analogico dove 1023 è il tuo massimo e 0 è il tuo minimo.

Ad esempio, se hai un picco sul tuo segnale analogico di 5V, questo valore che passa attraverso l'ADC sarebbe rappresentato come 1023 .. Se 0V è il tuo minimo, 0 sarebbe il valore che esce dal tuo ADC.Alla fine, fa solo una leggera differenza.Se hai davvero bisogno di una misurazione precisa e questa equazione ti sta causando problemi, proverei un diverso microprocessore o scheda di sviluppo poiché non è così veloce e 1024 bit è nella media per ATMEGA328p ..

Grazie per la risposta.Rimarrò con ATMEGA328P poiché funziona perfettamente per il mio progetto.Volevo solo cancellare quella domanda dalla mia mente.


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...