Problemi con LCD 20x4 sparkfun con Leonardo ...

Esatto.

questo è ovviamente un limite ma così è; per leggere TUTTI i valori di un sensore che fornisce un'uscita sull'intera alimentazione tra 0V e 5V

Diciamo pure che non esiste nessun sensore alimentato a 5V dotato di un full range tra 0 e 5V, arriverà sempre a qualcosina di meno per ovvi motivi elettronici, anche i migliori opamp rail to rail hanno sempre qualche mV di offset rispetto alla tensione di alimentazione, quindi il problema non sussiste.
Se poi nel calderone ci metti pure la reale precisione e linearità del ADC, l'instabilità tipica di +/- 1 count dovuta agli errori di quantizzazione, che però consentono l'aumento della risoluzione tramite oversampling, ecco che preoccuparsi della mancanza di 1/1024 rispetto al valore di aRef non è un problema per il quale valga la pena perderci un solo secondo di tempo :slight_smile:

Adesso vado a preparare il pranzo, per il mio stomaco sono le 13:25 (il forum sta ancora con l'ora legale) e brontola non poco :grin: , più tardi ti spiego esattamente come funziona l'ADC del 328 e vedrai che ti diventa tutto chiarissimo.

Ottimo, mi stai dando un mare di spunti importanti, questo ulteriore chiarimento sul funzionamento generale sarà prezioso, potrò rivedere l'intero lavoro (sono 18 pagine di Word, mica bruscolini :)); se poi tu riuscissi a trovare il tempo per spiegarmi come portare la risoluzione a 12-14 bit (una cosa di cui parlasti al tempo in cui cercavo di accendere il mio primo led compandato da un potenziometro) allora sarebbe davvero il massimo! Buon pranzo, te lo meriti :grin:
A dopo.

@Michele
Provo a spiegarti in maniera diversa....Abbiamo appreso tutti che 10 bit equivalgono a 1024 in decimale e fin quì non vi è ombra di dubbio.
Per leggere una tensione abbiamo bisogno di partire da 0 volt fino a 5 volt (come nel nostro caso).
Quando abbiamo in ingresso un valore di tensione pari a 0 volt il nostro ADC ci darà una lettura in binario di 00 0000 0000 che è uno step di quei famosi 1024 che in questo caso corrisponde allo step zero e continuerà ad essere tale fino a quando avrai una tensione applicata minore di 4,8828125mV.
Per poter passare allo step 1 il valore di tensione deve superare 4,8828125mV, la lettura in binario sarà 00 0000 0001 e continuerà ad esserlo fino a che la tensione applicata non diventi maggiore di 4,8828125mV*2..........
Detto questo si capisce che quando applichiamo i 5 volt lui ci restituirà 0x3ff che saranno i 5 volt meno quelli persi nella condizione di zero volt 4,8828125mV con il risultato che la massima lettura sarà 5-0,0048828125 = 4,995117188V.
Ciao.

ps Scusatemi se mi sono intromesso

Tonid, ti ringrazio e non sei affatto un intruso, i Topic sono liberi, come detto ho già scritto 18 pagine di roba sull'argomento e "creato" almeno una quindicina di diverse formule per fare di tutto e di più con l'ADC, ho scritto anche un approfondimento su campionamento, quantizzazione e codifica dei segnali analogici, con tanto di grafici esplicativi. In tutto ciò mi era sfuggito un solo particolare, quello appunto che il fondo scala non poteva coincidere con l'ARef, che è certamente una cosa grave ma tutto il resto mi è chiaro. Ho fatto anche un discreto studio sull'alimentazione separata dell'ADC e sulle tensioni di riferimento di ARef diverse dall'alimentazione e proveniente oltre che dall'ottimo comparatore (?) interno a 1,1V, da generatori di tensioni di riferimento di precisione che ho comprato espressamente per fare una serie di prove.
Ho detto ad Astro che gradisco un approfondimento perché penso che escano fuori cose nuove per me, come l'oversampling e la codifica a 12 e 14 bit; se non sbaglio il primo metodo consiste nel fare la media di un certo numero di conteggi ripetuti in sequenza, per compensare il ±1 count di tolleranza, se è questo allora lo conosco in quanto l'ho applicato un paio di volte, altrimenti lo ignoro. Tu ne sai qualcosa?

Successive Approximation ADC

L'ADC utilizzato dagli AVR è del tipo SAR che sta per Successive Approximation Register, in italiano Registro ad Approsimazioni Successive, come fa intuire il nome questo tipo di ADC arriva al risultato tramite una serie di approsimazioni.
La figura allegata è lo schema a blocchi generico di un ADC di tipo SAR, come si vede è costituito da un comparatore analogico al quale viene applicata la tensione campionata dal sistema di sample and hold e una tensione di riferimento generata tramite un DAC (Digital Analog Converter) che a sua volta è controllato dal registro SAR.
Il funzionamento è abbastanza semplice, si parte settando il DAC per generare una tensione pari a 1/2 aRef, è a questa unità che fa capo il relativo pin, impostando il bit più significativo del registro SAR a 1, nel caso di un ADC a 10 bit è il decimo bit che ha peso 512, se la tensione del DAC risulta minore di quella in ingresso, proveniente dal sample/hold, questo bit viene lasciato a 1 in caso contrario si riporta a 0, dopo di che si porta a 1 il nono bit, peso 256, e si ripete il paragone con la stessa logica di prima, ovvero se la tensione totale in uscita dal DAC è minore di quella del S/H il bit rimane a 1 altrimenti si riporta a 0.
Si ripete il procedimento con la stessa logica per tutti i bit del ADC, nel nostro caso in totale sono 10, e alla fine il registro SAR contiene il valore digitale della nostra tensione analogica, facciamo un esempio pratico.

Ipotizziamo che la tensione su Aref è 5V esatti, questo vuol dire che ogni step del DAC vale 5/1024 = 4,883 mV, e che la tensione da misurare è 2.815V.

Primo step:
Setto il bit 10 del SAR a 1, al DAC arriva il valore binario 0b1000000000 che vale 512 pertanto la tensione in uscita dal DAC è 4.883512 = 2.500V, il comparatore mi dice che la tensione sul S/H è maggiore di quella del DAC pertanto lascio il bit 10 del SAR a 1 logico.
Secondo step:
Setto il bit 9 del SAR a 1, al DAC arriva il valore binario 0b1100000000 che vale 768, la tensione in uscita è 4.883
768 = 3.750V, il comparatore mi dice che la tensione sul S/H è minore di quella del DAC pertanto riporto il bit 9 del SAR a 0 logico.
Terzo step:
Setto il bit 8 del SAR a 1, al DAC arriva il valore binario 0b1010000000 che vale 640, la tensione in uscita è 4.883640 = 3.125V, il comparatore mi dice che la tensione sul S/H è minore di quella del DAC pertanto riporto il bit 8 del SAR a 0 logico.
Quarto step:
Setto il bit 7 del SAR a 1, al DAC arriva il valore binario 0b1001000000 che vale 576, la tensione in uscita è 4.883
576 = 2.812V, il comparatore mi dice che la tensione sul S/H è maggiore di quella del DAC pertanto lascio il bit 7 del SAR a 1 logico.

--- Si continua in questo modo fino all'ultimo bit del SAR ---

Una volta arrivati al bit 0, peso 1, mi ritroverò all'interno del SAR il valore 1001000000 che equivale alla tensione di 2.812V, si trova tra 2.816V e 2.807V che è il range entro il quale è contenuto il reale valore della tensione che stiamo misurando.
Il vantaggio di questa tipologia di ADC è che sono relativamente veloci e richiedono tanti cicli clock ADC quanti sono i bit più uno per completare la conversione, sono semplici da implementare all'interno di un micro e possono arrivare a sample rate di svariati megasamples.
La tecnica dell'oversampling per aumentare la risoluzione sfrutta sia l'errore di quantizzazione tra le misure, cioè quei mV in più o in meno che mancano rispetto al valore reale della tensione e lo step minimo del DAC, e il rumore presente sul segnale, per quanto possa sembrare assurdo in questo caso una tensione perfettamente pulita non permette l'uso dell'oversampling.
La teoria che c'è dietro questa tecnica è abbastanza complessa, ne puoi trovare una sintesi molto semplificata sulla application note AVR121 di Atmel, in compenso metterla in pratica è una cosa abbastanza semplice.
Per implementare l'oversampling è necessario acquisire 4^n sample, ove n è il numero di bit da guadagnare, sommarli e dividerli per 2^n.
Esempio pratico, vogliamo passare da 10 a 11 bit, si acquisiscono 4 letture (4^1=4) si sommano tra loro e si dividono per 2 (2^1=2), se vogliamo passare a 12 bit si acquisiscono 16 letture (4^2=16) e si dividono per 4 (2^2 = 4).
Il prezzo da pagare per l'aumento della risoluzione è la banda, se passo da 10 a 11 bit la banda si riduce a 1/4, se passo da 10 a 12 bit si riduce a 1/16, e così via, non è consigliabile superare un incremento di 2 bit.
Solitamente la tecnica dell'oversampling si usa quando la velocità di lettura non è prioritaria mentre serve la maggiore risoluzione possibile, p.e. con una ntc/ptc per la misura della temperatura.

Grandioso! Mi aspettavo proprio un approfondimento del genere, devi apportare solo una piccola correzione al testo
4 letture (4^1=1) --> 4 letture (4^1=4).
Non capisco però come si arriva al risultato; p.es. a 11bit, se faccio 4 letture (diciamo 1000, 1002, 1002,1000), le sommo tra loro e le divido per 2 ottengo 2001; questo perché a 11 bit il range arriva a 2047 e quindi mi devo rapportare ad esso?

Piccola svista, ho scritto tutto di getto sull'editor del forum ed è un miracolo se c'è solo quell'errore :slight_smile:

Non capisco però come si arriva al risultato; p.es. a 11bit, se faccio 4 letture (diciamo 1000, 1002, 1002,1000), le sommo tra loro e le divido per 2 ottengo 2001; questo perché a 11 bit il range arriva a 2047 e quindi mi devo rapportare ad esso?

Si, passando a 11 bit il fondo scala diventa 2047 pertanto anche la lettura cambia di conseguenza perché la risoluzione raddoppia.

Perfetto, grandissimo, sappi che sarai AMPIAMENTE plagiato, ovvio che farò in modo, quando sarà, di mettere gli opportuni ringraziamenti.
Ora ho scoperto che l'oversampling che praticavo io era in realtà una zoccolata :smiley:

@astrobeed
E' da un po che seguo i tuoi post e ti faccio i miei sinceri complimenti per il bagaglio di Conoscenza che hai :wink:
@Michele
sono tornato adesso e comunque le mie conoscenze da autodidatta Non sono sicuramente quelle di astro che come hai potuto vedere ti ha fornito un ottima e semplice spiegazione.....ahah ,ecco perchè non volevo essere un intruso 8)

