Problema con Sensori di temperatura

Salve a tutti,

ho un problema con la lettura dei valore di due sensori : DHT22 e DS18B20.

Mi spiego meglio…
Ho scritto un semplice script di prova e funziona correttamente, inserendo però quest’ultimo nel mio progetto non funziona, o meglio non riesco a leggere i valori dai rispettivi sensori, anche se al momento della compilazione non ottengo errori.

Per utilizzare questi sensori nel mio progetto, ho creato un file .h chiamato sensore_temperatura e il suo rispettivo file .cpp

All’interno ho un costruttore dove passo il pin del sensore, il pin di un relè, un riferimento ad un’altra classe per la gestione dei messaggi di output e una variabile boolean per identificare il tipo di sensore.

Posto il codice sotto del file .h:

#ifndef sensore_temperatura_h
#define sensore_temperatura_h

//Librerie di sistema
#include <Arduino.h>
#include "codici_gestione_sistema.h"
#include "pinout.h"

//Includo il file per la gestione del sensore di temperatura DHT
#include <SimpleDHT.h>

// librerie per il funzionamento del sensore DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>

class sensore_temperatura
{

	public:

		//sensore_temperatura(int S_TMAC, int RL_VEN, codici_gestione_sistema C_G_S);
		sensore_temperatura(int, int, codici_gestione_sistema, bool);
		//sensore_temperatura(int, int, codici_gestione_sistema);

		float GetTemperatura();
		float GetUmidita();
		void AttivaVentilatore();
		void DisattivaVentilatore();
		int GetStatoVentilatore();

	private:

		bool _sensoreDallas;
		int _S_TMAC;
		int _RL_VEN;
        SimpleDHT22 _sensTemp;
		DallasTemperature _sensore;
		OneWire _oneWire;
		codici_gestione_sistema _C_G_S;

};


#endif

e ora il codice del file .cpp:

#include "sensore_temperatura.h"

sensore_temperatura::sensore_temperatura(int S_TMAC, int RL_VEN, codici_gestione_sistema C_G_S, bool sensoreDallas) {

	//Salvo la variavile sensoreDallas, che mi occorre per sapere se il sensore che sto leggendo e' un sensore
	//Dallas oppure un DHT22
	_sensoreDallas = sensoreDallas;

	//Salvo le variabili passate
	_S_TMAC = S_TMAC;
	_RL_VEN = RL_VEN;
	_C_G_S = C_G_S;

	//Ora controllo se il sensore che sto creando sia un sensore Dallas
	if (sensoreDallas) {

		//Imposto i due pinMode dei due parametri passati durante la creazione dell'instanza
		//pinMode(S_TMAC, INPUT);
		//pinMode(RL_VEN, OUTPUT);

		//Inizializzo il sensore Dallas
		//Per prima cosa imposto la connessione OneWire
		OneWire oneWire(_S_TMAC); 
		//Ora dichiaro l'oggetto sensore Dallas
		DallasTemperature sensore(&oneWire);

		//Salvo le due variabili del sensore
		_oneWire = oneWire;
		_sensore = sensore;

		//Avvio il sensore in lettura
		_sensore.begin();

	}
	//Se non e' un sensore Dallas allora si tratta di un sensore DHT22
	else {

		//Imposto i due pinMode dei due parametri passati durante la creazione dell'instanza
		//pinMode(S_TMAC, INPUT);
		//pinMode(RL_VEN, OUTPUT);

		//Salvo nelle variabili locali le due variabili passate
		_S_TMAC = S_TMAC;
		_RL_VEN = RL_VEN;
		_C_G_S = C_G_S;

		//Inizializzo il sensore DHT22
		SimpleDHT22 sensTemp(S_TMAC);

		//Creo un'istanza del sensore
		_sensTemp = sensTemp;

	}

}

