DHT22 instability when using a Relay module

Hi everyone,
first post here.

I'm currently working on a DIY project: a fermentation box with automatic temperature control.

The temperature is monitored via a DHT22 sensor, and based on specific temperature ranges, I control a 5V KY-019 relay module (high-level triggered) which turns a heating cable on or off accordingly.
Additionally, I display the measured values on an I2C LCD display.

Here’s some photos of the current setup:


At first, I was using a DHT11, and while not very accurate, it worked without major issues.

Then I decided to upgrade to a DHT22, and that’s when the problems began.

Almost every time the relay switched on or off, the DHT22 started returning NaN readings, and the program would freeze, making it impossible to continue monitoring without manually resetting the whole system (power off/on).

So I searched online and found that the DHT22 is quite sensitive to voltage fluctuations, often caused by the relay switching.
(Note: the DHT22 works fine as long as the relay is disconnected from the circuit.)


I’ve tried several solutions so far:

  • First, I added 100 nF ceramic capacitors, which I read can help filter high-frequency voltage spikes.
  • When that didn’t solve it, I added 470 µF electrolytic capacitors to smooth out low-frequency fluctuations — but again, no improvement.
  • Finally, I tried powering the relay module separately using an MB102 power supply board, with GNDs connected in common (as shown in the photos).
    I kept the capacitors in the circuit.

Still, the issue persists: when the relay switches, the DHT22 often fails and stops updating, freezing the program until a manual reset.


At this point, I don’t know if it’s a wiring issue, a faulty DHT22, or if the solutions I’ve tried are ineffective.

So I’m turning to you:
What else can I do?
Any advice or recommendations would be greatly appreciated.

Here's the code:


```cpp
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define DHTPIN 2
#define DHTTYPE DHT22
#define RELAY_PIN 6

DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);

bool cicloAvviato = false;
bool relayStato = false;
unsigned long previousMillis = 0;
unsigned long intervallo;  // intervallo variabile

void setup() {
  Serial.begin(9600);
  dht.begin();
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);
  lcd.init();
  lcd.backlight();
}

void loop() {
  unsigned long currentMillis = millis();
  float temp = dht.readTemperature();
  float hum = dht.readHumidity();

  // --- CONTROLLO VALORI NON VALIDI O FUORI RANGE ---
  if (isnan(temp) || isnan(hum)) {
    Serial.println("❌ Errore lettura dal sensore DHT22: NaN");
    lcd.setCursor(0, 0);
    lcd.print("Temp: ERR       ");
    lcd.setCursor(0, 1);
    lcd.print("Hum: ERR        ");
    digitalWrite(RELAY_PIN, LOW);
    delay(2000);
    return;
  }

  if (temp < -10 || temp > 60 || hum < 0 || hum > 100) {
    Serial.println("⚠️ Valori fuori range sensato!");
    Serial.print("Temp: ");
    Serial.print(temp);
    Serial.print("C  Hum: ");
    Serial.print(hum);
    Serial.println("%");
    digitalWrite(RELAY_PIN, LOW);
    lcd.setCursor(0, 0);
    lcd.print("Temp: OUT       ");
    lcd.setCursor(0, 1);
    lcd.print("Hum: OUT        ");
    delay(2000);
    return;
  }

  // --- GESTIONE INTERVALLI IN BASE ALLA TEMPERATURA ---
  intervallo = (temp >= 32.0) ? 120000 : 60000;

  // --- GESTIONE CONDIZIONI DI BLOCCO ALTA TEMPERATURA ---
  if (temp >= 34.0) {
    digitalWrite(RELAY_PIN, LOW);
    cicloAvviato = false;
    Serial.println("🔥 Superati 34°C - Relay SPENTO per sicurezza!");
  }

  else if (temp >= 33.0 && cicloAvviato == false) {
    Serial.println("⏳ Attesa - Temp >33°C ma sotto soglia di blocco");
    digitalWrite(RELAY_PIN, LOW);
  }

  // --- GESTIONE ACCENSIONE CICLO ---
  else if (temp >= 31.0) {
    if (!cicloAvviato) {
      Serial.println("🌡️ Raggiunti i 31°C - Inizio ciclo on/off");
    }
    cicloAvviato = true;
  } else {
    if (cicloAvviato) {
      Serial.println("🌡️ Temp scesa sotto 31°C - Fine ciclo");
    }
    cicloAvviato = false;
    digitalWrite(RELAY_PIN, HIGH);
  }

  // --- GESTIONE CICLO ON/OFF ---
  if (cicloAvviato && currentMillis - previousMillis >= intervallo) {
    previousMillis = currentMillis;
    relayStato = !relayStato;
    digitalWrite(RELAY_PIN, relayStato ? HIGH : LOW);
    Serial.print("🔁 Ciclo: ");
    Serial.println(relayStato ? "ACCESO" : "SPENTO");
  }

  // --- LCD ---
  lcd.setCursor(0, 0);
  lcd.print("Temp: ");
  lcd.print(temp);
  lcd.print("C   ");
  lcd.setCursor(0, 1);
  lcd.print("Hum: ");
  lcd.print(hum);
  lcd.print("%   ");

  // --- MONITOR SERIAL ---
  Serial.print("Temp: ");
  Serial.print(temp);
  Serial.print("C  Humidity: ");
  Serial.print(hum);
  Serial.print("%  Relay: ");
  Serial.println(digitalRead(RELAY_PIN) ? "ON" : "OFF");

  delay(1000);
}

  • Disconnect Arduino UNO from breadboard power supply when Arduino UNO is connected to PC thru USB.

  • In the Arduino IDE, use Ctrl T or CMD T to format your code then copy the complete sketch.
    Use the < CODE / > icon from the ‘posting menu’ to attach the copied sketch.

How are you ensuring air circulation to keep the temperature and humidity from stratifying?

Done what you suggested, I turned on Arduino with a power supply at 6:33 pm and I got NaN measures at 6:42 pm.
You can see the code now in my post.

Actually, I'm not actively working on that, because I'm pretty stuck on this issue, since I can't control it if I can't measure it accurately.
Still I have some ideas, like using silica gel for absorbing humidity with the aid of a 5V PC fan, given the fact that most fermentation processes produce humidity.

And as for air circulation, I have not figured out an automated solution yet, for now I'm opening the box manually to remove the excess humidity and so the air changes.

What voltage are you feeding to the power supply input?

I'm using a 9V - 1,5 A power supply

You have not told us how you are calibrating the sensors. What are you using for a standard?

  • Try adding a 10k pull-up resistor to 5V on the DHT22 Data pin.
void loop()
{
. . .

delay(1000); // <———-<<<< Try 2000
}