DHT-22 humidity temp sensor stops updating after about 30 minutes

DHT-22 humidity temp sensor stops updating after about 30 minutes.
My display shows alternating temp in Celsius and humidity every 10 seconds and works OK
for about 30 minutes.
After that the temperature shows 0 C on the display and a humidity of 44.6%.
Only a restart makes it OK again for some time.
Tried adding a decoupling capacitor on the V+ and GND and various pull-up resistors (4.7 to 10 KOhm).
Wire connection to DHT-22 to board is about 20 cm.

Pump motor, push-button and Led still work as expected, so no infinite loops.
Can it be conflicting libraries or is my sensor broken?
Or is it something stupid in my code?

/*
 Name:		HumiditySwitch.ino
 Created:	23/6/2021 12:56:53
 Author:	ajkes
 Based on:
 How to use the DHT-22 sensor with Arduino uno
   Temperature and humidity sensor
  https://www.makerguides.com/tm1637-arduino-tutorial/

  <JC_Button.h>          // https://github.com/JChristensen/JC_Button

  Using ATmega328P(old bootloader, Nano)

*/


#include <arduino.h>
#include <DHT.h>
#include <TM1637Display.h>
#include <JC_Button.h> 
#include <arduino-timer.h>
#include <Adafruit_Sensor.h>

//Constants
#define DHTPIN        4 	// DHT sensor connects to this pin.
#define CLK           2		// CLK pin for display.
#define DIO           3		// DIO pin for display.
#define DHTTYPE DHT22		// DHT 22  (AM2302).
#define MOTOROUTPIN   11	// Humidity  motor relay.
#define TEMPOUTPIN    12	// Heater relay.
#define BTNPIN        8		// Motor on/off button.
#define LEDPIN        9     // Motor on/off Led.

const uint8_t BUTTON_PIN(BTNPIN);
Button button(BUTTON_PIN);
const uint8_t celsius[] = { SEG_A | SEG_F | SEG_G };// Create lower case "C".
const uint8_t hum[] = {
  SEG_F | SEG_E | SEG_C | SEG_E | SEG_G };// Create lower case "h".
int seconds;
int Ontime = 60;
int Offtime = 30;
bool ReadingHum = false;
float temperature;
float humidity;
int ledState = HIGH;
bool heater = LOW;
bool ReadOK = false;
TM1637Display display = TM1637Display(CLK, DIO); // Create display object of type TM1637Display:
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor

auto timer = timer_create_default(); // create a timer with default settings

/// <summary>
/// Callback from timer.every(1000UL * 5, UpdateReading);
/// Alternate between reading Hum and temp
/// </summary>
/// <param name=""></param>
/// <returns>bool</returns>
bool UpdateReading(void*)
{
	if (ReadingHum)
	{
		ReadHum();
	}
	else
	{
		ReadTemp();
	}
	if (ReadOK)
	{
		//Switch heater ON or OFF
		if (humidity <= 10) 
		{
			//Serial.println("Hum < 10");
			digitalWrite(TEMPOUTPIN, LOW);
			heater = LOW;
		}
		else
		{
			digitalWrite(TEMPOUTPIN, HIGH);
			heater = HIGH;
			//Serial.println("Hum > 10");
		}

		//Prevent heater ON if temperature too high 
		if (temperature >= 40)
		{
			digitalWrite(TEMPOUTPIN, LOW);
			heater = LOW;
			//Serial.println("Temp 40+");
		}		
	}
	ReadingHum = !ReadingHum;
	return true;
}
/// <summary>
/// Callback from timer.every(1000UL, UpdateSeconds);
/// </summary>
/// <returns>bool</returns>
bool UpdateSeconds(void*)
{
	seconds++;
	if (seconds < Ontime)
	{
		if (humidity > 15)
		{
			//Serial.println("Hum > 15");
			digitalWrite(MOTOROUTPIN, ledState);// only run if pumpmotor is switched on(ledstate high
		}
		else
		{
			//Serial.println("Hum ! > 15");
			digitalWrite(MOTOROUTPIN, LOW);
		}
	}

	if (seconds >= Ontime)// only run pump-motor for fixed amount of time to prevent overheating
	{
		digitalWrite(MOTOROUTPIN, LOW);
		if (seconds >= Ontime + Offtime)
		{
			seconds = 0;
		}
	}
	//Serial.print("Updating Pump  ");
	//Serial.println(digitalRead(MOTOROUTPIN));
	return true;
}

void ReadTemp()
{
	temperature = dht.readTemperature();
	if (temperature > -10 && !isnan(temperature))//check for false reading
	{
		ReadOK = true;
	}
	else
	{
		ReadOK = false;
		//impossible number to show false temperature reading
		temperature = 88.8;
	}
	//show on display
	display.showNumberDecEx(temperature * 10, 0b11100000, false, 3, 0);
	display.setSegments(celsius, 1, 3);
}

void ReadHum()
{
	humidity = dht.readHumidity();
	if (humidity > 0 && !isnan(humidity))
	{		
		ReadOK = true;
	}
	else 
	{		
		humidity = 99.9;//impossible number to show false temperature reading
		ReadOK = false;
	}
	display.showNumberDecEx(humidity * 10, 0b11100000, false, 3, 0);
	display.setSegments(hum, 1, 3);
}

void setup()
{
	Serial.begin(9600);
	display.setBrightness(7);
	pinMode(DHTPIN, INPUT_PULLUP);//Makes DHT reading more reliable
	dht.begin();
	
	pinMode(MOTOROUTPIN, OUTPUT);
	pinMode(TEMPOUTPIN, OUTPUT);
	button.begin();	
	
	pinMode(LEDPIN, OUTPUT);
	digitalWrite(LEDPIN, ledState);
	digitalWrite(MOTOROUTPIN, HIGH);
	digitalWrite(TEMPOUTPIN, HIGH);
	timer.every(1000UL * 5, UpdateReading);
	timer.every(1000UL, UpdateSeconds);
}

