Last Modified: | June 25, 2017, at 08:35 AM |
By: | Seth |
Platforms: | UNO, Leonardo, Nano |
Looking for a cheap DHT11-like sensor with better resolution and range I came across the DHT12 sensor which is a cheap ebay buy (1$/1€). It features 0.1 resolution in temperature and humidity readings and its data format is compatible to the other DHTxx sensors.
The DHT12 looks pin-compatible, however it is not! Data is exchanged via i2c instead of 1-wire. It took me quite some time to figure that out as information on the internet is scarce... All searches lead me to DHT11 resources and I wrongfully assumed also having 4 pins means pin-compatibility. Kudos to this guy https://github.com/Bobadas/DHT12_library_Arduino who managed to provide a data-sheet (in Chinese) as well as some descriptions including a pin description of the DHT12 and a wiring diagram.
From the Chinese data-sheet:
I have no clear idea what the latter two mean...
Again, I have no clear idea what the latter means... I would assume the sensor does internally some kind of integration or moving average and these time would be the times until changes in sensed data is reflected to the readout.
Make sure you orient the sensor correctly to get the PINOUT correct NEVER wire it as a DHT11 they are NOT compatible (Different PINOUTS, Different Protocols) The pins on the DH13 and others sensors in this range are not symmetrical. So single wire dupont connector will give a really BAD connection. Pop the pins of your 4 single wire female connector and pop them in order into a 4 PIN Dupont Connector. A small dab of hot glue on the top of the 4 wide female dupont connector applied once the sensor wires are almost in will help with a stable physical connection.
These units are cheap, and not calibrated. If you have 10 most will be off by a few degrees. A simple way to address this is to calibrate the temp offset / humidity offset needed to bring the sensors closer to a known good value. Write the offset needed to correct each sensor on the unit eg. +2.1 C -3% HR etc for some application these units are fine. The DHT22 is better but costs a lot more!
Standing on the shoulder of giants... I kludged together my library from DHTLib and DHT11Lib and extended it for the DHT12 sensor. You should definitely check out these two pages, it is a good read around using the DHT sensors. My library basically uses this great pieces of work but is blended with my personal OO preferences :)
Since DHT11 sensors provide a integer resolution and the other DHTxx sensors provide 0.1 resolution, I decided (avoiding floating point arithmetic) to return all values (temperature and humidity) in x10 scaled format. So reading a 21.2°C temperature my library would yield 210 on a DHT11 or 212 on a better, say DHT12 sensor.
The library provides two classes:
dht1wire(uint8_t _pin, dhtmodels _model);
dht1wire sensor(11, dth::DHT11);
dht12(uint8_t _id = 0x5c);
dht12 sensor(0x5c);
(0x5c is the default i2c bus address of the DHT12 sensor)Both classes derive from a common base class dht, which does all the common stuff like data conversion and provides the enums for model names (e.g. dht::DHT11
) and return values of the read()
function. I also kludged in the sloppy and quick dew point temperature function (using floats - there is no reasonable way avoiding this).
dht1wire and dht12 implement the specific _readSensor()
and _storeData()
function that actually does the communication with the sensor.
A very minimal sketch that reads out a DHT12 sensor every 5 seconds might look like this:
/*
* Example for a DHT12 sensor
* Beware some of the diagrams about the pinouts are incorrect.
* Pin Definition 1.VDD 2.SDA 3.GND 4.SCL
* Look at the sensor one side has holes to allow air inside. Lets call the surface with holes the FRONT
* The BACK of the sensor has printed codes and no holes
* The 4 PINS for connection come out of the BOTTOM of the sensor
* OK so we have defined the orientation of the sensor.
* Looking at the FRONT of the Sensor with the legs pointing down the LEFTMOST PIN is PIN ONE
*
*
* -----------------
* ! O O O O O !
* ! O O O O O !
* ! O O O O O !
* ! O O O O O !
* -----------------
* ! ! ! !
* ! ! ! !
* ! ! ! !
* ! ! ! !
* 1 2 3 4
*
*/
#include <Wire.h>
#include <dht.h>
dht12 DHT(0x5c);
void setup()
{
Serial.begin(9600);
Serial.println(F("DHT12 TEST PROGRAM"));
}
void loop()
{
unsigned long b = micros();
dht::ReadStatus chk = DHT.read();
unsigned long e = micros();
Serial.print(F("Read sensor: "));
switch (chk)
{
case dht::OK:
Serial.print(F("OK, took "));
Serial.print (e - b); Serial.print(F(" usec, "));
break;
case dht::ERROR_CHECKSUM:
Serial.println(F("Checksum error"));
break;
case dht::ERROR_TIMEOUT:
Serial.println(F("Timeout error"));
break;
case dht::ERROR_CONNECT:
Serial.println(F("Connect error"));
break;
case dht::ERROR_ACK_L:
Serial.println(F("AckL error"));
break;
case dht::ERROR_ACK_H:
Serial.println(F("AckH error"));
break;
default:
Serial.println(F("Unknown error"));
break;
}
Serial.print(F("Humidity: "));
Serial.print((float)DHT.getHumidity()/(float)10);
Serial.print(F("%, "));
Serial.print(F(". Temperature (degrees C): "));
Serial.print((float)DHT.getTemperature()/(float)10);
Serial.print(F(", Dew Point (degrees C): "));
Serial.println(DHT.dewPoint());
delay(4000);
}
//
// END OF FILE
//