[solved]AnalogRead di una sonda influenza anche l'altra

Ciao ragazzi! Come state? Era da un pò che non mi facevo sentire sul forum di Arduino. Per fortuna in questi mesi sono riuscito a cavicchiarmela un pò per conto mio risolvendo i problemini che incontravo di volta in volta soprattutto grazie a tutti gli aiuti che questo forum spettacolare da ogni utente.
Detto questo sono incappato in un problema che non sto riuscendo a risolvere :(.
Vi spiego.
Ho un piccolo progettino che legge delle temperature attraverso delle sonde di temperatura. Queste sonde sono di tipo resistivo, in particolare dei termistori. Ho seguito questo schema per il collegamento:
(Ground) ---- (10k-Resister) -------|------- (Thermistor) ---- (+5v)
|
Analog Pin 0
per la lettura delle temperature ho seguito tutto quello che c'è scritto su questo link:
http://playground.arduino.cc/ComponentLib/Thermistor2

Il problema è che quando varia la temperatura di una sonda, varia anche quella dell'altra! Come è possibile?
Vi posto anche il codice che ho utilizzato per le letture. E' un codice provvisorio che non tiene conto di tutte le operazioni con i logaritmi nel link che ho postato sopra.

#include <LiquidCrystal.h>

#define INTERVALLO_LETTURE 1
#define pin_acqua 0
#define pin_sonda 1

unsigned long ultima_media_time=0;

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

void loop(){
  t_check(analogRead(pin_acqua), analogRead(pin_sonda));
}
 
 
 void t_check(int lettura_acqua, int lettura_sonda) {

    if((millis() - ultima_media_time) / 1000 > (INTERVALLO_LETTURE)) {                        //inizia a fare questa operazione ogni tot secondi, in questo caso fa le letture ogni 1 secondo

      ultima_media_time = millis();                                                          //Prende il tempo di quando ho fatto la misurazione
 
      Serial.print("T-camera: ");
      Serial.print(lettura_acqua);
      Serial.print("  ");
      Serial.print("T-acqua: ");
      Serial.println((map(lettura_sonda, 0, 1023, 0, 255)));
    }
  }

Per l'esecuzione del programma ho utilizzato un Arduino2009, ma anche con un Nano ottengo lo stesso comportamento.
Potete consigliarmi qualcosa?Il problema è parecchio frustante, perchè così non ottengo delle rilevazioni di temperatura affidabili!

PS: per provare a far variare i valore dell'analogRead per adesso sto utilizzando sul pin 0 un termistore, e sul pin1 un potenziometro da 2.2K...ma i risultati non cambiano. Una fa variare l'altra

Sulla lettura consecutiva si sta discutendo anche in un altro topic.
Per separare le letture fai un analogread a vuoto.

PaoloP:
Per separare le letture fai un analogread a vuoto.

Non serve nulla, è tutto spiegato qui.

astrobeed:
Non serve nulla, è tutto spiegato qui.

Si ma...

astrobeed:
In questi casi la vera soluzione è aumentare il tempo di sampling del ADC, però su Arduino è fisso a ~10ksps e per modificarlo tocca agire direttamente su i registri del ADC, se non si è capaci di farlo si fa prima ad eseguire 2-3-...n letture consecutive in modo da ottenere lo stesso il corretto valore.

siccome non so manipolare correttamente i registri faccio fare una lettura a vuoto cosi risolvo il problema.
E' un workaround lo so e non la soluzione definitiva, ma funziona. ]:smiley:

EDIT: Mi correggo... meglio fare più letture. :wink:

void loop(){
int lettacqua, lettsonda;
for (byte x=0; x<3;x++) lettacqua = analogRead(pin_acqua);
for (byte x=0; x<3;x++) lettsonda = analogRead(pin_sonda);  
t_check(lettacqua, lettsonda);
}

Cavolo! Pensavo fosse un problema molto più semplice! Mi sono andato a impelagare in un bel pasticcio :smiley:

Oppure puoi fare così con piccole modifiche al codice.

void loop(){
t_check(multiread(pin_acqua,3),multiread(pin_sonda,3));
}

int multiread (byte pinread, byte n=1)
{
int lettura;
for (byte x=0; x<n; x++) lettura = analogRead(pinread);
return lettura;
}

n è il numero delle letture. (max 254)
Nota che la funzione restituisce solo l'ultima lettura, non fa ne la somma ne la media.

Nota che la funzione restituisce solo l'ultima lettura, non fa ne la somma ne la media.

motivo per cui il compilatore potrebbe decidere arbitrariamente di eliminare il ciclo.. forse se metti uno sleep(1)... o forse basta lo sleep(1) senza multiple letture.. non so

Quindi per risolvere potrei fare una cosa del genere?

#include <LiquidCrystal.h>

#define INTERVALLO_LETTURE 1
#define pin_acqua 0
#define pin_sonda 1

unsigned long ultima_media_time=0;

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

void loop(){
  t_check(pin_acqua, pin_sonda);
}
 
 
 void t_check(int lettura_acqua, int lettura_sonda) {

    if((millis() - ultima_media_time) / 1000 > (INTERVALLO_LETTURE)) {                        //inizia a fare questa operazione ogni tot secondi, in questo caso fa le letture ogni 1 secondo
      int misurazione1 = 0;
      int misurazione2 = 0;
      ultima_media_time = millis();                                                          //Prende il tempo di quando ho fatto la misurazione
      for(int i=0; i<10; i++){
      misurazione1 = analogRead(lettura_acqua);
      }
      for(int j=0; j<10; j++){
      misurazione2 = analogRead(lettura_sonda);
      }
      Serial.print("T-camera: ");
      Serial.print(misurazione1);
      Serial.print("  ");
      Serial.print("T-acqua: ");
      Serial.println((map(misurazione2, 0, 1023, 0, 255)));
    }
  }

Se ho scritto cavolate consigliatemi :slight_smile:

lesto:
motivo per cui il compilatore potrebbe decidere arbitrariamente di eliminare il ciclo..

Ma assolutamente no, al massimo potrebbe segnalarti la cosa con una warning, ma non gcc perché non è così "intelligente".

mi ricordo che tempo fa feci qualche prova a tal proposito, e se la variabile assegnata nel ciclo non era usata, il ciclo veniva tagliato... e da lì sono paranoico su queste cose :grin:

il fatto che la variabile sia solo assegnata non vorrei che facesse casino. Ma se sei sicuro meglio così

Nulla, inserendo i cicli for per 10 letture i valori si influenzano ancora

Per me hai inserito i sensori nello stesso pin e non lo vuoi ammettere. ]:smiley: ]:smiley: ]:smiley:

