Pin analogici LM35

Ciao, sono nuovo del forum, avrei un problema con il progetto che sto realizzando:

utilizzo Arduino Due e la Ethernet Shield, ho collegato a un pin analogico (A11) l'uscita di un sensore di temperatura in tensione (LM35), una volta letto il valore e calcolata la temperatura la vado a salvare sulla microSD presente sulla shield. Il problema e' che quando vado a leggere la prima volta la temperatura e' corretta, mentre la seconda volta, ovvero dopo che ho effettuato la scrittura su microSD il valore che leggo e' sempre zero. La cosa strana e' che se sul pin analogico al posto del sensore metto un valore fisso di tensione piu alto funziona tutto. Inoltre il pin A11 non e' uno dei pin in comune con shield quindi non dovrebbe dare fastidio.

Qualcuno sa darmi qualche spiegazione?

Spero di essermi spiegato bene.

Grazie in anticipo

Con quale tensione alimenti LM35?
Attenzione, non puoi fornire più di 3V3 ai pin dell'Arduino Due, rischi di guastare il chip.

Lo alimento con i 5v e in uscita mi da una tensione di circa 0,26V che varia poi al variare della temperatura, ma comunque nell'ordine dei mV.

Se il LM35 da 10mV/°C cosa vuoi che Ti dia se non 260mV a 26°C ?

Ciao Uwe

Ma infatti va bene. Il problema e' che quando vado a leggere la prima volta la temperatura e' corretta, mentre la seconda volta, ovvero dopo che ho effettuato la scrittura su microSD il valore che arduino legge è sempre 0.0 mentre sull'uscita dell'LM35 sono ancora presenti 0,26v.

Sembrerebbe un problema di sketch, potresti postarlo?

Eccolo: leggo e calcolo la temperatura, scrivo il file index.htm su micro SD e faccio un trasferimento con il protocollo FTP.

#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>

#define FTPWRITE    //con questo dichiarazione abilito l'upload FTP
#define LM35 A5

byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x86, 0x5A }; 
IPAddress ip( 192, 168, 3, 9);     // assegno un ip ad arduino   
IPAddress gateway( 192, 168, 2, 1 );  // ip del router a cui è collegato
IPAddress subnet( 255, 255, 254, 0 ); // maschera della sottorete

IPAddress server( **, ***, ***, **);  // ip del server per la comunicazione FTP

EthernetClient client;
EthernetClient dclient;

int pin_write = 22;
int pin_sys = 23;
int pin_ftp = 24;
int pin_ftp_work = 25;
int pin_temp=  11;   // pin A1 analogico per i dati del sensore di temperatura
float sens_temp = 0;

char outBuf[128];
char outCount;
float temp;
byte inChar;
File myFile;


void setup()
{
  Serial.begin(9600);
  
  pinMode(pin_write, OUTPUT);
  pinMode(pin_sys, OUTPUT);
  pinMode(pin_ftp, OUTPUT);
  pinMode(pin_ftp_work, OUTPUT);
  
  analogRead(pin_temp); //lettura a vuoto per assestamento
  
  // inizializzo la scheda SD e controllo il collegamento
  Serial.print("Inizializzo SD card...");
  if(SD.begin(4) == 0)
  {
    Serial.println("Inizializzazione SD fallita");          
  }
  Serial.println("inizializzazione completata."); 
 
  Ethernet.begin(mac, ip, gateway, gateway, subnet); 
  digitalWrite(10,HIGH);
  delay(2000);
 // Serial.println("Ready. Press f or r");
  digitalWrite(pin_sys, HIGH);
}

void loop()
{
  digitalWrite(pin_ftp_work, LOW);
  //inChar = Serial.read();
  
    
  compilo();
 
  if(inChar == 'f')
  {
    digitalWrite(pin_ftp, LOW);
    digitalWrite(pin_ftp_work, HIGH);
    if(doFTP()) Serial.println("FTP OK");
    else Serial.println("FTP FAIL");
  }
  digitalWrite(pin_ftp, HIGH); 

}



