Go Down

Topic: Stranezza lettura analogica Arduino DUE (Read 2 times) previous topic - next topic

adrirobot

Ciao a tutti
Vi scrivo per sapere se qualcuno ha avuto il mio stesso problema.   Ho collegato un sensore di temperatura TMP36 all'ingresso A0 di una scheda Arduino DUE, il problema è che dopo un certo numero di letture corrette, ad un certo punto il valore letto tende a diminuire, anche se misurando con un multimetro la tensione ai capi del sensore questa non è effettivamente diminuita, se non per le variazioni di temperatura.
Il problema non si manifesta però leggendo per esempio la tensione fornita dal pin 3.3V della scheda stessa, oppure utilizzando una fotoresistenza, oppure ancora una tensione fornita da due batterie da 1,5V in serie.
Sul sensore ho inserito il condensatore consigliato da 100nF tra alimentazione e massa, o anche provato un altro sensore tipo TMP36 con gli stessi risultati
Uso la versione dell'IDE 1.5 potrebbe risolvere utilizare l'ultima versione?
Eventualmente qualcuno può effettuare la prova e farmi sapere.
Saluti
Adriano

uwefed

nei dati del TMP36 c'é scritto:
"Output Load Current IL da 0 a 50 μA."
Presumo non avendo un DUE (ma piú di 2 UNO  ;) ;) ;) ) che il circuito sample and hold sia simile di quello del Atmega percui ogni misura carica un condensatore interno e percui per brevi tempi chiede molto di piú di 50µA.

Soluzioni:
Condensatore da 0,1µF in tra A0 e massa, e diminuire la frequenza di misura e poche misure al secondo se non a una misura ogni decina di secondi.

Seconda possibilitá cambia l' impedenza del sensore interponendo un Amplificatore operazionale come amplificatore non invertente con guadagno 1. ( segnale su entrata + e collegare uscita a entrata - e a A0). Devi usare un amplificatore Rail to Rail come per esempio il LMV358.

Ciao Uwe

astrobeed

#2
Nov 21, 2012, 08:50 am Last Edit: Nov 21, 2012, 09:05 am by astrobeed Reason: 1

nei dati del TMP36 c'é scritto:
"Output Load Current IL da 0 a 50 ?A."
Presumo non avendo un DUE (ma piú di 2 UNO  ;) ;) ;) ) che il circuito sample and hold sia simile di quello del Atmega percui ogni misura carica un condensatore interno e percui per brevi tempi chiede molto di piú di 50µA.


In realtà il sistema di sample hold del SAM3X è decisamente migliore di quello degli AVR, sul data sheet nella sezione delle caratteristiche elettriche del ADC c'è la tabella 46.35 (pag. 1419, versione documento 11057B-ATARM-28-May-12) che riporta l'impedenza d'uscita massima della sorgente in funzione della frequenza di clock del ADC sia per il modo a 10bit che per quello a 12bit.
Dalla citata tabella si desume che alla massima frequenza di campionamento l'impedenza deve essere 10k a 12 bit e 14k a 10 bit, valori decisamente buoni visto che il reale campionamento è a 1 MHz, basta scendere a un ADC clock di 10 MHz (500 ksps) per rientrare nei ~20 kohm di impedenza d'uscita dei TMP36.
Adesso toccherebbe verificare come viene usato l'ADC da Arduino DUE, ovvero come viene inizializzato e con che clock ADC lavora.

edit: un rapido controllo al reference del IDE 1.5x suggerisce che il sample rate è sempre 10ksps come sulla UNO, il che escluderebbe qualunque problema legato all'impedenza d'uscita del TMP36, c'è in più il comando AnalogResolution per cambiare la risoluzione della lettura e sfruttare tutti i 12bit.
Più tardi provo a dare un'occhiata direttamente al codice che inizializza l'ADC così scopriamo quale sia la reale velocità di sample.

astrobeed

Da una prima verifica sembra che l'ADC della DUE viene settato per il massimo sample rate, ovvero ADC clock a 20 MHz e di conseguenza 1 Msps, i file incriminati sono ADC.C dove viene definita la funzione ADC_INIT, ADC.H dove si trovano i parametri richiesti dalla funzione che viene invocata all'interno del file VARIANT.CPP.
Tutti i file si trovano nella cartella ..\arduino-1.5.1\hardware\arduino\sam\ e relative sottocartelle.

In particolare abbiamo la chiamata di ADC_INIT:
Code: [Select]

// Initialize Analog Controller
  pmc_enable_periph_clk(ID_ADC);
  adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST);
  adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);
  adc_configure_trigger(ADC, ADC_TRIG_SW, 0); // Disable hardware trigger.
  adc_disable_interrupt(ADC, 0xFFFFFFFF); // Disable all ADC interrupts.
  adc_disable_all_channel(ADC);


Con i parametri definiti in ADC.H:
Code: [Select]

/* The max adc sample freq definition*/
#define ADC_FREQ_MAX   20000000
/* The min adc sample freq definition*/
#define ADC_FREQ_MIN    1000000
/* The normal adc startup time*/
#define ADC_STARTUP_NORM     40
/* The fast adc startup time*/
#define ADC_STARTUP_FAST     12


uwefed

allora astrobeed, cosa é la causa del problema e possibile soluzione?
Ciao Uwe

Go Up