Dubbio analogReference( INTERNAL )

Sono possessore dell'Arduino Uno Rev3 Ethernet dove ho collegato un sensore di temperaturaa LM35, per calcolare la temperatura uso:
tempC = (5.0 * tempC * 100.0)/1024.0; però ho visto che mi porta oltre un grado di differenza, per ovviare a questo problema ho usato
un esempio trovato in rete:
analogReference( INTERNAL ); // per l'ADC usiamo il Vref interno da 1,1V (migliore precisione)
in effetti è molto più preciso, però ho il dubbio che analogReference( INTERNAL ) mi imposta tutti gli input analogici
a 1,1 volt, perche se in un'altro pin collego un fotoresistore, quest'ultimo non funziona per niente bene, mentre se commento
la riga analogReference( INTERNAL ) funziona bene.
Quindi mi confermate il mio dubbio?
Se si c'è un modo per avere una buona precisione con LM35 e in contemporanea usare un fotoresistore, e anche eventualmente un PIR?

Grazie per l'aiuto.

La tensione di riferimento vale sempre per tutti le entrate analogiche (che in pratica sono un convertitoer A/D e un multiplexer.
Puoi ovviare al problem se porti la tensione piú alta con un pertitore resistivo sotto 1.1V Oppure cambi il riferimento e devi fare alcune letture a vuoto per stabilizzare il cambio di tensione di riferiemento.
Ciao Uwe

Oppure cambi il riferimento e devi fare alcune letture a vuoto per stabilizzare il cambio di tensione di riferiemento.

quindi una cosa del genere:
analogReference( INTERNAL ); // imposto 1,1V
analogRead( pin_LM35 ); // lettura a vuoto

e dopo posso usare il sensore LM35 a 1,1V e anche il fotoresistore a 5V?

Perdonami ma non sono esperto di programmazione / elettronica

Se imposti il riferimento a 1V1, tutto quello che leggi di tensione superiore a 1V1 e inferiore a 5V sarà letto sempre a fondo scala per cui la lettura ti restituirà sempre 1023.
Devi ridurre la tensione max a 1V1 anche del fotoresistore come ti ha detto Uwe

usa un partitore di tensione, vedi wikipedia.

e non dare in "pasto" alle porte analogiche un voltaggio superiore al reference, rischi di friggerle

Lesto, scusa ma il limite di rottura delle porte analogiche NON è dato dalla tensione di riferimento, bensì da quella di alimentazione, quindi se anche il riferimento è a 1,1V si può inviare alle porte la tensione di 5V (se il micro è alimentato a tale tensione) senza che succeda nulla; l'unico problema è che da circa 1,09V in poi legge sempre 1023

mi metti il dubbio, dovrei guardare il datasheet

Puoi metterci la mano sul fuoco.
Nella famiglia AVR gli ADC sono del tipo SAR, Successive Approximation Register.
L'ADC viene alimentato tramite i pin AVCC e GND del micro.
L'ARef invece è un pin del DAC (è proprio DAC...) interno al circuito ADC SAR, che serve per generare la tensione campione pari a 1/2 di quella applicata sull'ARef, da inviare all'ingresso non invertente del comparatore, mentre all'altro ingresso viene applicata la tensione da misurare. Di conseguenza tutta la circuiteria dell'ADC SAR lavora alla tensione di alimentazione AVCC (tipicamente collegata in parallelo, anche se andrebbe disaccoppiata, al VCC), quindi il comparatore può accettare tranquillamente tensioni fino all'AVCC, solo che superata la soglia ARef tali tensioni forniscono sempre una lettura 1023, ad indicare l'over-range.

mi sa che hai ragione e questa "limitazione" la hai con le tensioni vcc e Avcc :grin:

Credo proprio che il sensore LM35 e una fotoresistenza non possono lavorare insieme, perchè ho alimentato il sensore LM35 a parte, se lavora da solo tutto ok, dal momento che collego la fotoresistenza, se c'è luce la temperatura è corretta (valore della fotoresistenza circa 170), se non c'è luce la temperatura è completamente sballata (valore della fotoresistenza circa 1000).
Poi ho verificato con il tester la tensione dell'arduino sulla breadboard con luce spenta è 4.60 Volt e temperatura sballata, mentre con luce accesa e temperatura ok è sempre 4.60, ma come metto i puntali sui 2 cavetti la tensione è sempre 4.60, ma la temperatura è sballata come se ci fosse la luce spenta.
Il sensore è collegato senza nessuna resistenza, mentre alla fotoresistenza ho messo sia un resistenza da 10 kOhm e sia una da 5,6 kOhm.

aspetta format, ma la fotoresistenza e l'LM35 li hai messi su pin diversi? non potresti postare lo schema delle connessioni? Non c'è alcuna ragione perché un LM35 e una fotoresistenza si debbano influenzare tra loro, quindi ci deve essere un errore nei collegamenti o nell'elaborazione software del dato

aspetta format, ma la fotoresistenza e l'LM35 li hai messi su pin diversi? non potresti postare lo schema delle connessioni?

Questo è il codice che uso: (Lo stesso errore si ripete anche se non uso l'opzione internal)

float temp = 0.0;       // valore convertito in temperatura (°C)
int val = 0;            // valore quantizzato dall'ADC [0..1023]
float vref = 1.1;
float tempPin = 1;   // pin analogico IN temperatura sensore

int Fotoreistenza = 0;     // Utilizzo del pin 0 per la lettura dei valori del fotoresistore.
int Valore = 0;          // Variable usata per memorizzare il valore letto dal fotoresistore





void setup() 
{
  Serial.begin(9600);
  analogReference( INTERNAL );  // per l'ADC usiamo il Vref interno da 1,1V (migliore precisione)
  analogRead( tempPin );       // Prima lettura "a vuoto" (serve per l'assestamento dell'ADC)

}

void loop()


{
 
    val = analogRead( tempPin );              // legge il dato della tensione sul pin 'LM35_pin' 
    temp = ( 100.0 *  vref * val ) / 1024.0;   // lo converte in °C
  
   Valore = analogRead(Fotoreistenza ); 
  
   Serial.println(temp);             //invia i dati alla seriale
   Serial.print(" Celsius, ");
   
   Serial.print("Valore luminosita' = ");
   Serial.println (Valore);          
    delay( 1500 );
 
 
}

Il sensore LM35 anche se lo alimento a parte come si vede in foto non cambia nulla, inoltre dai screenshot si vede quando la temperatura sballa a luce spenta.
Alla fotoresistenza ho messo anche valori di resistenza diversi, quello che cambia sono i valori + alti o + bassi della fotoresistenza, ma l'errore è sempre uguale.
Quindi credo che anche se collegassi un sensore PIR (che devo ancora acquistare) insieme al sensore LM35 anche così avrei delle letture false, questo LM35 credo deve essere collegato da solo sui pin analogici di Arduino.

Intanto metti una lettura analogica della fotoresistenza "a perdere", perché l'ADC interno è multiplexato e quando cambi canale deve essere ricalibrato.

Valore = analogRead(Fotoreistenza ); 
Valore = analogRead(Fotoreistenza );

Se anche così non va, poi si guarda l'HW.

Allora in quell'immagine io noto:
1 - la mancanza dei C da 100nF su IN e OUT (e verso GND) del 7805
2 - la mancanza del C da 100nF tra il pin ARef e GND di Arduino
3 - l'LDR a mia memoria lavora in modo inversamente proporzionale: maggiore è la luce, minore è la sua resistenza interna; così configurata lavora in modo inverso sull'ADC, nel senso che aumentando la luce diminuisce la tensione; se vuoi ottenere un funzionamento diretto, devi invertire tra loro LDR e resistenza; quest'ultima, da 100k (se vedo bene) a me sembra assolutamente eccessiva, io la diminuirei a 10k
sul software te la vedi con Leo :slight_smile:

Intanto metti una lettura analogica della fotoresistenza "a perdere"

ho modificato il codice così:

float tempC;      //dichiarazione di variabile
int tempPin = 1;  //inizializzazione del pin di Arduino

int Fotoreistenza = 0;     // Utilizzo del pin 0 per la lettura dei valori del fotoresistore.
int Valore = 0;          // Variable usata per memorizzare il valore letto dal fotoresistore





void setup() 
{
  Serial.begin(9600);
 
  analogRead( tempPin );       // Prima lettura "a vuoto" (serve per l'assestamento dell'ADC)
  analogRead(Fotoreistenza ); 
}

void loop()
{
 
  
    tempC = analogRead(tempPin);           //lettura valore del sensore
    tempC = (5.0 * tempC * 100.0)/1024.0;  //conversione del dato analogico in temperatura
  
   Valore = analogRead(Fotoreistenza ); 
  
   Serial.println(tempC);             //invia i dati alla seriale
   Serial.print(" Celsius, ");
   
   Serial.print("Valore luminosita' = ");
   Serial.println (Valore);          
    delay( 1500 );
 
 
}

1 - la mancanza dei C da 100nF su IN e OUT (e verso GND) del 7805

allego lo schema del 7805 (però se alimento solo il sensore LM35 con il 7805 funziona bene)

2 - la mancanza del C da 100nF tra il pin ARef e GND di Arduino

ho messo anche un condensatore da 100nf tra Aref e GND dell'arduino, l'ho messo sui pin dalla parte degli ingressi digitali, perchè verso
gli ingressi analogici ho 2 GND ma non Aref, ma IORef, va bene così?

3 - l'LDR a mia memoria lavora in modo inversamente proporzionale: maggiore è la luce, minore è la sua resistenza interna; così configurata lavora in modo inverso sull'ADC, nel senso che aumentando la luce diminuisce la tensione; se vuoi ottenere un funzionamento diretto, devi invertire tra loro LDR e resistenza; quest'ultima, da 100k (se vedo bene) a me sembra assolutamente eccessiva, io la diminuirei a 10k

qua non ti seguo, non ho capito come invertire fotoresistenza e resistenza.
La resistenza è da 10k.

Comuque dopo queste prove c'è sempre l'errore della temperatura sballata.

Non so se vi siete accorti, ma io sono alle prime armi con programmazione e elettronica, ieri ho comprato i componenti (per il 7805)
seguendo uno schema trovato in rete, e gia farlo funzionare per me è stata una vittoria...
Voi per le vostre conoscenze non ci perdete nemmeno tempo per queste piccole cose...e per questo vi ringrazio per l'aiuto che mi date.

schema_elettrico.jpg

No, ho detto quando cambi canale, ecco perché ho messo la doppia lettura della fotoresistenza, perché è la seconda lettura analogica che fai.
Quindi così:

void setup() {
  Serial.begin(9600)
}

void loop() {
    tempC = analogRead(tempPin);           //lettura valore del sensore
    tempC = (5.0 * tempC * 100.0)/1024.0;  //conversione del dato analogico in temperatura
  
    Valore = analogRead(Fotoreistenza ); 
    Valore = analogRead(Fotoreistenza ); 
  
    Serial.println(tempC);             //invia i dati alla seriale
    Serial.print(" Celsius, ");
    
    Serial.print("Valore luminosita' = ");
    Serial.println (Valore);          
    delay( 1500 );
}

Purtroppo neanche così funziona....

format:
Purtroppo neanche così funziona....

Bene, a livello SW abbiamo appurato che va tutto bene.
adesso segui i consigli di Michele per la parte HW :wink:

Prima di tutto ti faccio i complimenti per la foto, finalmente qualcuno che mette chiunque in condizioni di vedere e comprendere i collegamenti, anche se l'ideale è sempre postare uno schema elettrico completo, le cose saltano all'occhio più faculmente.

Ho visto ora che il C 100nF in uscita c'è (parlo del 7805): aggiungi anche quello in ingresso e mettili entrambi vicinissimi ai pin IN/OUT del regolatore; il resto dello schema va bene

il pin IORef dovrebbe corrispondere all'ARef, va bene così, un C100nF infilato tra questo pin e GND

la resistenza mi sembrava marrone-nero-giallo, se l'ultimo anello è arancio allora va bene; devi invertirli di posizione: metti l'LDR tra 5V e A0 e la R tra A0 e GND, in tal modo otterrrai un incremento della tensione su A0 man mano che aumenta la luce, è anche più semplice da gestire.

Il problema che hai a mio avviso è esclusivamente software, l'LM35 funziona in modo lineare, la conversione che fai non è precisa ma indicativamente dovrebbe andare, il reference INTERNAL dovrebbe migliorare le cose, ma anche così non dovrebbe "sballare"; ma un'indicazione dei valori che ottieni e della temperatura presunta potresti darceli?

domande per Leo:
1 - non converrebbe mettere un piccolo delay tra le letture di A0 e A1
2 - il fatto che usi i comandi di lettura analogica permette di chiamare i pin 0 e 1 invece che A0 e A1?
3 - è buona pratica quella di usare la stessa variabile per acquisire il dato analogico e poi per ricalcolarne il valore nella conversione?

Ho visto ora che il C 100nF in uscita c'è (parlo del 7805): aggiungi anche quello in ingresso e mettili entrambi vicinissimi ai pin IN/OUT del regolatore; il resto dello schema va bene

ok grazie per il consiglio

il pin IORef dovrebbe corrispondere all'ARef, va bene così, un C100nF infilato tra questo pin e GND

ho messo anche il condensatore

la resistenza mi sembrava marrone-nero-giallo, se l'ultimo anello è arancio allora va bene; devi invertirli di posizione: metti l'LDR tra 5V e A0 e la R tra A0 e GND, in tal modo otterrrai un incremento della tensione su A0 man mano che aumenta la luce, è anche più semplice da gestire.

infatti ora legge i valore al contrario di prima, la resistenza è marrone - nero - arancio

questi i valori che leggo nel serial monitor a luce spenta:

22.46
Celsius, Valore luminosita' = 9
22.95
Celsius, Valore luminosita' = 9
22.46
Celsius, Valore luminosita' = 9

la temperatura con altri due termometri mi segna circa un grado in meno, ma se uso il reference INTERNAL è precisa

questi i valori che leggo nel serial monitor a luce accesa:

17.09
Celsius, Valore luminosita' = 784
18.55
Celsius, Valore luminosita' = 785
20.02
Celsius, Valore luminosita' = 786
33.20
Celsius, Valore luminosita' = 788

ho provato anche così:
int tempPin = A1;
int Fotoreistenza = A0;

ma non cambia nulla