void compilo()
{

    sens_temp = analogRead(pin_temp);
    delay(500);
    temp = (sens_temp * 100.0 * 3.4)/1024.0; // Calcolo temperatura in gradi
    delay(500);
    Serial.println(sens_temp);
    Serial.println(temp);
  
 
  // controllo se il file esiste nel caso esiste lo elimino per sovrascriverlo
  if (SD.exists("index.htm")){ 
   SD.remove("index.htm");
  }
  else {
   Serial.println("Il file index non esiste");  
  } 
  
   myFile = SD.open("index.htm", FILE_WRITE); // apro il file
   if (myFile) {
     
    //costruisco pagina html e la scrivo sul file index.htm
    Serial.print("Compilo index.htm ...");
   // digitalWrite(pin_write, HIGH);
    //myFile.println("HTTP/1.1 200 OK.....");
    //myFile.println("Content-Type: text/html");
    myFile.println();
    myFile.println("<html><head><title>ARDUINO</title><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' ></head><body>");
    myFile.println("<meta http-equiv=\"refresh\" content=\"5\">");
    myFile.println("<div  align='center'>"); 
    myFile.println("<h1>MONITOR SENSORI</h1><hr />");
    myFile.println("<p>TEMPERATURA = ");
    myFile.print(temp);
    myFile.println(" C 
</p>");
    myFile.println("</div>");
    myFile.println("</body></html>");
    delay(8000); // aspetto che sia completata la scrittura
    myFile.close();   // chiudo il file
    digitalWrite(pin_write, LOW);
    Serial.println("Fatto.");
    delay(1000);
    inChar='f';
    

  } else {
    Serial.println("Errore durante l'apertura di index.htm");
  }
  
 
}

File fh;

byte doFTP()
{
#ifdef FTPWRITE
  fh = SD.open("index.htm",FILE_READ);
#else
  SD.remove("index.htm");
  fh = SD.open("index.htm",FILE_WRITE);
#endif

  if(!fh)
  {
    Serial.println("SD open fail");
    return 0;    
  }

  Serial.println("SD opened");
  
  if (client.connect(server,21)) {
    Serial.println("Command connected");
  } 
  else {
    Serial.println("Command connection failed");
    fh.close();
    return 0;
  }

  if(!eRcv()) return 0;

// username account Ftp
  client.write("USER *******\r\n");

  if(!eRcv()) return 0;

// password account FTP
  client.write("PASS ********\r\n");

  if(!eRcv()) return 0;

  client.write("SYST\r\n");

  if(!eRcv()) return 0;

  client.write("PASV\r\n");

  if(!eRcv()) return 0;

// new code

  char *tStr = strtok(outBuf,"(,");
  int array_pasv[6];
  for ( int i = 0; i < 6; i++) {
    tStr = strtok(NULL,"(,");
    array_pasv[i] = atoi(tStr);
    if(tStr == NULL)
    {
      Serial.println("Bad PASV Answer");    
      client.stop();
      fh.close(); 
      return 0;  
    }
  }

  unsigned int hiPort,loPort;

  hiPort = array_pasv[4] << 8;
  loPort = array_pasv[5] & 255;

// end of new code

  Serial.print("Data port: ");
  hiPort = hiPort | loPort;
  Serial.println(hiPort);
  
  if (dclient.connect(server,hiPort)) {
    Serial.println("Data connected");
  } 
  else {
    Serial.println("Data connection failed");
    client.stop();
    fh.close();
    return 0;
  }

#ifdef FTPWRITE 
  client.write("STOR /www.************.it/index.htm\r\n");
#else
  client.write("RETR /www.************.it/index.htm\r\n");
#endif

  if(!eRcv())
  {
    dclient.stop();
    return 0;
  }

#ifdef FTPWRITE
  Serial.println("Writing");

// This needs improvement

  while(fh.available())
  {
    char c = fh.read();
    dclient.write(c);
  }

#else
  while(dclient.connected())
  {
    while(dclient.available())
    {
      char c = dclient.read();
      fh.write(c);      
      Serial.write(c); 
    }
  }
#endif

  dclient.stop();
  Serial.println("Data disconnected");
  
  if(!eRcv()) return 0;

  client.write("QUIT\r\n");

  if(!eRcv()) return 0;

  client.stop();
  Serial.println("Command disconnected");

  fh.close();
  Serial.println("SD closed");
  return 1;
}

byte eRcv()
{
  byte respCode;
  byte thisByte;

  while(!client.available()) delay(1);

  respCode = client.peek();

  outCount = 0;
  
  while(client.available())
  {  
    thisByte = client.read();    
    Serial.write(thisByte);

    if(outCount < 127)
    {
      outBuf[outCount] = thisByte;
      outCount++;      
      outBuf[outCount] = 0;
    }
  }

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }

  return 1;
}


void efail()
{
  byte thisByte = 0;

  client.write("QUIT\r\n");

  while(!client.available()) delay(1);

  while(client.available())
  {  
    thisByte = client.read();    
    Serial.write(thisByte);
  }

  client.stop();
  Serial.println("Command disconnected");
  fh.close();
  Serial.println("SD closed");
}

Ho provato ad usare Arduino Mega 2560 e non da nessun problema, riesce a leggere tutte le volte il valore corretto dell'LM35 sul pin analogico. Qualcuno mi sa dire quale potrebbe esserre il problema sulla scheda Arduino Due?