Tonid, ti ho ringraziato non azzannato :sweat_smile:
E comunque la spiegazione di Astro, rispetto alla tua, più che ottima e semplice mi sembra proprio diversa, ed era esattamente il tipo di "contributo" che mi aspettavo da lui, è già diventato parte integrante del lavoro :smiley: ma ciò non toglie nulla al valore del tuo contributo :slight_smile:

E comunque la spiegazione di Astro, rispetto alla tua, più che ottima e semplice mi sembra proprio diversa

Si ,infatti ,mi riferisco anche io all'approfondimento che cercavi.....quando ho letto tutti i post appena sono tornato,ho visto anche la risposta di astro alla tua domanda ed oltre al fatto che io non avrei saputo darti luce ,lui lo ha fatto in maniera ottima e semplice e per semplice intendo comprensibile nel modo in cui le ha esposte. :slight_smile:
Buon lavoro :wink:

Adc: ottime domande, ottime risposte
X iscrizione

io leggo ma non sono in grado di ribattere , non è il mio campo.... :~

a dire il vero posso dire qualcosa , ho visto il grafico di risposta del sensore sulla temperatura non è lineare.....

Snoopy1:
ho visto il grafico di risposta del sensore sulla temperatura non è lineare.....

Non so quale grafico hai guardato però la risposta del sensore è praticamente lineare in tutto il range di misura, come da specifiche la precisione è il 2% e la linearità è 0.5%, il grafico da guardare è quello segnato come "Figure 6. Output Voltage vs. Temperature" .

