Problema ingressi analogici

Salve a tutti! Sto costruendo un nuovo progetto e ho intenzione di collegare 2 sensori (temperatura e fotoresistenza) su 2 pin analogici. Fin qui tutto bene, la luminosità la legge ma quando attivo il pin della temperatura questa oscilla ad intervalli irregolari da 14 gradi a 35 gradi costantemente, quindi ne deduco che ci sia qualche problema con la lettura della tensione. Ciò non accade se uso sempre lo stesso pin con la medesima formula ma senza attivare il secondo pin della fotoresistenza, in questo caso il valore della temperatura è corretto. Quale può essere il problema?

Ma leggi 2 pin analogici consecutivamente? Se nello sketch fai così, ricordati che quando cambi canale dell'ADC, la prima lettura fatta sul secondo pin è da scartare perché riflette il valore letto sul pin precedente.

PS: posta codice e schema per favore

Non la sapevo questa cosa, che la seconda lettura prende il valore della prima, procedendo in questo modo ora funziona correttamente:

lum = analogRead(pinLum);
lum = lum * 100.0 / 1024.0;

... 

temp = analogRead(pinTemp);
temp = analogRead(pinTemp);
temp = 5 * temp * 100.0 / 1024.0;

penso sia corretto, grazie tante!

GioJoker: Non la sapevo questa cosa, che la seconda lettura prende il valore della prima, procedendo in questo modo ora funziona correttamente:

E' una cosa che ho appreso dal datasheet.

leo72:

GioJoker: Non la sapevo questa cosa, che la seconda lettura prende il valore della prima, procedendo in questo modo ora funziona correttamente:

E' una cosa che ho appreso dal datasheet.

bella informazione Leo, ricordavo che c'era qualcosa di particolare (infatti ti dicevo l'altro giorno che non voglio usare gli altri pin ADC per il mio lavoro) ma non cosa, messa in saccoccia, e penso proprio che dovremo tenerla ben presente in futuro, grazie!

[quote author=Michele Menniti link=topic=154179.msg1156327#msg1156327 date=1363275006]

leo72:

GioJoker: Non la sapevo questa cosa, che la seconda lettura prende il valore della prima, procedendo in questo modo ora funziona correttamente:

E' una cosa che ho appreso dal datasheet.

bella informazione Leo, ricordavo che c'era qualcosa di particolare (infatti ti dicevo l'altro giorno che non voglio usare gli altri pin ADC per il mio lavoro) ma non cosa, messa in saccoccia, e penso proprio che dovremo tenerla ben presente in futuro, grazie! [/quote] :P

Sempre che il compilatore non se ne accorga e ottimizzi il codice eliminando "l'inutile" ripetizione.

Non credo, altrimenti non gli funzionerebbe.

Per Leo:

E' una cosa che ho appreso dal datasheet.

Per favore potresti indicarmi in che punto del datasheet hai letto questa cosa?

Cap. 24.5.1, quando si parla di modalità free running. Se non erro, è la modalità impostata sull'Arduino perché vedo che si attiva con i bit ADCxD del registro DIDR0 a 0, registro che non vedo toccato dal core di Arduino (file wiring_analog.c). Siccome in free running le letture sono fatte di continuo, cambiando il canale la prima lettura riflette ancora il canale precedente. Un'altra condizione critica è quella riguardante il cambio di riferimento, cosa che fa sballare la lettura successiva.

Probabilmente fai riferimento al manuale dell'AT contenuto nella UNO, mentre lo stesso capitolo per l'AT della MEGA è il 26.5.1

A parte questo, leggo:

When changing channel selections, the user should observe the following guidelines to ensure that the correct channel is selected: In Single Conversion mode, always select the channel before starting the conversion. The channel selection may be changed one ADC clock cycle after writing one to ADSC. However, the simplest method is to wait for the conversion to complete before changing the channel selection. In Free Running mode, always select the channel before starting the first conversion. The channel selection may be changed one ADC clock cycle after writing one to ADSC. However, the simplest method is to wait for the first conversion to complete, and then change the channel selection. Since the next conversion has already started automatically, the next result will reflect the previous channel selection. Subsequent conversions will reflect the new channel selection. When switching to a [u]differential gain channel[/u], the first conversion result may have a poor accuracy due to the required settling time for the automatic offset cancellation circuitry. The user should preferably disregard the first conversion result.

In pratica, se non ho capito male, consigliano di scartare la prima lettura, ma solo quando si commuta il canale nella modalità [u]differenziale[/u].

Immagino che tu abbia già fatto delle prove: quali sono state le tue conclusioni? Scusa se ti rompo i... transistor, ma vorrei capire una volta per tutte questa cosa.

Io parlo dell'Atmega328 ma lo stesso identico discorso vale per tutti gli Atmel: leggi il capitolo inerente l'Atmega2560, l'Attiny84 ecc... hanno tutti lo stesso testo del paragrafo intitolato "ADC Input Channels".