hermit274:
Nulla, inserendo i cicli for per 10 letture i valori si influenzano ancora

Il termistore è un PTC o un NTC, quan'tè il suo valore ohmmico nominale ?

Per me hai inserito i sensori nello stesso pin e non lo vuoi ammettere.

Se veramente fosse così mi sarei sotterrato per aver aperto un topic inutilmente :sweat_smile:

Il termistore è un PTC o un NTC, quan'tè il suo valore ohmmico nominale ?

Comunque il termistore mi sembra sia un PTC, se ben ricordo, domani mattina vi saprò dire meglio, e il suo valore nominale a t standard di riferimento è 10K

Comunque ragazzi mi sono accorto che il problema si risolve mettendo un delay tra i due cicli for. Il bello che deve esser anche un delay abbastanza "lungo". Se metto un valore di 5 millisecondi, nonostante i cicli le letture continuano ad essere falsate. Se metto delay più lunghi, dell'ordine dei 500 millisecondi tutto funziona alla grande. Come mai?

Astro a detto che gli ingressi lasciati flottanti misurano lo stesso valore di quello precedente.
Non è che sul secondo pin il sensore è mal collegato e quindi l'analogread legge lo stesso valore?

hermit274:
Comunque ragazzi mi sono accorto che il problema si risolve mettendo un delay tra i due cicli for. Il bello che deve esser anche un delay abbastanza "lungo". Se metto un valore di 5 millisecondi, nonostante i cicli le letture continuano ad essere falsate. Se metto delay più lunghi, dell'ordine dei 500 millisecondi tutto funziona alla grande. Come mai?

L'ADC è uno solo a cui sono collegati tramite un multiplexer tutti i pin analogici, il valore analogico viene copiato in un condensatore di sample and hold che necessita di tempo per caricarsi e scaricarsi in base alla corrente che circola. Se hai un'alta impedenza la corrente che circola è poca e quindi ci vuole più tempo per caricare/scaricare il condensatore.

Ciao

ok...ho capito. Per risolvere ho dovuto fare necessariamente in questo modo altrimenti l'analogread mi dava valori falsati e anche di parecchio!

for(int i=0; i<4; i++){
      misurazione_acqua = analogRead(lettura_acqua);
      delay(10);
      }
      
      for(int j=0; j<4; j++){
      misurazione_sonda = analogRead(lettura_sonda);
      delay(10);
      }
      Serial.print("T-camera: ");
      Serial.print(misurazione_sonda);
      Serial.print("  ");
      Serial.print("T-acqua: ");
      Serial.println((map(misurazione_acqua, 0, 1023, 0, 255)));

mettendo un unico delay tra i due cicli sembrava avessi risolto il problema ma in realtà non era così, mi dava ancora letture falsate.
Spero di essere stato d'aiuto per qualcuno :slight_smile: