DHT12 (i2c Cheap Humidity and Temperature Sensor), Fast Easy Usage

Introduction: DHT12 (i2c Cheap Humidity and Temperature Sensor), Fast Easy Usage

About: Software developer but I love electronics, wood, nature, and everything else as well.

You can find update and other on my site https://www.mischianti.org/2019/01/01/dht12-library-en/ .

I like sensor that can be used with 2 wire (i2c protocol), but I love the inexpensive one.

This is an Arduino and esp8266 library for the DHT12 series of very low cost temperature/humidity sensors (less than 1$) that work with i2c or one wire connection.

Very usefully if you want use esp01 (if you use serial you have only 2 pin) to read humidity and temperature and display it on i2c LCD.

AI read that sometime seems that need calibration, but I have tree of this and get value very similar to DHT22. If you have calibration this problem, open issue on github and I add implementation.

Step 1: How I2c Works

I2C works with it's two wires, the SDA(data line) and SCL(clock line).

Both these lines are open-drain, but are pulled-up with resistors.

Usually there is one master and one or multiple slaves on the line, although there can be multiple masters, but we'll talk about that later.

Both masters and slaves can transmit or receive data, therefore, a device can be in one of these four states: master transmit, master receive, slave transmit, slave receive.

Step 2: Library

You can find my library here.

To download.

Click the DOWNLOADS button in the top right corner, rename the uncompressed folder DHT12.

Check that the DHT folder contains DHT12.cpp and DHT12.h.

Place the DHT library folder your /libraries/ folder.

You may need to create the libraries subfolder if its your first library.

Restart the IDE.

Step 3: Behaivor

This libray try to emulate the behaivor of standard DHT library sensors (and copy a lot of code), and I add the code to manage i2c olso in the same manner.

The method is the same of DHT library sensor, with some adding like dew point function.

Step 4: I2c Usage

To use with i2c (default address and default SDA SCL pin) the constructor is:

DHT12 dht12; 

and take the default value for SDA SCL pin.

