Following on from my previous post on measuring humidity, I decided to test another couple of humidity sensors I had lying around. These were the DHT11 and the DYPTH01B. These are both low-cost capacitive sensors and both had been obtained when I put in an order with a Chinese supply website (Sun Tek Store).

Neither of these devices came with any support or information.

Sensor 1: DHT11

This is a low-cost sensor which has a capacitive humidity sensor and the thermistor within the same case.
I am using the DHT11, which is ultra-low cost, but not very accurate (while the DHT22 is slightly higher cost and has slightly better specifications).
There is a basic analog-to-digital converter within the unit and hence the output is digital.
They are very slow and the maximum sample rate is once per second.

alt

alt

Adafruit has (as always) a great intro on using these devices here. I used the DHT11 Arduino code from LadyAda website (downloaded about a year ago), from here: http://learn.adafruit.com/dht/downloads.

There are a number of other Arduino libraries for these sensors including here and here.

As there is not much info on the sensor itself the pin-out is vital:
From left to right, looking at the sensor from the face with holes in it:
1 : VCC (5V)
2 : SIGnal
3 : NC Not connected
4 : GND
I wired the signal pin to D2 on the Arduino and powered up with 5V (voltage supply range is 3-5.5V, so good for both 3.3V and 5V). I uploaded the following code:

// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain

#include "DHT.h"

#define DHTPIN 2     // what pin we're connected to

// Uncomment whatever type you're using!
#define DHTTYPE DHT11   // DHT 11 
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600); 
  Serial.println("DHTxx test!");
 
  dht.begin();
}

void loop() {
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT");
  } else {
    Serial.print("Humidity: "); 
    Serial.print(h);
    Serial.print(" %t");
    Serial.print("Temperature: "); 
    Serial.print(t);
    Serial.println(" *C");
  }
}

And it started to output data onto the serial interface:alt

One issue with this is the delay in readings (it took around 2 seconds before a change in humidity was detected).
It also took a very long time for the humidity values to fall, although this might be how long it takes for humidity to drop.

Also the precision of the data was only within 1 degree or 1% humidity and the accuracy of the data was within 2% for temperature and 5% for humidity. But good enough for basic comparison data.

Sensor 2: DYPTH01B

I also had a low-cost DYPTH01B-SPI temperature and humidity sensor module. Some details on this sensor are available here. When searching there were far fewer projects using this sensor.

alt

Annoyingly this had output pins which were 2mm pitch, so did not fit into my 2.54mm (0.1″) pitch standard breadboard. So I created a converter from some 0.1″ header pins which were bent to fit the 2mm pitch holes. This meant I could plug it into a prototyping board.

alt

There are far fewer examples and libraries for this device, but I did find this weather station design.

This was wired to the SPI lines on the Arduino:

10      SS   ->  Chip Select
11      MOSI -> No Connection
12      MISO -> Serial Data
13      CLK  ->  Serial Clock

5V      ->  VDD
GND    -> VSS
No Connection      ->  Reset

I could not get this sending data when I wired it up to the Arduino. There was a solder bridge over one of the capacitors (which was missing). When I looked at another unit I had – it had a 0 ohm resistor in that position, so it is meant to be connected…

This device used a CRC (cyclic redundancy check) to double check that the data received is correct. After quite a lot of head-scratching, I used this (slightly modified) code from Nick Gammon. There were a number of changes to make on the wiring. I finally used these connections to get data from the device:

GND -> Chip Select
11      MOSI -> Serial Data
12      MISO -> No Connection
13      CLK  ->  Serial Clock

5V      ->  VDD
GND    -> VSS
No Connection      ->  Reset

The changes were:

Set the Chip Select line low. This tells the sensor to constantly put out data.

The data from the sensor goes to the MOSI line to be read by the Arduino SPI interrupt.

// Written by Nick Gammon
// February 2011
// see http://mushclient.com/spi

// Rework for DYPTH01B_SPI Temperature and Humidity sensor
// using MTH01 Sensor
// D. Richards, Jan 2012
// see http://www.suntekstore.co.uk/product-14001923-DYPTH01B-SPI+Temperature++Humidity+Sensor+Module.html

// CS -> LOW
// 11 MOSI / SDAT
// 12 MISO
// 13 CLK  / SCK

// 5V      / VDD
// GND     / VSS
// nc      / Reset

//#include "pins_arduino.h"

unsigned char buf [10];
volatile byte pos;
volatile boolean process_it;
int MTH_temperature;
int MTH_humidity;
#define HCS 10
#define HRT 7


/*
  The following procedure calculates the CRC-8. The result accumulates in the variable CRC.
  Var CRC : Byte;
  Procedure calc_CRC(X: Byte);

  Begin
  CRC := CRC_Table[X xor CRC];
  End;

 Polynomial is x^8 + x^5 + x^4
*/
 