void loop()
{
	timer.tick();
	delay(1);
	button.read();
	if (!ledState)
	{
		seconds = 0;
		digitalWrite(MOTOROUTPIN, LOW);
	}

	   // Returns true if the button state was released at the last call to read().
	   // Does not cause the button to be read.
	if (button.isReleased()) // set led state to indicate pump-motor is ON or OFF
	{
		ledState = !ledState; // SET ledState TO THE OPPOSITE OF ledState
		digitalWrite(LEDPIN, ledState); // WRITE THE NEW ledState		
	}
}

Compiler info:
Compiling 'HumidityControler' for 'ATmega328P (Old Bootloader) (Arduino Nano) (nano_atmega328old)'
Program size: 6.280 bytes (used 20% of a 30.720 byte maximum) (1,54 secs)
Minimum Memory Usage: 516 bytes (25% of a 2048 byte maximum)

Move up to a BME280.

Thirty of anything is suspicious. Often it's because you have stored something in an int and it overflowed. Anytime someone complains that their code fails after thirty seconds, it's usually actually 32767 milliseconds.

Your Seconds variable is an int :wink:

Seconds get reset to 0 after 90 seconds, so no problem there.

int seconds;
int Ontime = 60;
int Offtime = 30;
if (seconds >= Ontime)// only run pump-motor for fixed amount of time to prevent overheating
	{
		digitalWrite(MOTOROUTPIN, LOW);
		if (seconds >= Ontime + Offtime)
		{
			seconds = 0;
		}
	}

not "wrong" but there must be a clearer way to do this.

Can you try putting a ```
dht.begin();


in the code that resets the seconds? - just to clear the interface to the dht?

Hi,
Can you please post a circuit diagram?

Have you got a 1K or 4K7 resistor between 5V and the DHT-22 data pin?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

I could try to clear the interface to the DHT, but not in the code that resets the seconds,
it is only for controlling the pump-motor on/off time.
I'll use a third timer callback for that. But doing that will be a kind of an hack and not give
any insight about why the DHT-22 stops updating and shows 0 C on the display and a humidity
of 44.6% for infinity.

Hi,
How have you got your DHT and pump wires routed?
Have you got back EMF diode on your pump motor?
How are you controlling your pump?

A circuit diagram would be helpful.

Can you please post a image(s) of your project so we can see your component layout?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

It is difficult for me to provide image(s) of my project, all is in an enclosure and in use.
My project is a 3D printer filament dry box.
An airtight box with a heater to get the temperature 10 degrees Celsius above ambient temp and the DHT-22.
Two air hoses in and out, circulating air trough a 1 litre bottle of desiccant with the use of an air-pump.
A control box, containing 12 volt 10 amp power supply. 2 DC/DC converters for 5 and 3.3 volt.
A 2 relay board for pump(12V 1A) and heater(12V 5A), Arduino nano, Led display, Push-button, LED and pump.

I suspected the DHT buffer might need to reset. You could check this very easily by running the dhttester sketch and see if it crashes after running for a while (>30 min)

why should it show ANY specific value if its not working? it would have to between 0 and 100 as its a percentage.

Hi, @GrooverFromHolland

Well if this is the first iteration of your project, you need to make it serviceable.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, component names and pin labels.

Have you kept the DHT sensor wires away from the power wires and the relay and pump supply wiring?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

40 years experience in electronics design and repair, I know what I'm doing. Wiring and layout is too simple, so I won't post

You're catching us up! :grinning:

Can you isolate whether its the humidity sensor & code or something else that is causing the issue?

Why are you using a debounce library for one push button? it just adds unnecessary obscure complexity to your program. You havent said what the push biutton does; however I'd recommend hardware debouncing as explained here.

BlockquoteCan you isolate whether its the humidity sensor & code or something else that is causing the issue?

That is what I try to find out!

BlockquoteWhy are you using a debounce library for one push button? it just adds unnecessary obscure complexity to your program.

It's a habit, the JC_Button.h library is more than a debounce library. It has a lot of features that I often use:

 // Returns the current debounced button state, true for pressed,
        // false for released. Call this function frequently to ensure
        // the sketch is responsive to user input.
        bool read();

        // Returns true if the button state was pressed at the last call to read().
        // Does not cause the button to be read.
        bool isPressed();

        // Returns true if the button state was released at the last call to read().
        // Does not cause the button to be read.
        bool isReleased();

        // Returns true if the button state at the last call to read() was pressed,
        // and this was a change since the previous read.
        bool wasPressed();

        // Returns true if the button state at the last call to read() was released,
        // and this was a change since the previous read.
        bool wasReleased();

        // Returns true if the button state at the last call to read() was pressed,
        // and has been in that state for at least the given number of milliseconds.
        bool pressedFor(uint32_t ms);

        // Returns true if the button state at the last call to read() was released,
        // and has been in that state for at least the given number of milliseconds.
        bool releasedFor(uint32_t ms);

        // Returns the time in milliseconds (from millis) that the button last
        // changed state.
        uint32_t lastChange();

Have you run the DHTtester sketch as I suggested? My best guess is this problem is code related rather than a hardware problem.

THis is perhaps a trivial suggestion, but if you wrote functions for "motor on" "motor off"
"heater on", "heater off"
it would help to make your code self-commenting
and also make testing easier as you can simply comment out
the digital writes that perform those actions in the function.

That would eliminate the possibility that electrical issues in controlng the motor or heater are causing the problem.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.