Ma togliendo tutto e lasciando solo la lettura della temperatura stampata sulla seriale, hai di questi problemi?
Cioè, la temperatura letta con la DUE è sempre corretta oppure ti dà un valore giusto e poi 0.0 anche così?

Togliendo tutto e lasciando solo la lettura non da problemi. Da quello che ho capito da dei problemi quando vado a scrivere sulla microSD. Ma non capisco perché e cosa può essere.

Andiamo per ordine. Aggiungendo ora la lib SD per salvare il log sulla schedina, senza libreria SPI e Ethernet, continua a funzionare regolarmente?
Prova cioè a fare 1 lettura, 1 salvataggio, 1 lettura, 1 salvataggio ecc..

Ho provato, ma niente da fare, sempre il solito problema, alla seconda lettura mi legge 0.0.
Ecco lo sketch che ho usato:

#include <SD.h>
#include <SPI.h>


int pin_write = 22;
int pin_sys = 23;
int pin_ftp = 24;
int pin_ftp_work = 25;
int pin_temp=  A11;   // pin A1 analogico per i dati del sensore di temperatura
float sens_temp = 0;

char outBuf[128];
char outCount;
float temp;
byte inChar;
File myFile;


void setup()
{
  Serial.begin(9600);
  
  pinMode(pin_write, OUTPUT);
  pinMode(pin_sys, OUTPUT);
  pinMode(pin_ftp, OUTPUT);
  pinMode(pin_ftp_work, OUTPUT);
  
  analogRead(pin_temp); //lettura a vuoto per assestamento
  
  // inizializzo la scheda SD e controllo il collegamento
  Serial.print("Inizializzo SD card...");
  if(SD.begin(4) == 0)
  {
    Serial.println("Inizializzazione SD fallita");          
  }
  Serial.println("inizializzazione completata."); 
  digitalWrite(10,HIGH);
  delay(2000);
  digitalWrite(pin_sys, HIGH);
}

void loop()
{
  digitalWrite(pin_ftp_work, LOW);    
  compilo();
}


void compilo()
{
    const uint8_t A11 = 65;
    sens_temp = analogRead(A5);
    delay(500);
    temp = (sens_temp * 100.0 * 3.4)/1024.0; // Calcolo temperatura in gradi
    delay(500);
    Serial.println(sens_temp);
    Serial.println(temp);
  
 
  // controllo se il file esiste nel caso esiste lo elimino per sovrascriverlo
  if (SD.exists("index.htm")){ 
   SD.remove("index.htm");
  }
  else {
   Serial.println("Il file index non esiste");  
  } 
  
   myFile = SD.open("index.htm", FILE_WRITE); // apro il file
   if (myFile) {
     
    //costruisco pagina html e la scrivo sul file index.htm
    Serial.print("Compilo index.htm ...");
   // digitalWrite(pin_write, HIGH);
    //myFile.println("HTTP/1.1 200 OK.....");
    //myFile.println("Content-Type: text/html");
    myFile.println();
    myFile.println("<html><head><title>ARDUINO</title><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' ></head><body>");
    myFile.println("<meta http-equiv=\"refresh\" content=\"5\">");
    myFile.println("<div  align='center'>"); 
    myFile.println("<h1>MONITOR SENSORI</h1><hr />");
    myFile.println("<p>TEMPERATURA = ");
    myFile.print(temp);
    myFile.println(" C 
</p>");
    myFile.println("</div>");
    myFile.println("</body></html>");
    delay(8000); // aspetto che sia completata la scrittura
    myFile.close();   // chiudo il file
    digitalWrite(pin_write, LOW);
    Serial.println("Fatto.");
    delay(1000);
  } else {
    Serial.println("Errore durante l'apertura di index.htm");
  } 
 
}

Mi spieghi questo?

    const uint8_t A11 = 65;
    sens_temp = analogRead(A5);

Mi spieghi questo?
Code:
const uint8_t A11 = 65;
sens_temp = analogRead(A5);

Era una riga reduce da una precedente versione ma non influisce. In ogni caso ho scoperto qual'è la causa del problema, è il delay, ovvero l'attesta prima di chiudere il file per aspettare che finisca la scrittura. Se tolgo quel delay legge sempre correttamente la temperatura, il problema è che dopo non fa in tempo a scrivere i dati sul file. Come posso ovviare a questo problema?

Ma intendi il delay(8000)?
E come c'entrerebbe con la lettura analogica del sensore?

Comunque, prova a fare 2, 3 letture analogiche del pin, a volte risolve i problemi di letture sballate.
Vale a dire, al posto di:

sens_temp = analogRead(pin_temp);

fai:

for (byte i = 0; i < 3; i++) {
  sens_temp = analogRead(pin_temp);
}

Problema risolto tramite il suggerimento di leo72.

Dovevo ripetere la lettura analogica 3 o 4 volte.

Grazie mille. :slight_smile: