DHT11 errore checksum

Ciao a tutti,
sto utilizzando il sensore DHT11 per il monitoraggio di umidità e temperatura.

C'è un comportamento che proprio non capisco, di tanto in tanto, diciamo una volta al minuto circa, benché venga dato checksum OK arrivano dei dati sbagliati.

Il DHT11 è cablato al termine di un cavetto telefonico lungo circa 6mt (due poli per VCC, due poli per SIGN e due poli per GND). Come da manuale ho installato una resistenza da 5Kohm tra SIGN e VCC.

Ho comunque provato anche resistenze di valore diverso ma il risultato non cambia. Ho provato anche ad installare un condensatore da 100nF tra SIGN E GND ma ugualmente il risultato non cambia.

Lo sketch è:

/*************************************************************************************************************
*
* Title			    : Monitoraggio temperatura ed umidità con visualizzazione su xively
* Version		            : v4
* Last updated	            : 20.11.14
* Target		            : Arduino UNO
* Installato il                 : 20 Novembre 2014
* IDE                            : 1.0.6
***************************************************************************************************************

                       Monitoraggio temperatura ed umidità con visualizzazione su xively
                       https://xively.com/feeds/281717909
  XIVELY APY KEY:      tuHwQmRgHRrcO19dzHzSpTJ3C7vSBDANrMxVLyVaVf6baWSc
  XIVELY FEEDS:        281717909


/*************************************************************************************************************

      D2 = ING DHT11 per monitoraggio umidità e temperatura

**************************************************************************************************************/


#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>

// MAC address for your Ethernet shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// Your Xively key to let you upload data
char xivelyKey[] = "tuHwQmRgHRrcO19dzHzSpTJ3C7vSBDANrMxVLyVaVf6baWSc";

// Define the strings for our datastream IDs
char sensorId[] = "Umidità_Umidif.";
char sensorId2[] = "Temperatura_Umidif.";

XivelyDatastream datastreams[] = {
    XivelyDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT),
    XivelyDatastream(sensorId2, strlen(sensorId2), DATASTREAM_FLOAT),
    
    };
// Finally, wrap the datastreams into a feed
XivelyFeed feed(281717909, datastreams, 2 /* number of datastreams */);

EthernetClient client;
XivelyClient xivelyclient(client);

/////////////////////////////////FINE INIZIALIZZAZIONE XIVELY 
// 
//   FILE:  dht11_test1.pde
// PURPOSE: DHT11 library test sketch for Arduino
// DHT11 connesso a pin DIGITALE 2
//

//Celsius to Fahrenheit conversion
double Fahrenheit(double celsius)
{
	return 1.8 * celsius + 32;
}

//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
	return celsius + 273.15;
}

// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm 
double dewPoint(double celsius, double humidity)
{
	double A0= 373.15/(273.15 + celsius);
	double SUM = -7.90298 * (A0-1);
	SUM += 5.02808 * log10(A0);
	SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
	SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
	SUM += log10(1013.246);
	double VP = pow(10, SUM-3) * humidity;
	double T = log(VP/0.61078);   // temp var
	return (241.88 * T) / (17.558-T);
}

// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
	double a = 17.271;
	double b = 237.7;
	double temp = (a * celsius) / (b + celsius) + log(humidity/100);
	double Td = (b * temp) / (a - temp);
	return Td;
}


#include <dht11.h>

dht11 DHT11;

#define DHT11PIN 2   // PIN DIGITALE 2

void setup()
{
  Serial.begin(9600);
  Serial.println("DHT11 TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();
  
  while (Ethernet.begin(mac) != 1)
  {
    Serial.println("Error getting IP address via DHCP, trying again...");
    delay(15000);
  }

}


void loop()
{
  Serial.println("\n");

  int chk = DHT11.read(DHT11PIN);

  Serial.print("Read sensor: ");
  switch (chk)
     {  
        case 0: Serial.println("OK"); 
    {
      Serial.print("Humidity (%): ");
  Serial.println((float)DHT11.humidity, 2);
  datastreams[0].setFloat(DHT11.humidity);
  Serial.print("Read sensor value ");
  Serial.println(datastreams[0].getFloat());

  Serial.print("Temperature (oC): ");
  Serial.println((float)DHT11.temperature, 2);
  datastreams[1].setFloat(DHT11.temperature);
  Serial.print("Read sensor value ");
  Serial.println(datastreams[1].getFloat());
  
  Serial.println("Uploading it to Xively");
  int ret = xivelyclient.put(feed, xivelyKey);
  Serial.print("xivelyclient.put returned ");
  Serial.println(ret);

  //Serial.println();
  delay(2000);
  break;
     }
    case -1: Serial.println("Checksum error"); break;
    case -2: Serial.println("Time out error"); break;
    default: Serial.println("Unknown error"); break;
     }
 
  delay(100);
}

// END OF FILE

Qualcuno sa spiegarmi il motivo dell'errore?
E' possibile visualizzare il funzionamento/non funzionamento dello sketch presso: https://xively.com/feeds/281717909

Grazie e buona giornata a tutti.

Qualche appunto:

1 - per ridurre l'occupazione di memoria RAM, ti conviene usare la funzione F() con i vari Serial.print;

2 - nella formula del dewpoint (punto di rugiada) adoperi la variabile A0 che può creare problemi di interpretazione, essendo A0 il pin di un ingresso analogico;

3 - il cavo di 6m, se puoi, riducilo il più possibile;

4 - elimina le (inutili) parentesi graffe nel case 0 dello switch

Grazie cyberhs, risolutivo come sempre!

Già solo modificando A0 sembra che tutto vada molto meglio.

Grazie ancora.

Ops...
qualche schifezza esce ancora...

#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>

// MAC address for your Ethernet shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// Your Xively key to let you upload data
char xivelyKey[] = "tuHwQmRgHRrcO19dzHzSpTJ3C7vSBDANrMxVLyVaVf6baWSc";

// Define the strings for our datastream IDs
char sensorId[] = "Umidità_Umidif.";
char sensorId2[] = "Temperatura_Umidif.";

XivelyDatastream datastreams[] = {
    XivelyDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT),
    XivelyDatastream(sensorId2, strlen(sensorId2), DATASTREAM_FLOAT),
    
    };
// Finally, wrap the datastreams into a feed
XivelyFeed feed(281717909, datastreams, 2 /* number of datastreams */);

EthernetClient client;
XivelyClient xivelyclient(client);

/////////////////////////////////FINE INIZIALIZZAZIONE XIVELY 
// 
//   FILE:  dht11_test1.pde
// PURPOSE: DHT11 library test sketch for Arduino
// DHT11 connesso a pin DIGITALE 2
//

//Celsius to Fahrenheit conversion
double Fahrenheit(double celsius)
{
	return 1.8 * celsius + 32;
}

//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
	return celsius + 273.15;
}

// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm 
double dewPoint(double celsius, double humidity)
{
	double C= 373.15/(273.15 + celsius);
	double SUM = -7.90298 * (C-1);
	SUM += 5.02808 * log10(C);
	SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/C)))-1) ;
	SUM += 8.1328e-3 * (pow(10,(-3.49149*(C-1)))-1) ;
	SUM += log10(1013.246);
	double VP = pow(10, SUM-3) * humidity;
	double T = log(VP/0.61078);   // temp var
	return (241.88 * T) / (17.558-T);
}

// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
	double a = 17.271;
	double b = 237.7;
	double temp = (a * celsius) / (b + celsius) + log(humidity/100);
	double Td = (b * temp) / (a - temp);
	return Td;
}

#include <dht11.h>
dht11 DHT11;
#define DHT11PIN 2   // PIN DIGITALE 2

void setup()
{
  Serial.begin(9600);
  Serial.println(F("DHT11 TEST PROGRAM "));
  Serial.print(F("LIBRARY VERSION: "));
  Serial.println(F(DHT11LIB_VERSION));
  Serial.println();
  
  while (Ethernet.begin(mac) != 1)
  {
    Serial.println(F("Error getting IP address via DHCP, trying again..."));
    delay(15000);
  }
}