const unsigned char CRC8table[256] PROGMEM = {

  0, 49, 98, 83, 196, 245, 166, 151, 185, 136, 219, 234, 125, 76, 31, 46,
  67, 114, 33, 16, 135, 182, 229, 212, 250, 203, 152, 169, 62, 15, 92, 109,
  134, 183, 228, 213, 66, 115, 32, 17, 63, 14, 93, 108, 251, 202, 153, 168,
  197, 244, 167, 150, 1, 48, 99, 82, 124, 77, 30, 47, 184, 137, 218, 235,
  61, 12, 95, 110, 249, 200, 155, 170, 132, 181, 230, 215, 64, 113, 34, 19,
  126, 79, 28, 45, 186, 139, 216, 233, 199, 246, 165, 148, 3, 50, 97, 80,
  187, 138, 217, 232, 127, 78, 29, 44, 2, 51, 96, 81, 198, 247, 164, 149,
  248, 201, 154, 171, 60, 13, 94, 111, 65, 112, 35, 18, 133, 180, 231, 214,
  122, 75, 24, 41, 190, 143, 220, 237, 195, 242, 161, 144, 7, 54, 101, 84,
  57, 8, 91, 106, 253, 204, 159, 174, 128, 177, 226, 211, 68, 117, 38, 23,
  252, 205, 158, 175, 56, 9, 90, 107, 69, 116, 39, 22, 129, 176, 227, 210,
  191, 142, 221, 236, 123, 74, 25, 40, 6, 55, 100, 85, 194, 243, 160, 145,
  71, 118, 37, 20, 131, 178, 225, 208, 254, 207, 156, 173, 58, 11, 88, 105,
  4, 53, 102, 87, 192, 241, 162, 147, 189, 140, 223, 238, 121, 72, 27, 42,
  193, 240, 163, 146, 5, 52, 103, 86, 120, 73, 26, 43, 188, 141, 222, 239,
  130, 179, 224, 209, 70, 119, 36, 21, 59, 10, 89, 104, 255, 206, 157, 172,
};

void setup (void)
{
  Serial.begin (115200);   // debugging
  Serial.println ("initialising");

  pinMode(HCS, OUTPUT);        // CS output
  digitalWrite(HCS, HIGH);     // CS inactive
  pinMode(HRT, OUTPUT);        // RST output
  digitalWrite(HRT, HIGH);     // RST inactive
 
  // turn on SPI in slave mode
  SPCR |= _BV(SPE);
 
  // get ready for an interrupt
  pos = 0;   // buffer empty
  process_it = false;

  // now turn on interrupts
  SPCR |= _BV(SPIE);
  
  digitalWrite(HCS, LOW);      // CS active, starts conversion
  

}  // end of setup


// SPI interrupt routine
ISR (SPI_STC_vect)
{
  byte c = SPDR;  // grab byte from SPI Data Register
  
  // add to buffer if room
  if (pos < sizeof buf)
  {
    buf [pos++] = c;
   
    if(pos >= 4) // when all 4 bytes received
    {
      digitalWrite(HCS, HIGH);  // disable further conversions
      process_it = true;      // signal ready to main loop
    }     
  }  // end of room available
 
}  // end of interrupt routine SPI_STC_vect

// main loop - wait for flag set in interrupt routine
void loop (void)
{
  byte idx;
  byte crc;
  byte byt;
  int i;
  
  if (process_it)
  {  
    crc = 0;
    for (i=0; i<4; i++)
    {
      byt = buf[i];
      idx  =  byt ^ crc;
//      idx  =  buf[i] ^ crc;
      crc = CRC8table[idx];
//      crc = CRC8table[buf[i] ^ crc];
     
      Serial.print(" n");
      Serial.print(i, HEX);
      Serial.print(" b");
      Serial.print(byt, HEX);
      Serial.print(" c");
      Serial.print(crc, HEX);
      Serial.print(" i");
      Serial.print(idx, HEX);           
      Serial.print(", ");
    }

    if(crc == 0)
    {
      MTH_temperature = ( (256*buf[0]) + buf[1] ) - 400;
      MTH_humidity = buf[2];
     
      Serial.print(" T=");
      Serial.print( MTH_temperature / 10);
      Serial.print(".");
      Serial.print( MTH_temperature % 10);

      Serial.print("C, H=");
      Serial.print(MTH_humidity);
      Serial.print("%");
    }
    else
    {
      // reset chip here     
      digitalWrite(HRT, LOW);     // RST active
      delay(2);
      digitalWrite(HRT, HIGH);     // RST inactive
      Serial.print("Reset");
      delay(100);
    }
    Serial.println();
     
    delay(500);
    pos = 0;                // reset buffer index
    process_it = false;     // preset buffer not ready
    digitalWrite(HCS, LOW);    // start conversion   
   
  }  // end of flag set
   
}  // end of loop

I used the above code and wiring, but still did not have too much luck with this sensor. I think I need to play a bit more with it. The data output was not often recognised. This is probably due to the fact the CS line it kept low, so data is coming out all the time and we are not receiving all of it. Hence it mainly throws up an error (“Reset” is written to the output, as shown below). You can also see the correct values highlighted below when it did work.

alt

I think with more effort on the code I could get this working,but that is for a day when I have more time.

If anyone has a good routine to get this running then please post a link in the comments, thanks.

2 responses to “Humidity sensors part II

Leave a Reply

Your email address will not be published. Required fields are marked *