Quando in modalità free running (ossia una conversione dietro l'altra) cambiando canale la prima lettura fatta sul nuovo canale in realtà riflette quella fatta sul canale precedente per cui è da scartare.

L'ADC degli Atmega non è un gran che, anche letture su segnali con alta impedenza possono dare valori sballati perché il circuito S&H si carica con lentezza. Un'altra cosa che si trova leggendo il datasheet e che in passato era stata adottata anche dal team di Arduino è di mettere un piccolo delay fra la scelta del canale ed il recupero della lettura, per dar modo al muxer interno di cambiare il canale. Se guardi nel file wiring_analog.c c'è ad un certo punto un delay(1) commentato.

Per evitare questi problemi ho risolto mettendo una piccola routine di lettura del pin analogico e chiamandola per fare una decina di letture a vuoto, restituendo solo l'ultima. Altra tecnica è quella di fare la media delle letture, ma tendo ad evitarla perché se una di queste è troppo sballata rispetto alle altre mi altera anche la media.

leo72: Io parlo dell'Atmega328 ma lo stesso identico discorso vale per tutti gli Atmel:

In realtà questo problema esiste su quasi tutte le mcu di tutti i produttori, tutti quanti consigliano vari modi per risolvere il problema nel modo più efficiente possibile, però alla fine il modo più pratico è proprio quello di buttare via la prima lettura dopo il cambio canale. Da notare che questo fatto ha un impatto negativo sul sample rate, riduce sensibilmente la banda di misura.

leo72: Ma leggi 2 pin analogici consecutivamente? Se nello sketch fai così, ricordati che quando cambi canale dell'ADC, la prima lettura fatta sul secondo pin è da scartare perché riflette il valore letto sul pin precedente.

Avevo letto in un altro post questa tua affermazione, che risponde ad una logica secondo il datasheet, ma non ho riscontrato nessuna differenza tra fare una lettura a vuoto dell pin analog prima di inviare il dato effettivo e spedirli tutti in sequenza, i pin successivi restano comunque influenzati da quello precedente i valori vanno a scalare.

Spesso è così, difatti consiglio di farsi una serie di letture per pin e di considerare solo l'ultima. L'ADC degli Atmega non è il massimo :sweat_smile:

Sto studiando molto questo argomento, che dovrebbe essere il mio prossimo lavoro "teorico", e proprio in questi giorni ho realizzato uno schema in cui avevo necessità di usare un ingresso ADC con la massima precisione possibile. Alcuni consigli utili: 1 - l'alimentazione del circuito deve essere ultra-stabile 2 - NON usare mai il Reference di default, decisamente preferibile l'INTERNAL (1,1V è un valore indicativo, in realtà è un valore stabilissimo prossimo a quella tensione, quindi va misurato sull'ARef) 3 - Se non è possibile ricondurre la scala a 1,1V usare l'EXTERNAL ma ricorrendo ad una fonte stabile come appunto quegli integrati (formato TO-92) che hanno specifica funzione, esistono da 1 a 5V, se non erro, ovvio che in quest'ultimo caso necessitano di una tensione superiore da stabilizzare. 4 - Disaccoppiare l'alimentazione dell'ADC rispetto al resto del micro, è sufficiente collegare AVcc a 5V tramite una impedenza da 10µH e poi mettere un C da 100nF tra AVcc e GND (da datasheet) 5 - Aggiungere un C da 100nF tra ARef e GND. 6 - se si usano resistenze di pull o partitori di adattamento BISOGNA NECESSARIAMENTE misurare con idonea strumentazione ogni valore, compresa la fonte di alimentazione del partitore (in genere i 12V), questo è l'errore che compiono quasi tutti: calcolare i dati in base ai valori nominali!!! 7 - Indispensabile il ricorso ad un clock ultra-stabile, quindi un quarzo e non un risuonatore ceramico (ho fatto dei test comparativi tra la 2009 col quarzo e la UNO con il risuonatore, NON c'è STORIA!!!), meglio ancora un oscillatore quarzato TTL, ma qui l'uovo deve valere la candela :sweat_smile: Ho messo a punto una trentina di formule che serviranno ad uscire fuori da qualsiasi situazione iniziale ed a stabilire con esattezza assoluta (nei limiti della risoluzione dell'ADC) a cosa corrisponde una data lettura restituita dall'ADC. Vi assicuro che alle prove dei fatti l'ADC ATMEL non è la ciofeca che può sembrare con l'uso che ne facciamo NORMALMENTE. Bene, con tutti questi accorgimenti, usando l'ADC come strumento di regolazione di precisione ho ottenuto una taratura precisa a ±1Hz su una lettura di 1GHz (per capirci... 1.000.000.000 Hz), fate voi i conti della precisione in percentuale, io non ci riesco ;) Naturalmente i limiti ci sono, non ultimo la risoluzione a 10bit ma sappiamo che con l'over-sampling è possibile arrivare a 12 bit. Comunque sia sul mercato escono ogni giorno dei precisissimi integrati ADC a svariati canali, che potrebbero essere collegati ai pin digitali di Arduino, migliorando decisamente anche questa sezione, fate un po' Voi. Conservatevi questo post e fidatevi del sottoscritto, non voglio caffé né altro, mi basta una benedizione ogni volta che vi tornerà utile :*

[quote author=Michele Menniti link=topic=154179.msg1158739#msg1158739 date=1363436926] mi basta una benedizione ogni volta che vi tornerà utile :* [/quote] Ego benidicus tibi ;)

…in nomine Banzi, Arduino et ATMEL. Amen.

[quote author=Michele Menniti link=topic=154179.msg1158739#msg1158739 date=1363436926] mi basta una benedizione ogni volta che vi tornerà utile :* [/quote]

Vos nominare Patrona Arduino Michele primus :grin:

Michele, questo link potrebbe esserti utile:

hacking.majenko.co.uk/making-accurate-adc-readings-on-arduino