void loop()
{
  Serial.println(F("\n"));

  int chk = DHT11.read(DHT11PIN);

  Serial.print(F("Read sensor: "));
  switch (chk)
       {
        case 0: Serial.println("OK");
    
      Serial.print(F("Humidity (%): "));
      Serial.println((float)DHT11.humidity, 2);
      datastreams[0].setFloat(DHT11.humidity);
      Serial.print(F("Read sensor value "));
      Serial.println(datastreams[0].getFloat());
  
      Serial.print(F("Temperature (oC): "));
      Serial.println((float)DHT11.temperature, 2);
      datastreams[1].setFloat(DHT11.temperature);
      Serial.print(F("Read sensor value "));
      Serial.println(datastreams[1].getFloat());
  
      Serial.println(F("Uploading it to Xively"));
      //int ret = xivelyclient.put(feed, xivelyKey);
      //Serial.print(F("xivelyclient.put returned "));
      //Serial.println(ret);

      //Serial.println();
  
    //  delay(2000); 
  break;
  
    case -1: Serial.println("Checksum error"); break;
    case -2: Serial.println("Time out error"); break;
    default: Serial.println("Unknown error"); break;
     }
   int ret = xivelyclient.put(feed, xivelyKey);
   Serial.print(F("xivelyclient.put returned "));
   Serial.println(ret);

  delay(100);
}

// END OF FILE

Mannaggia!

Mmmm...come detto da cyberhs sicuramente i 6 metri di cavo non sono esattamente l'ideale per questo tipo applicazione.... penso personalmente di non aver mai superato il metro....

Questi 6 metri di cavo dove passano? magari in una canalina con molti altri cavi? o vicino a qualche dispositivo che potrebbe interferire ? ( ad esempio io ebbi problemi con una presa di quelle a radiocomando)

I 6m di cavo sono fissati al muro e lontani da apparecchi elettrici.

il data sheet che ho trovato da addirittura una distanza di 30m di cavo... l'importante è utilizzare una resistenza tra VCC e DATA... ma non mi sembra una cosa realistica...

Ho fatto girare per un po' uno sketch che utilizza il dht11 su un ing analog di arduino ma... non riesce proprio a comunicarci...

In effetti, senza cavo lo sketch funziona benissimo!

Accorciare il cavo ed avvicinare arduino al punto dove ho installato il sensore è un problema...

Adesso ho modificato lo sketch in modo tale da avere una lettura ogni 100sec. ma come si può vedere su: https://xively.com/feeds/281717909 capitano delle letture "strane"

Ma ciò che vorrei capire è: perché il checksum mi da OK benché i valori siano sballati?

Grazie

gelholder:
Ma ciò che vorrei capire è: perché il checksum mi da OK benché i valori siano sballati?

Se il checksum è corretto vuol dire che è il sensore ad inviare dati sballati, il problema, quasi sicuramente, è sulla alimentazione del sensore, disturbi e scarsa tensione possono causare letture errate sebbene l'invio dei dati è corretto.
Prova ad alimentare direttamente il sensore, vanno bene tre batterie da 1.5V in serie, stacca il +5V proveniente da Arduino e lascia in comune il gnd, quasi sicuramente spariscono tutte le letture errate, se è così hai la conferma che il problema è l'alimentazione.
Se Arduino è alimentato da USB può benissimo essere questa la causa, la tensione proveniente dalla USB oltre ad essere un valore mai 5V esatti contiene moltissimo rumore che sommato ai sei metri di cavo possono bastare a disturbare il normale funzionamento del sensore, in questo caso la soluzione è semplicissima, alimenta Arduino da sorgente esterna, 7-9V, tramite l'apposito ingresso.

Arduino è alimentato a 9v.

Proverò a seguire il tuo consiglio e ad alimentare il sensore in maniera autonoma mantenendo il GND in comune.

Grazie