Friday, 12 December 2014

Arduino Dehumidifier Controller Failure, and Upgrade!

The dehumidifier controller has been performing faultlessly throughout the summer months. And I've done the geeky thing and plotted the data out on a month by month basis. Humidity has been relatively steady...

Every month has seen the odd un-explainable spike, but other than that it's all been good.

Now the weather has gone colder, I'm a bit concerned about the state of things up there in the attic, but have been keeping an eye on it, and it's been dry, until last week, when there was signs of condensation. I started to contemplate moving the switch point in the sketch to bring the dehumidifier on a little earlier, especially as the actual roof will be cooler than the surrounding air. And also maybe a loop which runs the dehumidifier for an hour every now-and-again, just to make sure it's still working OK (it didn't run for months during the summer).

Also, one months data is 3GB ! Which takes Open Office Calc a little while to plot (like hours), so I thought about slowing the transmission rate down again. Anyway, most of this was a little way down the list of things to do... until Monday, when the kitchen display shows the following....

Now, it's a few degrees above freezing outside, and there's no way it's a balmy 60 in my attic, unless it's on fire.

I go into the attic and reset the box. Nope, same lies there.

I bring the box downstairs and do a few checks. 5v is nice and steady. I re-load the sketch and libraries. No, still the same. I load a simple test sketch provided with the library, and the same lies are repeated via the serial monitor.

So, it's most likely the DHT11 itself has a screw-loose, and has fond memories for hot summer's days!

I think this is a good opportunity to re-engineer the sketch slightly, and have a play with oh-so-very nice DHT22.

Now the DHT22 (A.K.A. RHT03 or  AM2302) has almost the same form factor as the DHT11, is catered for by our library, has the same pinouts, and has better accuracy and does a wider range of temperature (goes negative too) and humidity. It's a little bit more expensive.

I also decide to decrease the transmission rate to one every 198 seconds, and to bring the dehumidifier on when the dew point is within 10 degrees of the temperature. Also, regardless of temperature or humidity, the dehumidifer is run once every 259,200 seconds (or 3 days) just to keep the dehumidifier running and humidity low.

 Sensible figures now...

... and negative if it gets cold up there!

Here's the sketch:

// Wireless dehumidifier Controller
// Copyright Andy Doswell 24th May 2014 modified Dec 2014
// PURPOSE: DHT22 sensor with LCD Display and output for controlling dehumidifier.
// Data send via virtualwire and 433MHZ link to remote display
// Dehumidifier is controlled by a relay attached to pin 7, defined in rlyPin.
// DHT22 sensor is connected to 8, as defined in #define
// LCD is a Hitachi HD44780 or compatible, attached thus:
// LCD RS pin to digital pin 12
// LCD Enable pin to digital pin 11
// LCD D4 pin to digital pin 5
// LCD D5 pin to digital pin 4
// LCD D6 pin to digital pin 3
// LCD D7 pin to digital pin 2
// RW to GND
// V0 Held high (this may or may not work with your LCD, usual practice is to connect this to a 10K pot between +5 and GND)
// TX connected to pin 10
// Modified to transmit every 198 seconds, and to switch dehumidifier on when Dewpoint is within 10 Degrees of actual temperature
// Also brings dehumidifer on every 3 days regardless of temperature or humidity.
// You'll need the wonderful dht library by Rob Tillaart from here : 
// and the equally wonderful Virtualwire library from here :

// reference:
double dewPointFast(double celsius, double humidity)
 double a = 17.271;
 double b = 237.7;
 double temp = (a * celsius) / (b + celsius) + log(humidity*0.01);
 double Td = (b * temp) / (a - temp);
 return Td;

#include <VirtualWire.h>
#include <VirtualWire_Config.h>

#include <dht.h>

dht DHT;

#define DHT22_PIN 8

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// define constants & global variables
const int rlyPin = 7; //defines pin the relay is connected to. relay is active low
const int TimerLength = 1800;// number of seconds in an hour / 2 - this sets the minimum time the dehumidifier will remain on for.
int Timer = 0; //timer is off to start
boolean DewFlag = false; // This is the dew flag. Off as default.
boolean OutputStatus = false; //Output status is off as default
int chk;
int Temp;
int Dew;
int Humidity;
int DewTrip;
float Timer2 = 0;

// Data structure set up for Transmission

struct TXData
  int TX_ID;
  int Temp;
  int Humidity;
  int Dew;
  boolean Output;

void setup()
  lcd.begin(16, 2); // defines the LCD as a 16 x 2
  pinMode (rlyPin, OUTPUT); // sets our relay pin
  digitalWrite (rlyPin, HIGH); // sets the relay off for default condition.
  // Virtualwire setup
  vw_set_tx_pin(10); // TX pin set to 10
  vw_set_rx_pin(9); // RX pin set to a spare pin, even though we don't use it. If left as default it interferes with LCD operation.
  vw_setup(300); //sets virtualwire for a tx rate of 300 bits per second


void loop()
  for(int i = 0; i < 100 ; i++) { //transmit only every 99 loops (198 seconds)
    chk = DHT.read22(DHT22_PIN); // these 4 lines get data from the sensor
    Dew = dewPointFast(DHT.temperature, DHT.humidity);
    Temp = (DHT.temperature);
    Humidity = (DHT.humidity);
    DewTrip= Dew + 10; // Brings the dehumidifier on 5 deg C before the dew point. 
    // writes information about the system to the LCD
    lcd.clear ();
    lcd.setCursor(0, 1);
    lcd.setCursor(6, 1);
  // Dew detect loop. If the dewTrip point is reached, start the timer running and set the Dew flag
    if ( Temp <= DewTrip || Timer2 == 129600 ) {
      DewFlag = true;
      Timer = 1;    
      Timer2 = 0;   
    else {
      DewFlag = false;

    if (Timer >= TimerLength and DewFlag == false) { // If the timer has expired and there's no dew, switch the dehumidifier off.
      Timer = 0;
      digitalWrite (rlyPin, HIGH);

    if (Timer !=0) {                // If the timer is running, switch the dehumidifier on , and write On to the lcd.
      digitalWrite (rlyPin, LOW);
      lcd.setCursor (13,0);
      lcd.print (" On");
      OutputStatus = true;
    else {
      lcd.setCursor (13,0);
      lcd.print ("off");
      OutputStatus = false;
 delay (2000);
 Timer2 ++;

struct TXData payload; //Loads the Data struct with the payload data
lcd.clear ();
lcd.print ("Transmitting");
payload.Temp = Temp;
payload.Humidity = Humidity;
payload.Dew = Dew;
payload.Output = OutputStatus;
vw_send((uint8_t *)&payload, sizeof(payload)); //Transmits the struct
vw_wait_tx(); //waits for the TX to complete



  1. Hello, is it possible to get the schematics of this system?

    1. There's a simplified schematic here :

      This (full) version is identical, except it has the transmitter connected to pin 10 of the arduino, and no switch. You may need to decouple the power to the transmitter module at it's power pins with a 0.01uF cap. The receiver module should be self explanatory from the code.