//Funzione che restituisce un float contentente la temperatura
float sensore_temperatura::GetTemperatura() {

	//Creo la variabile float relativa alla temperatura
	float temperatura = 0 ;

	//Aggiungo un piccolo delay di sincronizzazione
        delay(50);

	//Per prima cosa controllo quale sensore sto utilizzando

	//Primo caso : Sensore Dallas
	if (_sensoreDallas) {

		//Attivo la richiesta della temperatura
		_sensore.requestTemperatures();

		//Aggiungo un piccolo delay di sincronizzazione
    	delay(50);

  		//Memorizzo la temperatura letta in gradi Celsius
  		temperatura = _sensore.getTempCByIndex(0);

		//Aggiungo un piccolo delay di sincronizzazione
    	delay(50);

		Serial.print("Dallas ");
		Serial.println(temperatura);

	}

	//Secondo caso : Sensore DHT
	else {

		//Creo la variabile temporanea relativa all'umidita'
		float umidita = 0 ;

		//Creo la variabile intera relativa a simpleDHTErrSuccess
		int err = SimpleDHTErrSuccess;

		Serial.print("DHT ERR ");
		Serial.println(err);

		if ((err = _sensTemp.read2(&temperatura, &umidita, NULL)) != SimpleDHTErrSuccess){

			temperatura = 999;
			Serial.print("DHT ERR1 ");
			Serial.println(err);
		}

		//Aggiungo un piccolo delay di sincronizzazione
    	        delay(50);

		Serial.print("DHT ");
		Serial.println(temp);

	}

	//Controllo che non ci siano valori nulli della temperatura, in caso di valore nullo ritorno 999
	if (!isnan(temperatura) && temperatura==999) return temperatura;
	else return 999;
	
}

Ho inserito un paio di Serial.print per fare un po di debug…

Dove sbaglio???

Grazie a tutti per l’aiuto!!

Fabrizio

In che senso non riesci a leggere i sensori?
A me lascia perpelesso l’ultima if

	if (!isnan(temperatura) && temperatura==999) return temperatura;

Ti posto il risultato della lettura del sensore DHT22

12:51:50.676 → DHT ERR 0
12:51:50.676 → DHT ERR1 4112
12:51:50.716 → DHT 0
12:51:50.716 → 999.00

L’ultimo if controlla se il dato ricevuto e valido, ovvero che non sia NULL o non sia 999 (999 lo imposto se ottengo qualche errore).

Diciamo che non è quest’ultimo if che mi preoccupa :sweat_smile:

Non sono pratico, ma dalla libreria non riesci a vedere a cosa corrispondono quei codici di errore?

Poi riguardo l’if, avevo capito lo scopo, ma lascia perplesso l’== col 999.

Il problema è che se utilizzo questo script:

#include <SimpleDHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// for DHT22, 
//      VCC: 5V or 3V
//      GND: GND
//      DATA: 2
int pinDHT22 = 44;
int pinDallas = 42;
SimpleDHT22 dht22(pinDHT22);

//Inizializzo il sensore Dallas
    //Per prima cosa imposto la connessione OneWire
    OneWire oneWire(pinDallas); 
    //Ora dichiaro l'oggetto sensore Dallas
    DallasTemperature sensore(&oneWire);

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

void loop() {
  // start working...
  Serial.println("=================================");
  Serial.println("Sample DHT22...");
  
  // read without samples.
  // @remark We use read2 to get a float data, such as 10.1*C
  //    if user doesn't care about the accurate data, use read to get a byte data, such as 10*C.
  float ciao = 0;
  float bye = 0;
  int err = SimpleDHTErrSuccess;
  if ((err = dht22.read2(&ciao, &bye, NULL)) != SimpleDHTErrSuccess) {
    Serial.print("Read DHT22 failed, err="); Serial.print(SimpleDHTErrCode(err));
    Serial.print(","); Serial.println(SimpleDHTErrDuration(err)); delay(2000);
    return;
  }
  
  Serial.print("Sample OK: ");
  Serial.print((float)ciao); Serial.print(" *C, ");
  Serial.print((float)bye); Serial.println(" RH%");

  Serial.println("Sensore Dallas");

  float temperatura = 0 ;

  //Attivo la richiesta della temperatura
    sensore.requestTemperatures();

    //Aggiungo un piccolo delay di sincronizzazione
      delay(50);

      //Memorizzo la temperatura letta in gradi Celsius
      temperatura = sensore.getTempCByIndex(0);

    //Aggiungo un piccolo delay di sincronizzazione
      delay(50);

    Serial.print("Dallas ");
    Serial.println(temperatura);
  
  // DHT22 sampling rate is 0.5HZ.
  delay(2500);
}

funziona tutto correttamente.

Utilizzo il 999 per evitare che si possa confondere con un valore di temperatura. Il metodo GetTempertatura() deve restituire un valore float, quindi quando vado a leggere poi quel valore devo capire se tutto è andato bene oppure c’è stato un problema.

Tutto qua, intercetto l’errore con il valore 999.