(It's possible to redefine with specified contructor for esp8266, needed for ESP-01). or

DHT12 dht12(uint8_t addressOrPin) 
addressOrPin -> address 

to change address.

Step 5: One Wire Usage

To use one wire:

DHT12 dht12(uint8_t addressOrPin, true) 
addressOrPin -> pin 

boolean value is the selection of oneWire or i2c mode.

Step 6: Implicit Read

You can use It with "implicit", "simple read" or "fullread": Implicit, only the first read doing a true read of the sensor, the other read that become in 2secs. interval are the stored value of first read.

// The read of sensor have 2secs of elapsed time, unless you pass force parameter
		// Read temperature as Celsius (the default)
		float t12 = dht12.readTemperature();
		// Read temperature as Fahrenheit (isFahrenheit = true)
		float f12 = dht12.readTemperature(true);
		// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
		float h12 = dht12.readHumidity();
		
		
		// Compute heat index in Fahrenheit (the default)
		float hif12 = dht12.computeHeatIndex(f12, h12);
		// Compute heat index in Celsius (isFahreheit = false)
		float hic12 = dht12.computeHeatIndex(t12, h12, false);
		// Compute dew point in Fahrenheit (the default)
		float dpf12 = dht12.dewPoint(f12, h12);
		// Compute dew point in Celsius (isFahreheit = false)
		float dpc12 = dht12.dewPoint(t12, h12, false);

Step 7: Simple Read

Simple read to get a status of read.

		// The read of sensor have 2secs of elapsed time, unless you pass force parameter
		bool chk = dht12.read(); // true read is ok, false read problem
		// Read temperature as Celsius (the default)
		float t12 = dht12.readTemperature();
		// Read temperature as Fahrenheit (isFahrenheit = true)
		float f12 = dht12.readTemperature(true);
		// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
		float h12 = dht12.readHumidity();
		
		// Compute heat index in Fahrenheit (the default)
		float hif12 = dht12.computeHeatIndex(f12, h12);
		// Compute heat index in Celsius (isFahreheit = false)
		float hic12 = dht12.computeHeatIndex(t12, h12, false);
		// Compute dew point in Fahrenheit (the default)
		float dpf12 = dht12.dewPoint(f12, h12);
		// Compute dew point in Celsius (isFahreheit = false)
		float dpc12 = dht12.dewPoint(t12, h12, false);

Step 8: Full Read

Full read to get a specified status.

		// The read of sensor have 2secs of elapsed time, unless you pass force parameter
		DHT12::ReadStatus chk = dht12.readStatus();
		Serial.print(F("\nRead sensor: "));
		switch (chk) {
		case DHT12::OK:
			Serial.println(F("OK"));
			break;
		case DHT12::ERROR_CHECKSUM:
			Serial.println(F("Checksum error"));
			break;
		case DHT12::ERROR_TIMEOUT:
			Serial.println(F("Timeout error"));
			break;
		case DHT12::ERROR_TIMEOUT_LOW:
			Serial.println(F("Timeout error on low signal, try put high pullup resistance"));
			break;
		case DHT12::ERROR_TIMEOUT_HIGH:
			Serial.println(F("Timeout error on low signal, try put low pullup resistance"));
			break;
		case DHT12::ERROR_CONNECT:
			Serial.println(F("Connect error"));
			break;
		case DHT12::ERROR_ACK_L:
			Serial.println(F("AckL error"));
			break;
		case DHT12::ERROR_ACK_H:
			Serial.println(F("AckH error"));
			break;
		case DHT12::ERROR_UNKNOWN:
			Serial.println(F("Unknown error DETECTED"));
			break;
		case DHT12::NONE:
			Serial.println(F("No result"));
			break;
		default:
			Serial.println(F("Unknown error"));
			break;
		}
		// Read temperature as Celsius (the default)
		float t12 = dht12.readTemperature();
		// Read temperature as Fahrenheit (isFahrenheit = true)
		float f12 = dht12.readTemperature(true);
		// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
		float h12 = dht12.readHumidity();
		
		// Compute heat index in Fahrenheit (the default)
		float hif12 = dht12.computeHeatIndex(f12, h12);
		// Compute heat index in Celsius (isFahreheit = false)
		float hic12 = dht12.computeHeatIndex(t12, h12, false);
		// Compute dew point in Fahrenheit (the default)
		float dpf12 = dht12.dewPoint(f12, h12);
		// Compute dew point in Celsius (isFahreheit = false)
		float dpc12 = dht12.dewPoint(t12, h12, false);

Step 9: Connection Diagram

With examples, there are the connection diagram, it's important to use correct pullup resistor.

Thanks to Bobadas, dplasa and adafruit, to share the code in github (where I take some code and ideas).

Step 10: Arduino: OneWire

Step 11: Arduino: I2c

Step 12: Esp8266 (D1Mini) OneWire

Step 13: Esp8266 (D1Mini) I2c

Step 14: Thanks

Arduino playground (https://playground.arduino.cc/Main/DHT12SensorLibrary)

i2c project series (Collection):

Be the First to Share

    Recommendations

    • The 1000th Contest

      The 1000th Contest
    • Battery Powered Contest

      Battery Powered Contest
    • Hand Tools Only Challenge

      Hand Tools Only Challenge

    7 Discussions

    0
    dziobas83
    dziobas83

    Tip 8 months ago

    thanks a loot!! i use DHT12 Esp8266 (D1Mini) OneWire conections & blynk :
    //
    //in blynk app use label value V0 and V1 for read data
    #define BLYNK_PRINT Serial
    #include <ESP8266WiFi.h>
    #include <BlynkSimpleEsp8266.h>
    #include <DHT12.h>
    #include <Wire.h> //The DHT12 uses I2C comunication.
    DHT12 dht12(D4, true);
    // You should get Auth Token in the Blynk App.
    // Go to the Project Settings (nut icon).
    char auth[] = "***********";
    // Your WiFi credentials.
    // Set password to "" for open networks.
    char ssid[] = "*********";
    char pass[] = "********";
    BlynkTimer timer;
    void myTimerEvent() {
    // You can send any value at any time.
    // Please don't send more that 10 values per second.
    Blynk.virtualWrite(V9, millis() / 1000);
    float tmp = dht12.readTemperature();
    float hum = dht12.readHumidity();
    Serial.printf("Temperatura: %2.2f*C Wilgotnosc: %0.2f%%\r\n", tmp, hum);
    Blynk.virtualWrite(V0, tmp);
    Blynk.virtualWrite(V1, hum);
    }
    void setup()
    {
    // Debug console
    Serial.begin(9600);
    dht12.begin();
    Blynk.begin(auth, ssid, pass);
    timer.setInterval(2000L, myTimerEvent);
    }
    void loop()
    {
    Blynk.run();
    timer.run(); // Initiates BlynkTimer
    }

    F17DE5PJB2S55UU.LARGE.jpgIMG_20200207_102822.jpgScreenshot_2020-02-07-10-26-42-497_cc.blynk.jpg
    0
    xxreef
    xxreef

    Reply 8 months ago

    Good work..
    Thanks to write Renzo

    0
    pchatill
    pchatill

    Question 1 year ago on Step 5

    Hi!
    Thanks for your tutorial!
    I tried with one wire connection and it works well.
    Then I tried to put an other DHT12 in parallell with the first one. But no response from the two sensors.
    Is that possible to have many sensors on the same line like DS18B20 ?
    Do I have to modify the sketch?
    Thanks in advance!
    Patrick

    0
    xxreef
    xxreef

    Answer 1 year ago

    Hi,
    if I undestand you want use the same wire for all sensor, but no It isn't possible, with one wire you must use "one wire" per sensor.
    Bye

    0
    pchatill
    pchatill

    Reply 1 year ago

    Thanks for your quick answer.
    And with I2C protocol, Can I manage many dht12 sensors with only 2 wires (SDA and SCL). Because all dht12 have same address : 05c

    0
    marcudanf
    marcudanf

    Question 2 years ago

    Hi!

    I got a couple of those (link here) from China but I can't get them to work.

    I tried both Arduino and esp and i2c and one wire, with and without resistors.

    Can you give me some help with these??