direi che l'argomento di questo post è cambiato quindi ne apro un altro per la questione sensore temperatura.
ad un attento esame effettivamente il mio lcd è un seriale e ho notato picchi improvvisi di assorbimento che mi hanno convinto a sospendere e sostituire il mio lcd con uno parallelo, anche se tutto comunque funziona evidentemente l'assorbimento anomalo dovuta all'incompatibilità arduino / LCD seriale metteva in crisi il mio quadruplicatore di porta usb, la cosa è migliorata usando una porta esclusiva ma continuando a rilevare picchi improvvisi con consumi anomali ( rilevati con oscilloscopio) ho preferito sospendere.
Nel frattempo sto sperimentando le formule per il sensore di temperatura con un lcd 2x16 di recupero in attesa di ricevere il 4x20.
grazie a tutti voi che mi avete aiutato

Snoopy1:
ad un attento esame effettivamente il mio lcd è un seriale e ho notato picchi improvvisi di assorbimento che mi hanno convinto a sospendere e sostituire il mio lcd con uno parallelo

Cioè non hai mai letto la pagina del prodotto dove è chiaramente scritto che è un LCD seriale con tanto di schema e sorgente del software ?

ma perche' non lo colleghi in seriale , LCD che hai ?

non sei il primo a suggerirglielo, ma probabilmente lui non sa come fare e quindi non interpreta bene il consiglio.
per farti capire, snoopy, tu hai comprato una ferrari ma vuoi usarla come una 500,

ferrari: lcd seriale, costa 30 euro, usi un solo pin per pilotarlo
500: lcd parallelo, costo 3 euro, usi molti pin per usarlo