Inoltre, l’errore 4112 non è sempre lo stesso, a volte mi da 3088, altre volte altri valori etc…

Sì, l’ho capito. Sicuro che serva == invece di !=?
Cmq potrebbe non essere lì il problema.

Si giusto!! errore mio.

Inizialmente doveva essere senza ! poi ho negato tutto… Il problema però è prima poichè con i Serial.print ottengo quel problema.

Prova a stampare gli errori in HEX

e come si fa ?

Serial.println(Value, HEX);

Ho parzialmente risolto il problema della lettura con il sensore Dallas…

Inserendo nel metodo GetTemperatura:

DallasTemperature sensore(&_oneWire);

ovviamente modificando la parte sotto sostituendo _sensore con sensore

però diciamo che questa soluzione anche se funzionante mi piace poco.

Ho provato a fare lo stesso con il sensore DHT ma non funziona :frowning:

Non sono pratico con le classi, ma in effetti il passaggio dalle variabili intermedie mi lasciava perplesso.
SimpleDHT è una classe. Puoi fare un’assegnazione diretta? Forse assegni un puntatore… ma per me è un terreno minato e non vorrei dire cavolate.

Ho provato con questo codice, sostituendolo ovviamente nella parte precedente:

                SimpleDHT22 sensTemp(_S_TMAC);

		Serial.print("Pin DHT ");
		Serial.println(_S_TMAC);

		//Creo la variabile temporanea relativa all'umidita'
		float umidita = 0 ;

		//Creo la variabile intera relativa a simpleDHTErrSuccess
		int err = SimpleDHTErrSuccess;

		Serial.print("DHT ERR ");
		Serial.println(err);

		//if ((err = _sensTemp.read2(&temperatura, &umidita, NULL)) != SimpleDHTErrSuccess){
		if ((err = sensTemp.read2(&temperatura, &umidita, NULL)) != SimpleDHTErrSuccess){
		
			temperatura = 999;
			Serial.print("DHT ERR1 ");
			Serial.println(err);

		}

		//Aggiungo un piccolo delay di sincronizzazione
    	        delay(50);

		Serial.print("DHT ");
		Serial.println((int)temperatura);

ma ho lo stesso problema.

Anche io inizialmente ho pensato ad un problema di assegnazione, ma pur facendo cosi non funziona!

Riguardo gli errori, se non ho capito male:

// High 8bits are time duration.
// Low 8bits are error code.
// For example, 0x0310 means t=0x03 and code=0x10,
  • 4112 dec = 0x1010 = l’errore è 0x10 = 16 in decimale =
// Error to wait for start low signal.
#define SimpleDHTErrStartLow 16
  • 3088 dec = 0x0C10 = l’errore è sempre 0x10 = 16 in decimale

Guarda, la sensazione è che con l’assegnazione tra istanze di classe venga assegnato un puntatore. Passando per una variabile locale, quando esci dal costruttore la variabile viene distrutta e il puntatore punta chissàdove…
Ma ripeto che su questi argomenti non sono ferrato, quindi meglio se aspetti qualcuno di quelli bravi.

//Funzione che restituisce un float contentente l'umidita'
float sensore_temperatura::GetUmidita() {

	SimpleDHT22 _sensTemp(44);

	//Creo la variabile umita di tipo float che conterra'
	//il valore dell' umidita' letta dal sensore
    float umidita = 0 ;
	float temperatura = 0 ;

    //Aggiungo un piccolo delay di sincronizzazione
    delay(50);

	//Creo la variabile intera relativa a simpleDHTErrSuccess
	int err = SimpleDHTErrSuccess;

	Serial.print("DHT ERR ");
	Serial.println(err);

	if ((err = _sensTemp.read2(&temperatura, &umidita, NULL)) != SimpleDHTErrSuccess){

		umidita = 999;
	}

	Serial.print("DHT UMIDITA' ");
	Serial.println(umidita);

	//Controllo che non ci siano valori nulli della umidita', in caso di valore nullo ritorno 999
	if (!isnan(umidita) && umidita != 999) return umidita;
	else return 999;

}

Anche con la funzione che restituisce l’umidità ho lo stesso problema, anche istanziando il sensore all’interno del metodo.

Non uso quella libreria.
Di solito uso la DHT sensor library di Adafruit. Però non l’ho mai usata dentro a classi / medoti.

Volevo usarla anche io, ma mi dà errore e non me la prende. Non capisco come mai.