├── .gitattributes ├── .project ├── DHT12.cpp ├── DHT12.h ├── DHT12_sensor_library.h ├── LICENSE.md ├── README.md ├── examples ├── ArduinoI2CDHT12 │ ├── ArduinoI2CDHT12.fzz │ ├── ArduinoI2CDHT12.ino │ └── ArduinoI2CDHT12.png ├── ArduinoOneWireDHT12 │ ├── ArduinoOneWireDHT12.fzz │ ├── ArduinoOneWireDHT12.ino │ └── ArduinoOneWireDHT12.png ├── advanced │ └── ArduinoUNOCheckReadStatus │ │ └── ArduinoUNOCheckReadStatus.ino ├── esp32TwoWire │ ├── esp32I2CDHT12.fzz │ ├── esp32I2CDHT12_bb.jpg │ └── esp32TwoWire.ino ├── esp8266I2CDHT12 │ ├── esp8266I2CDHT12.fzz │ ├── esp8266I2CDHT12.ino │ └── esp8266I2CDHT12.png └── esp8266OneWireDHT12 │ ├── esp8266OneWireDHT12.fzz │ ├── esp8266OneWireDHT12.ino │ └── esp8266OneWireDHT12.png ├── keywords.txt └── library.properties /.gitattributes: -------------------------------------------------------------------------------- 1 | resources export-ignore 2 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | DHT12_sensor_library 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /DHT12.cpp: -------------------------------------------------------------------------------- 1 | /** \mainpage DHT12 sensor library 2 | * DHT12 Sensor Library 3 | * https://www.mischianti.org/2019/01/01/dht12-library-en/ 4 | * 5 | * The MIT License (MIT) 6 | * 7 | * Copyright (c) 2017 Renzo Mischianti www.mischianti.org All right reserved. 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | 28 | #include "DHT12.h" 29 | #include "Wire.h" 30 | 31 | // Default is i2c on default pin with default DHT12 address 32 | DHT12::DHT12(void) { 33 | _wire = &Wire; 34 | } 35 | 36 | DHT12::DHT12(uint8_t addressOrPin, bool oneWire) { 37 | _isOneWire = oneWire; 38 | if (oneWire) { 39 | _wire = NULL; 40 | _pin = addressOrPin; 41 | #if !defined(__AVR) && !defined(__STM32F1__) && !defined(TEENSYDUINO) 42 | _bit = digitalPinToBitMask(_pin); 43 | _port = digitalPinToPort(_pin); 44 | #endif 45 | _maxcycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for 46 | // reading pulses from DHT sensor. 47 | // Note that count is now ignored as the DHT reading algorithm adjusts itself 48 | // basd on the speed of the processor. 49 | 50 | DEBUG_PRINTLN("PIN MODE"); 51 | } else { 52 | _wire = &Wire; 53 | _address = addressOrPin; 54 | DEBUG_PRINTLN("I2C MODE"); 55 | } 56 | } 57 | 58 | // Is not good idea use other pin for i2c as standard on Arduino you can get lag. 59 | // The lag happens when you choose "different pins", because you are then using a 60 | // slow software emulation of the I2C hardware. The built in I2C hardware has fixed pin assignments. 61 | #if !defined(__AVR) && !defined(__STM32F1__) && !defined(TEENSYDUINO) 62 | DHT12::DHT12(uint8_t sda, uint8_t scl) { 63 | _wire = &Wire; 64 | _isOneWire = false; 65 | _sda = sda; 66 | _scl = scl; 67 | } 68 | 69 | DHT12::DHT12(uint8_t sda, uint8_t scl, uint8_t address) { 70 | _wire = &Wire; 71 | _isOneWire = false; 72 | _sda = sda; 73 | _scl = scl; 74 | _address = address; 75 | } 76 | 77 | #ifdef ESP32 78 | 79 | ///// changes for second i2c bus 80 | 81 | DHT12::DHT12(TwoWire *pWire) { 82 | _wire = pWire; 83 | _isOneWire = false; 84 | } 85 | 86 | DHT12::DHT12(TwoWire *pWire, uint8_t address) { 87 | _wire = pWire; 88 | _isOneWire = false; 89 | 90 | _address = address; 91 | } 92 | DHT12::DHT12(TwoWire *pWire, uint8_t sda, uint8_t scl) { 93 | _wire = pWire; 94 | _isOneWire = false; 95 | _sda = sda; 96 | _scl = scl; 97 | } 98 | DHT12::DHT12(TwoWire *pWire, uint8_t sda, uint8_t scl, uint8_t address) { 99 | _wire = pWire; 100 | _isOneWire = false; 101 | _sda = sda; 102 | _scl = scl; 103 | _address = address; 104 | } 105 | // changes 106 | #endif 107 | #endif 108 | 109 | void DHT12::begin() { 110 | _lastreadtime = -(MIN_ELAPSED_TIME + 1); 111 | if (_isOneWire) { 112 | // set up the pins! 113 | pinMode(_pin, INPUT_PULLUP); 114 | // Using this value makes sure that millis() - lastreadtime will be 115 | // >= MIN_INTERVAL right away. Note that this assignment wraps around, 116 | // but so will the subtraction. 117 | DEBUG_PRINT("Max clock cycles: "); 118 | DEBUG_PRINTLN(_maxcycles, DEC); 119 | } else { 120 | #if !defined(__AVR) && !defined(__STM32F1__) && !defined(TEENSYDUINO) 121 | _wire->begin(_sda, _scl); 122 | #else 123 | // Default pin for AVR some problem on software emulation 124 | // #define SCL_PIN _scl 125 | // #define SDA_PIN _sda 126 | _wire->begin(); 127 | #endif 128 | DEBUG_PRINT("I2C Inizialization: sda, scl: "); 129 | DEBUG_PRINT(_sda); 130 | DEBUG_PRINT(","); 131 | DEBUG_PRINTLN(_scl); 132 | } 133 | } 134 | 135 | DHT12::ReadStatus DHT12::readStatus(bool force) { 136 | // Check if sensor was read less than two seconds ago and return early 137 | // to use last reading. 138 | uint32_t currenttime = millis(); 139 | if (!force && ((currenttime - _lastreadtime) < MIN_ELAPSED_TIME)) { 140 | return _lastresult; // return last correct measurement 141 | } 142 | _lastreadtime = currenttime; 143 | 144 | if (_isOneWire) { 145 | // Reset 40 bits of received data to zero. 146 | data[0] = data[1] = data[2] = data[3] = data[4] = 0; 147 | 148 | // Send start signal. See DHT datasheet for full signal diagram: 149 | // http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf 150 | 151 | // Go into high impedence state to let pull-up raise data line level and 152 | // start the reading process. 153 | digitalWrite(_pin, HIGH); 154 | delay(250); 155 | 156 | // First set data line low for 20 milliseconds. 157 | pinMode(_pin, OUTPUT); 158 | digitalWrite(_pin, LOW); 159 | delay(20); 160 | 161 | uint32_t cycles[80]; 162 | { 163 | // Turn off interrupts temporarily because the next sections are timing critical 164 | // and we don't want any interruptions. 165 | InterruptLockDht12 lock; 166 | 167 | // End the start signal by setting data line high for 40 microseconds. 168 | digitalWrite(_pin, HIGH); 169 | delayMicroseconds(40); 170 | 171 | // Now start reading the data line to get the value from the DHT sensor. 172 | pinMode(_pin, INPUT_PULLUP); 173 | delayMicroseconds(10); // Delay a bit to let sensor pull data line low. 174 | 175 | // First expect a low signal for ~80 microseconds followed by a high signal 176 | // for ~80 microseconds again. 177 | if (expectPulse(LOW) == 0) { 178 | DEBUG_PRINTLN(F("Timeout waiting for start signal low pulse.")); 179 | _lastresult = ERROR_TIMEOUT_LOW; 180 | return _lastresult; 181 | } 182 | if (expectPulse(HIGH) == 0) { 183 | DEBUG_PRINTLN(F("Timeout waiting for start signal high pulse.")); 184 | _lastresult = ERROR_TIMEOUT_HIGH; 185 | return _lastresult; 186 | } 187 | 188 | // Now read the 40 bits sent by the sensor. Each bit is sent as a 50 189 | // microsecond low pulse followed by a variable length high pulse. If the 190 | // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds 191 | // then it's a 1. We measure the cycle count of the initial 50us low pulse 192 | // and use that to compare to the cycle count of the high pulse to determine 193 | // if the bit is a 0 (high state cycle count < low state cycle count), or a 194 | // 1 (high state cycle count > low state cycle count). Note that for speed all 195 | // the pulses are read into a array and then examined in a later step. 196 | for (int i = 0; i < 80; i += 2) { 197 | cycles[i] = expectPulse(LOW); 198 | cycles[i + 1] = expectPulse(HIGH); 199 | } 200 | 201 | // Inspect pulses and determine which ones are 0 (high state cycle count < low 202 | // state cycle count), or 1 (high state cycle count > low state cycle count). 203 | for (int i=0; i<40; ++i) { 204 | uint32_t lowCycles = cycles[2*i]; 205 | uint32_t highCycles = cycles[2*i+1]; 206 | if ((lowCycles == 0) || (highCycles == 0)) { 207 | DEBUG_PRINTLN(F("Timeout waiting for pulse.")); 208 | _lastresult = ERROR_TIMEOUT; 209 | return _lastresult; 210 | } 211 | data[i/8] <<= 1; 212 | // Now compare the low and high cycle times to see if the bit is a 0 or 1. 213 | if (highCycles > lowCycles) { 214 | // High cycles are greater than 50us low cycle count, must be a 1. 215 | data[i/8] |= 1; 216 | } 217 | // Else high cycles are less than (or equal to, a weird case) the 50us low 218 | // cycle count so this must be a zero. Nothing needs to be changed in the 219 | // stored data. 220 | } 221 | 222 | DEBUG_PRINTLN(F("Received:")); 223 | DEBUG_PRINT(data[0], HEX); DEBUG_PRINT(F(", ")); 224 | DEBUG_PRINT(data[1], HEX); DEBUG_PRINT(F(", ")); 225 | DEBUG_PRINT(data[2], HEX); DEBUG_PRINT(F(", ")); 226 | DEBUG_PRINT(data[3], HEX); DEBUG_PRINT(F(", ")); 227 | DEBUG_PRINT(data[4], HEX); DEBUG_PRINT(F(" =? ")); 228 | DEBUG_PRINTLN((data[0] + data[1] + data[2] + data[3]) & 0xFF, HEX); 229 | 230 | DHT12::ReadStatus cks = DHT12::_checksum(); 231 | if (cks != OK) { 232 | DEBUG_PRINTLN("CHECKSUM ERROR!"); 233 | _lastresult = cks; 234 | return cks; 235 | } 236 | 237 | _lastresult = OK; 238 | return OK; 239 | } 240 | // return DHT12::_readSensor(DHTLIB_DHT_WAKEUP, DHTLIB_DHT_LEADING_ZEROS); 241 | // return DHT12::_readSensor(DHTLIB_DHT11_WAKEUP, DHTLIB_DHT11_LEADING_ZEROS); 242 | 243 | } else { 244 | DEBUG_PRINT("I2C START READING.."); 245 | _wire->beginTransmission(_address); 246 | _wire->write(0); 247 | if (_wire->endTransmission() != 0) { 248 | DEBUG_PRINTLN("CONNECTION ERROR!"); 249 | _lastresult = ERROR_CONNECT; 250 | return _lastresult; 251 | } 252 | _wire->requestFrom(_address, (uint8_t) 5); 253 | for (uint8_t i = 0; i < 5; ++i) { 254 | data[i] = _wire->read(); 255 | DEBUG_PRINTLN(data[i]); 256 | } 257 | 258 | delay(1); 259 | if (_wire->available() != 0) { 260 | DEBUG_PRINTLN("TIMEOUT ERROR!"); 261 | _lastresult = ERROR_TIMEOUT; 262 | return _lastresult; 263 | } 264 | 265 | DHT12::ReadStatus cks = DHT12::_checksum(); 266 | if (cks != OK) { 267 | DEBUG_PRINTLN("CHECKSUM ERROR!"); 268 | _lastresult = cks; 269 | return cks; 270 | } 271 | 272 | DEBUG_PRINTLN("...READING OK"); 273 | _lastresult = OK; 274 | return _lastresult; 275 | } 276 | } 277 | 278 | bool DHT12::read(bool force) { 279 | ReadStatus chk = DHT12::readStatus(force); 280 | DEBUG_PRINT(F("\nRead sensor: ")); 281 | DEBUG_PRINT((chk != DHT12::OK)); 282 | switch (chk) { 283 | case DHT12::OK: 284 | DEBUG_PRINTLN(F("OK")); 285 | break; 286 | case DHT12::ERROR_CHECKSUM: 287 | DEBUG_PRINTLN(F("Checksum error")) 288 | ; 289 | break; 290 | case DHT12::ERROR_TIMEOUT: 291 | DEBUG_PRINTLN(F("Timeout error")) 292 | ; 293 | break; 294 | case DHT12::ERROR_TIMEOUT_HIGH: 295 | DEBUG_PRINTLN(F("Timeout error high")) 296 | ; 297 | break; 298 | case DHT12::ERROR_TIMEOUT_LOW: 299 | DEBUG_PRINTLN(F("Timeout error low")) 300 | ; 301 | break; 302 | case DHT12::ERROR_CONNECT: 303 | DEBUG_PRINTLN(F("Connect error")) 304 | ; 305 | break; 306 | case DHT12::ERROR_ACK_L: 307 | DEBUG_PRINTLN(F("AckL error")) 308 | ; 309 | break; 310 | case DHT12::ERROR_ACK_H: 311 | DEBUG_PRINTLN(F("AckH error")) 312 | ; 313 | break; 314 | case DHT12::ERROR_UNKNOWN: 315 | DEBUG_PRINTLN(F("Unknown error DETECTED")) 316 | ; 317 | break; 318 | case DHT12::NONE: 319 | DEBUG_PRINTLN(F("No result")) 320 | ; 321 | break; 322 | default: 323 | DEBUG_PRINTLN(F("Unknown error")) 324 | ; 325 | break; 326 | } 327 | return (chk == DHT12::OK); 328 | } 329 | 330 | float DHT12::convertCtoF(float c) { 331 | return c * 1.8 + 32; 332 | } 333 | 334 | float DHT12::convertFtoC(float f) { 335 | return (f - 32) * 0.55555; 336 | } 337 | 338 | // boolean isFahrenheit: True == Fahrenheit; False == Celsius 339 | float DHT12::computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit) { 340 | // Using both Rothfusz and Steadman's equations 341 | // http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml 342 | float hi; 343 | 344 | if (!isFahrenheit) 345 | temperature = convertCtoF(temperature); 346 | 347 | hi = 0.5 348 | * (temperature + 61.0 + ((temperature - 68.0) * 1.2) 349 | + (percentHumidity * 0.094)); 350 | 351 | if (hi > 79) { 352 | hi = -42.379 + 2.04901523 * temperature + 10.14333127 * percentHumidity 353 | + -0.22475541 * temperature * percentHumidity 354 | + -0.00683783 * pow(temperature, 2) 355 | + -0.05481717 * pow(percentHumidity, 2) 356 | + 0.00122874 * pow(temperature, 2) * percentHumidity 357 | + 0.00085282 * temperature * pow(percentHumidity, 2) 358 | + -0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2); 359 | 360 | if ((percentHumidity < 13) && (temperature >= 80.0) 361 | && (temperature <= 112.0)) 362 | hi -= ((13.0 - percentHumidity) * 0.25) 363 | * sqrt((17.0 - abs(temperature - 95.0)) * 0.05882); 364 | 365 | else if ((percentHumidity > 85.0) && (temperature >= 80.0) 366 | && (temperature <= 87.0)) 367 | hi += ((percentHumidity - 85.0) * 0.1) 368 | * ((87.0 - temperature) * 0.2); 369 | } 370 | 371 | return isFahrenheit ? hi : convertFtoC(hi); 372 | } 373 | 374 | float DHT12::readHumidity(bool force) { 375 | DEBUG_PRINTLN("----------------------------"); 376 | float humidity = NAN; 377 | 378 | if (_isOneWire) { 379 | if (DHT12::read(force)) { 380 | DEBUG_PRINT(data[0]); 381 | // humidity = data[0]; 382 | humidity = (data[0] + (float) data[1] / 10); 383 | } 384 | } else { 385 | if (DHT12::read(force)) { 386 | humidity = (data[0] + (float) data[1] / 10); 387 | } 388 | } 389 | return humidity; 390 | } 391 | 392 | // boolean S == Scale. True == Fahrenheit; False == Celsius 393 | float DHT12::readTemperature(bool scale, bool force) { 394 | float temperature = NAN; 395 | if (_isOneWire) { 396 | if (DHT12::read(force)) { 397 | // temperature = data[2]; 398 | // if (scale) { 399 | // temperature = convertCtoF(temperature); 400 | // } 401 | byte scaleValue = data[3] & B01111111; 402 | byte signValue = data[3] & B10000000; 403 | 404 | temperature = (data[2] + (float) scaleValue / 10);// ((data[2] & 0x7F)*256 + data[3]); 405 | if (signValue) // negative temperature 406 | temperature = -temperature; 407 | 408 | if (scale) { 409 | temperature = convertCtoF(temperature); 410 | } 411 | } 412 | } else { 413 | 414 | bool r = DHT12::read(force); 415 | DEBUG_PRINT("READ ---> "); 416 | DEBUG_PRINTLN(r); 417 | if (r) { 418 | DEBUG_PRINT("BIT 0 -> "); 419 | DEBUG_PRINTLN(data[0], BIN); 420 | DEBUG_PRINT("BIT 1 -> "); 421 | DEBUG_PRINTLN(data[1], BIN); 422 | DEBUG_PRINT("BIT 2 -> "); 423 | DEBUG_PRINTLN(data[2], BIN); 424 | DEBUG_PRINT("BIT 3 -> "); 425 | DEBUG_PRINTLN(data[3], BIN); 426 | DEBUG_PRINT("BIT 4 -> "); 427 | DEBUG_PRINTLN(data[4], BIN); 428 | DEBUG_PRINT("BIT 5 -> "); 429 | DEBUG_PRINTLN(data[5], BIN); 430 | 431 | byte scaleValue = data[3] & B01111111; 432 | byte signValue = data[3] & B10000000; 433 | 434 | temperature = (data[2] + (float) scaleValue / 10);// ((data[2] & 0x7F)*256 + data[3]); 435 | if (signValue) // negative temperature 436 | temperature = -temperature; 437 | 438 | if (scale) { 439 | temperature = convertCtoF(temperature); 440 | } 441 | } 442 | } 443 | return temperature; 444 | 445 | } 446 | 447 | #include 448 | // dewPoint function NOAA 449 | // reference (1) : http://wahiduddin.net/calc/density_algorithms.htm 450 | // reference (2) : http://www.colorado.edu/geography/weather_station/Geog_site/about.htm 451 | // 452 | // boolean S == Scale. True == Fahrenheit; False == Celsius 453 | float DHT12::dewPoint(float temperature, float humidity, bool isFahrenheit) { 454 | // sloppy but good approximation for 0 ... +70 °C with max. deviation less than 0.25 °C 455 | 456 | float temp; 457 | 458 | if(!isFahrenheit){ 459 | temp = temperature; 460 | } else { 461 | temp = convertFtoC(temperature); 462 | } 463 | 464 | float humi = humidity; 465 | float ans = (temp - (14.55 + 0.114 * temp) * (1 - (0.01 * humi)) - pow(((2.5 + 0.007 * temp) * (1 - (0.01 * humi))),3) - (15.9 + 0.117 * temp) * pow((1 - (0.01 * humi)), 14)); 466 | 467 | if(!isFahrenheit){ 468 | return ans; // returns dew Point in Celsius 469 | } 470 | 471 | return convertCtoF(ans); // returns dew Point in Fahrenheit 472 | } 473 | 474 | //////// PRIVATE 475 | DHT12::ReadStatus DHT12::_checksum() { 476 | uint8_t sum = data[0] + data[1] + data[2] + data[3]; 477 | if (data[4] != sum) 478 | return ERROR_CHECKSUM; 479 | return OK; 480 | } 481 | 482 | // Expect the signal line to be at the specified level for a period of time and 483 | // return a count of loop cycles spent at that level (this cycle count can be 484 | // used to compare the relative time of two pulses). If more than a millisecond 485 | // ellapses without the level changing then the call fails with a 0 response. 486 | // This is adapted from Arduino's pulseInLong function (which is only available 487 | // in the very latest IDE versions): 488 | // https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_pulse.c 489 | uint32_t DHT12::expectPulse(bool level) { 490 | uint32_t count = 0; 491 | // On AVR platforms use direct GPIO port access as it's much faster and better 492 | // for catching pulses that are 10's of microseconds in length: 493 | #if !defined(__AVR) && !defined(__STM32F1__) && !defined(TEENSYDUINO) 494 | uint8_t portState = level ? _bit : 0; 495 | while ((*portInputRegister(_port) & _bit) == portState) { 496 | if (count++ >= _maxcycles) { 497 | return 0; // Exceeded timeout, fail. 498 | } 499 | } 500 | // Otherwise fall back to using digitalRead (this seems to be necessary on ESP8266 501 | // right now, perhaps bugs in direct port access functions?). 502 | #else 503 | while (digitalRead(_pin) == level) { 504 | if (count++ >= _maxcycles) { 505 | return 0; // Exceeded timeout, fail. 506 | } 507 | } 508 | #endif 509 | 510 | return count; 511 | } 512 | -------------------------------------------------------------------------------- /DHT12.h: -------------------------------------------------------------------------------- 1 | /** \mainpage DHT12 sensor library 2 | * DHT12 Sensor Library 3 | * https://www.mischianti.org/2019/01/01/dht12-library-en/ 4 | * 5 | * The MIT License (MIT) 6 | * 7 | * Copyright (c) 2017 Renzo Mischianti www.mischianti.org All right reserved. 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | 28 | #ifndef DHT12_h 29 | #define DHT12_h 30 | 31 | #if ARDUINO >= 100 32 | #include "Arduino.h" 33 | #else 34 | #include "WProgram.h" 35 | #endif 36 | #include "Wire.h" 37 | 38 | #define DEFAULT_DHT12_ADDRESS 0x5C; 39 | #define DEFAULT_SDA SDA; 40 | #define DEFAULT_SCL SCL; 41 | 42 | #define MIN_ELAPSED_TIME 2000 43 | 44 | // Uncomment to enable printing out nice debug messages. 45 | //#define DHT_DEBUG 46 | 47 | // Define where debug output will be printed. 48 | #define DEBUG_PRINTER Serial 49 | 50 | // Setup debug printing macros. 51 | #ifdef DHT_DEBUG 52 | #define DEBUG_PRINT(...) { DEBUG_PRINTER.print(__VA_ARGS__); } 53 | #define DEBUG_PRINTLN(...) { DEBUG_PRINTER.println(__VA_ARGS__); } 54 | #else 55 | #define DEBUG_PRINT(...) {} 56 | #define DEBUG_PRINTLN(...) {} 57 | #endif 58 | 59 | #if !defined(__AVR) && !defined(__STM32F1__) && !defined(TEENSYDUINO) 60 | #define DHTLIB_TIMEOUT 10000 // should be approx. clock/40000 61 | #else 62 | #ifndef F_CPU 63 | #define DHTLIB_TIMEOUT 1000 // should be approx. clock/40000 64 | #else 65 | #define DHTLIB_TIMEOUT (F_CPU/40000) 66 | #endif 67 | #endif 68 | 69 | class DHT12 { 70 | public: 71 | /**Status of the read*/ 72 | enum ReadStatus { 73 | OK, /**All ok*/ 74 | ERROR_CHECKSUM, /**Error on checksum*/ 75 | ERROR_TIMEOUT, /**Timeout error*/ 76 | ERROR_TIMEOUT_LOW, /**Timeout on wait after low pulse*/ 77 | ERROR_TIMEOUT_HIGH,/**Timeout on wait after high pulse*/ 78 | ERROR_CONNECT, /**Connection error (Wire)*/ 79 | ERROR_ACK_L,/**Acknowledge Low */ 80 | ERROR_ACK_H,/**Acknowledge High */ 81 | ERROR_UNKNOWN, /**Error unknown */ 82 | NONE 83 | }; 84 | 85 | /** 86 | * Standard constructor, default wire connection on default SDA SCL pin 87 | */ 88 | DHT12(void); 89 | /** 90 | * Constructor 91 | * @param addressORPin If oneWire == true this is pin number if oneWire false this is address of i2c 92 | * @param oneWire select if is oneWire of i2c 93 | */ 94 | DHT12(uint8_t addressORPin, bool oneWire = false); 95 | //#ifndef __AVR 96 | #if !defined(__AVR) && !defined(__STM32F1__) && !defined(TEENSYDUINO) 97 | /** 98 | * Additional parameter non tested for Arduino, Arduino very slow on software i2c 99 | */ 100 | DHT12(uint8_t sda, uint8_t scl); 101 | DHT12(uint8_t sda, uint8_t scl, uint8_t address); 102 | 103 | #ifdef ESP32 104 | ///// changes for second i2c bus 105 | DHT12(TwoWire *pWire); 106 | DHT12(TwoWire *pWire, uint8_t sda, uint8_t scl); 107 | DHT12(TwoWire *pWire, uint8_t addr); 108 | DHT12(TwoWire *pWire, uint8_t sda, uint8_t scl, uint8_t address); 109 | #endif 110 | #endif 111 | /** 112 | * Start handshake 113 | */ 114 | void begin(void); 115 | /** 116 | * Read temperature 117 | * @param scale Select false --> Celsius true --> Fahrenheit 118 | * @param force 119 | * @return 120 | */ 121 | float readTemperature(bool scale = false, bool force = false); 122 | /** 123 | * Convert Celsius to Fahrenheit 124 | * @param 125 | * @return 126 | */ 127 | float convertCtoF(float); 128 | /** 129 | * Convert Fahrenheit to Celsius 130 | * @param 131 | * @return 132 | */ 133 | float convertFtoC(float); 134 | /** 135 | * The heat index (HI) or humiture is an index that combines air temperature and relative humidity, in shaded areas, as an attempt to determine the human-perceived equivalent temperature, as how hot it would feel if the humidity were some other value in the shade. The result is also known as the "felt air temperature" or "apparent temperature". 136 | * @param temperature 137 | * @param percentHumidity 138 | * @param isFahrenheit specify scale of temperature 139 | * @return 140 | */ 141 | float computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit = true); 142 | /** 143 | * Read humidity percentage 144 | * @param force Force to request new data (if 2secs is not passed from previous request) 145 | * @return 146 | */ 147 | float readHumidity(bool force = false); 148 | /** 149 | * Dew point the atmospheric temperature (varying according to pressure and humidity) below which water droplets begin to condense and dew can form. 150 | * @param temperature 151 | * @param humidity 152 | * @param isFahrenheit specify scale of temperature 153 | * @return 154 | */ 155 | float dewPoint(float temperature, float humidity, bool isFahrenheit = true); 156 | /** 157 | * Read and return status of the read 158 | * @param force 159 | * @return 160 | */ 161 | ReadStatus readStatus(bool force = false);bool read(bool force = false); 162 | 163 | private: 164 | bool _isOneWire = false; 165 | 166 | TwoWire *_wire; 167 | 168 | uint8_t data[5]; 169 | uint8_t _address = DEFAULT_DHT12_ADDRESS 170 | ; 171 | #ifdef __STM32F1__ 172 | #ifndef SDA 173 | #define DEFAULT_SDA PB7 174 | #define DEFAULT_SCL PB6 175 | #endif 176 | #endif 177 | uint8_t _sda = DEFAULT_SDA 178 | ; 179 | uint8_t _scl = DEFAULT_SCL 180 | ; 181 | 182 | uint32_t _lastreadtime = 0; 183 | ReadStatus _lastresult = NONE; 184 | 185 | uint8_t _pin = 3; 186 | #if !defined(__AVR) && !defined(__STM32F1__) && !defined(TEENSYDUINO) 187 | // Use direct GPIO access on an 8-bit AVR so keep track of the port and bitmask 188 | // for the digital pin connected to the DHT. Other platforms will use digitalRead. 189 | uint8_t _bit = 0, _port = 0; 190 | #endif 191 | uint32_t _maxcycles = 0; 192 | 193 | ReadStatus _checksum(void); 194 | uint32_t expectPulse(bool level); 195 | ReadStatus _readSensor(uint8_t wakeupDelay, uint8_t leadingZeroBits); 196 | 197 | }; 198 | 199 | class InterruptLockDht12 { 200 | public: 201 | InterruptLockDht12() { 202 | noInterrupts(); 203 | } 204 | ~InterruptLockDht12() { 205 | interrupts(); 206 | } 207 | 208 | }; 209 | 210 | #endif 211 | -------------------------------------------------------------------------------- /DHT12_sensor_library.h: -------------------------------------------------------------------------------- 1 | /* 2 | * DHT12_sensor_library 3 | * https://www.mischianti.org/2019/01/01/dht12-library-en/ 4 | * 5 | * The MIT License (MIT) 6 | * 7 | * Copyright (c) 2019 Renzo Mischianti www.mischianti.org All right reserved. 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | 28 | #ifndef DHT12_SENSOR_LIBRARY_H 29 | #define DHT12_SENSOR_LIBRARY_H 30 | 31 | #include "DHT12.h" 32 | 33 | #endif 34 | 35 | #pragma once 36 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Renzo Mischianti www.mischianti.org All right reserved. 4 | 5 | You may copy, alter and reuse this code in any way you like, but please leave 6 | reference to www.mischianti.org in your comments if you redistribute this code. 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |
3 | Support forum DHT12 English 6 |
7 |
8 | Forum supporto DHT12 italiano 11 |
12 | 13 | Additional information and document update here on my site: [DHT12 Article](https://www.mischianti.org/2019/01/01/dht12-library-en/). 14 | 15 | Here a comparison of the major competitor of the sensor: 16 | [Temperature humidity sensors comparison (Specifications) Part 1](https://www.mischianti.org/2019/07/01/temperature-humidity-sensors-comparison-settings-part-1/) 17 | 18 | [Temperature humidity sensors comparison (Code configuration) Part 2](https://www.mischianti.org/2019/07/08/temperature-humidity-sensors-comparison-code-configuration-part-2/). 19 | 20 | [Temperature humidity sensors comparison (Data) Part 3](https://www.mischianti.org/2019/07/16/temperature-humidity-sensors-comparison-data-part-3/). 21 | 22 | ![](https://www.mischianti.org/wp-content/uploads/2019/02/BreadBoardArduinoWeather-768x432.jpg) 23 | 24 | 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. 25 | 26 | 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. 27 | 28 | 06/04/2022: v1.0.2 Fix package size 29 | 30 | Tutorial: 31 | 32 | 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. 33 | 34 | # Reef complete DHT12 Humidity & Temperature 35 | 36 | 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. 37 | 38 | The method is the same of *DHT library sensor*, with some adding like *dew point* function. 39 | 40 | To use with i2c (default address and default SDA SCL pin) the constructor is: 41 | ```cpp 42 | DHT12 dht12; 43 | ``` 44 | and take the default value for SDA SCL pin. (It's possible to redefine with specified contructor for esp8266, needed for ESP-01). 45 | or 46 | ```cpp 47 | DHT12 dht12(uint8_t addressOrPin) 48 | ``` 49 | `addressOrPin -> address` 50 | to change address. 51 | 52 | To use one wire: 53 | ```cpp 54 | DHT12 dht12(uint8_t addressOrPin, true) 55 | ``` 56 | `addressOrPin -> pin` 57 | boolean value is the selection of oneWire or i2c mode. 58 | 59 | You can use It with "implicit", "simple read" or "fullread": 60 | **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*. 61 | ```cpp 62 | // The read of sensor have 2secs of elapsed time, unless you pass force parameter 63 | // Read temperature as Celsius (the default) 64 | float t12 = dht12.readTemperature(); 65 | // Read temperature as Fahrenheit (isFahrenheit = true) 66 | float f12 = dht12.readTemperature(true); 67 | // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 68 | float h12 = dht12.readHumidity(); 69 | 70 | 71 | // Compute heat index in Fahrenheit (the default) 72 | float hif12 = dht12.computeHeatIndex(f12, h12); 73 | // Compute heat index in Celsius (isFahreheit = false) 74 | float hic12 = dht12.computeHeatIndex(t12, h12, false); 75 | // Compute dew point in Fahrenheit (the default) 76 | float dpf12 = dht12.dewPoint(f12, h12); 77 | // Compute dew point in Celsius (isFahreheit = false) 78 | float dpc12 = dht12.dewPoint(t12, h12, false); 79 | 80 | ``` 81 | **Simple read** to get a status of read. 82 | ```cpp 83 | // The read of sensor have 2secs of elapsed time, unless you pass force parameter 84 | bool chk = dht12.read(); // true read is ok, false read problem 85 | 86 | // Read temperature as Celsius (the default) 87 | float t12 = dht12.readTemperature(); 88 | // Read temperature as Fahrenheit (isFahrenheit = true) 89 | float f12 = dht12.readTemperature(true); 90 | // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 91 | float h12 = dht12.readHumidity(); 92 | 93 | // Compute heat index in Fahrenheit (the default) 94 | float hif12 = dht12.computeHeatIndex(f12, h12); 95 | // Compute heat index in Celsius (isFahreheit = false) 96 | float hic12 = dht12.computeHeatIndex(t12, h12, false); 97 | // Compute dew point in Fahrenheit (the default) 98 | float dpf12 = dht12.dewPoint(f12, h12); 99 | // Compute dew point in Celsius (isFahreheit = false) 100 | float dpc12 = dht12.dewPoint(t12, h12, false); 101 | 102 | ``` 103 | **Full read** to get a specified status. 104 | ```cpp 105 | // The read of sensor have 2secs of elapsed time, unless you pass force parameter 106 | DHT12::ReadStatus chk = dht12.readStatus(); 107 | Serial.print(F("\nRead sensor: ")); 108 | switch (chk) { 109 | case DHT12::OK: 110 | Serial.println(F("OK")); 111 | break; 112 | case DHT12::ERROR_CHECKSUM: 113 | Serial.println(F("Checksum error")); 114 | break; 115 | case DHT12::ERROR_TIMEOUT: 116 | Serial.println(F("Timeout error")); 117 | break; 118 | case DHT12::ERROR_TIMEOUT_LOW: 119 | Serial.println(F("Timeout error on low signal, try put high pullup resistance")); 120 | break; 121 | case DHT12::ERROR_TIMEOUT_HIGH: 122 | Serial.println(F("Timeout error on low signal, try put low pullup resistance")); 123 | break; 124 | case DHT12::ERROR_CONNECT: 125 | Serial.println(F("Connect error")); 126 | break; 127 | case DHT12::ERROR_ACK_L: 128 | Serial.println(F("AckL error")); 129 | break; 130 | case DHT12::ERROR_ACK_H: 131 | Serial.println(F("AckH error")); 132 | break; 133 | case DHT12::ERROR_UNKNOWN: 134 | Serial.println(F("Unknown error DETECTED")); 135 | break; 136 | case DHT12::NONE: 137 | Serial.println(F("No result")); 138 | break; 139 | default: 140 | Serial.println(F("Unknown error")); 141 | break; 142 | } 143 | 144 | // Read temperature as Celsius (the default) 145 | float t12 = dht12.readTemperature(); 146 | // Read temperature as Fahrenheit (isFahrenheit = true) 147 | float f12 = dht12.readTemperature(true); 148 | // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 149 | float h12 = dht12.readHumidity(); 150 | 151 | // Compute heat index in Fahrenheit (the default) 152 | float hif12 = dht12.computeHeatIndex(f12, h12); 153 | // Compute heat index in Celsius (isFahreheit = false) 154 | float hic12 = dht12.computeHeatIndex(t12, h12, false); 155 | // Compute dew point in Fahrenheit (the default) 156 | float dpf12 = dht12.dewPoint(f12, h12); 157 | // Compute dew point in Celsius (isFahreheit = false) 158 | float dpc12 = dht12.dewPoint(t12, h12, false); 159 | 160 | ``` 161 | 162 | With examples, there are the connection diagram, it's important to use correct pullup resistor. 163 | 164 | Thanks to Bobadas, dplasa and adafruit, to share the code in github (where I take some code and ideas). 165 | 166 | ## DHT12 PIN ## 167 | 168 | ![DHT12 Pin](https://github.com/xreef/DHT12_sensor_library/blob/master/resources/DHT12_pinout.png) 169 | 170 | ## DHT12 connection schema ## 171 | ArduinoUNO i2c 172 | 173 | ![ArduinoUNO i2c](https://github.com/xreef/DHT12_sensor_library/blob/master/examples/ArduinoI2CDHT12/ArduinoI2CDHT12.png) 174 | 175 | ArduinoUNO oneWire 176 | 177 | ![ArduinoUNO oneWire](https://github.com/xreef/DHT12_sensor_library/blob/master/examples/ArduinoOneWireDHT12/ArduinoOneWireDHT12.png) 178 | 179 | esp8266 (D1Mini) i2c 180 | 181 | ![esp8266 (D1Mini) i2c](https://github.com/xreef/DHT12_sensor_library/blob/master/examples/esp8266I2CDHT12/esp8266I2CDHT12.png) 182 | 183 | esp8266 (D1Mini) oneWire 184 | 185 | ![esp8266 (D1Mini) oneWire](https://github.com/xreef/DHT12_sensor_library/blob/master/examples/esp8266OneWireDHT12/esp8266OneWireDHT12.png) 186 | -------------------------------------------------------------------------------- /examples/ArduinoI2CDHT12/ArduinoI2CDHT12.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/DHT12_sensor_library/a07f2cee5b2b9eb95ee3efdeec5ce9ac3536a2df/examples/ArduinoI2CDHT12/ArduinoI2CDHT12.fzz -------------------------------------------------------------------------------- /examples/ArduinoI2CDHT12/ArduinoI2CDHT12.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * DHT12 3 | * Arduino implicit read on i2c 4 | * by Mischianti Renzo 5 | * 6 | * https://www.mischianti.org/2019/01/01/dht12-library-en/ 7 | * 8 | * 9 | * DHT12 ----- Arduino 10 | * SDA ----- A4 11 | * SCL ----- A5 12 | * 13 | */ 14 | 15 | #include "Arduino.h" 16 | 17 | #include 18 | 19 | // Set dht12 i2c comunication on default Wire pin 20 | DHT12 dht12; 21 | 22 | void setup() 23 | { 24 | Serial.begin(112560); 25 | // Start sensor handshake 26 | dht12.begin(); 27 | } 28 | int timeSinceLastRead = 0; 29 | 30 | void loop() 31 | { 32 | // Report every 2 seconds. 33 | if(timeSinceLastRead > 2000) { 34 | // Reading temperature or humidity takes about 250 milliseconds! 35 | // Read temperature as Celsius (the default) 36 | float t12 = dht12.readTemperature(); 37 | // Read temperature as Fahrenheit (isFahrenheit = true) 38 | float f12 = dht12.readTemperature(true); 39 | // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 40 | float h12 = dht12.readHumidity(); 41 | 42 | bool dht12Read = true; 43 | // Check if any reads failed and exit early (to try again). 44 | if (isnan(h12) || isnan(t12) || isnan(f12)) { 45 | Serial.println("Failed to read from DHT12 sensor!"); 46 | 47 | dht12Read = false; 48 | } 49 | 50 | if (dht12Read){ 51 | // Compute heat index in Fahrenheit (the default) 52 | float hif12 = dht12.computeHeatIndex(f12, h12); 53 | // Compute heat index in Celsius (isFahreheit = false) 54 | float hic12 = dht12.computeHeatIndex(t12, h12, false); 55 | // Compute dew point in Fahrenheit (the default) 56 | float dpf12 = dht12.dewPoint(f12, h12); 57 | // Compute dew point in Celsius (isFahreheit = false) 58 | float dpc12 = dht12.dewPoint(t12, h12, false); 59 | 60 | 61 | Serial.print("DHT12=> Humidity: "); 62 | Serial.print(h12); 63 | Serial.print(" %\t"); 64 | Serial.print("Temperature: "); 65 | Serial.print(t12); 66 | Serial.print(" *C "); 67 | Serial.print(f12); 68 | Serial.print(" *F\t"); 69 | Serial.print(" Heat index: "); 70 | Serial.print(hic12); 71 | Serial.print(" *C "); 72 | Serial.print(hif12); 73 | Serial.print(" *F"); 74 | Serial.print(" Dew point: "); 75 | Serial.print(dpc12); 76 | Serial.print(" *C "); 77 | Serial.print(dpf12); 78 | Serial.println(" *F"); 79 | } 80 | timeSinceLastRead = 0; 81 | } 82 | delay(100); 83 | timeSinceLastRead += 100; 84 | 85 | } 86 | -------------------------------------------------------------------------------- /examples/ArduinoI2CDHT12/ArduinoI2CDHT12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/DHT12_sensor_library/a07f2cee5b2b9eb95ee3efdeec5ce9ac3536a2df/examples/ArduinoI2CDHT12/ArduinoI2CDHT12.png -------------------------------------------------------------------------------- /examples/ArduinoOneWireDHT12/ArduinoOneWireDHT12.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/DHT12_sensor_library/a07f2cee5b2b9eb95ee3efdeec5ce9ac3536a2df/examples/ArduinoOneWireDHT12/ArduinoOneWireDHT12.fzz -------------------------------------------------------------------------------- /examples/ArduinoOneWireDHT12/ArduinoOneWireDHT12.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * DHT12 3 | * Arduino implicit read on onw wire 4 | * by Mischianti Renzo 5 | * 6 | * https://www.mischianti.org/2019/01/01/dht12-library-en/ 7 | * 8 | * 9 | * DHT12 ----- Arduino 10 | * SDA ----- A4 11 | * SCL ----- A5 12 | * 13 | */ 14 | 15 | #include "Arduino.h" 16 | 17 | #include 18 | 19 | // Set dht12 pin to 5 and specify that is oneWire comunication (not default i2c) 20 | DHT12 dht12(5, true); 21 | 22 | void setup() 23 | { 24 | Serial.begin(112560); 25 | // Start sensor 26 | dht12.begin(); 27 | } 28 | int timeSinceLastRead = 0; 29 | 30 | void loop() 31 | { 32 | // Report every 2 seconds. 33 | if(timeSinceLastRead > 2000) { 34 | // Reading temperature or humidity takes about 250 milliseconds! 35 | // Read temperature as Celsius (the default) 36 | float t12 = dht12.readTemperature(); 37 | // Read temperature as Fahrenheit (isFahrenheit = true) 38 | float f12 = dht12.readTemperature(true); 39 | // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 40 | float h12 = dht12.readHumidity(); 41 | 42 | bool dht12Read = true; 43 | // Check if any reads failed and exit early (to try again). 44 | if (isnan(h12) || isnan(t12) || isnan(f12)) { 45 | Serial.println("Failed to read from DHT12 sensor!"); 46 | 47 | dht12Read = false; 48 | } 49 | 50 | if (dht12Read){ 51 | // Compute heat index in Fahrenheit (the default) 52 | float hif12 = dht12.computeHeatIndex(f12, h12); 53 | // Compute heat index in Celsius (isFahreheit = false) 54 | float hic12 = dht12.computeHeatIndex(t12, h12, false); 55 | // Compute dew point in Fahrenheit (the default) 56 | float dpf12 = dht12.dewPoint(f12, h12); 57 | // Compute dew point in Celsius (isFahreheit = false) 58 | float dpc12 = dht12.dewPoint(t12, h12, false); 59 | 60 | 61 | Serial.print("DHT12=> Humidity: "); 62 | Serial.print(h12); 63 | Serial.print(" %\t"); 64 | Serial.print("Temperature: "); 65 | Serial.print(t12); 66 | Serial.print(" *C "); 67 | Serial.print(f12); 68 | Serial.print(" *F\t"); 69 | Serial.print(" Heat index: "); 70 | Serial.print(hic12); 71 | Serial.print(" *C "); 72 | Serial.print(hif12); 73 | Serial.print(" *F"); 74 | Serial.print(" Dew point: "); 75 | Serial.print(dpc12); 76 | Serial.print(" *C "); 77 | Serial.print(dpf12); 78 | Serial.println(" *F"); 79 | 80 | 81 | } 82 | timeSinceLastRead = 0; 83 | 84 | } 85 | delay(100); 86 | timeSinceLastRead += 100; 87 | 88 | } 89 | -------------------------------------------------------------------------------- /examples/ArduinoOneWireDHT12/ArduinoOneWireDHT12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/DHT12_sensor_library/a07f2cee5b2b9eb95ee3efdeec5ce9ac3536a2df/examples/ArduinoOneWireDHT12/ArduinoOneWireDHT12.png -------------------------------------------------------------------------------- /examples/advanced/ArduinoUNOCheckReadStatus/ArduinoUNOCheckReadStatus.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * DHT12 3 | * Arduino full read on i2c 4 | * by Mischianti Renzo 5 | * 6 | * https://www.mischianti.org/2019/01/01/dht12-library-en/ 7 | * 8 | * 9 | * DHT12 ----- Arduino 10 | * SDA ----- A4 11 | * SCL ----- A5 12 | * 13 | */ 14 | 15 | #include "Arduino.h" 16 | 17 | #include 18 | 19 | DHT12 dht12; 20 | 21 | void setup() 22 | { 23 | Serial.begin(112560); 24 | 25 | // Start sensor 26 | dht12.begin(); 27 | } 28 | int timeSinceLastRead = 0; 29 | 30 | // The loop function is called in an endless loop 31 | void loop() 32 | { 33 | // Report every 2 seconds. 34 | if(timeSinceLastRead > 2000) { 35 | 36 | // The read of sensor have 2secs of elapsed time, unless you pass force parameter 37 | DHT12::ReadStatus chk = dht12.readStatus(); 38 | Serial.print(F("\nRead sensor: ")); 39 | switch (chk) { 40 | case DHT12::OK: 41 | Serial.println(F("OK")); 42 | break; 43 | case DHT12::ERROR_CHECKSUM: 44 | Serial.println(F("Checksum error")); 45 | break; 46 | case DHT12::ERROR_TIMEOUT: 47 | Serial.println(F("Timeout error")); 48 | break; 49 | case DHT12::ERROR_TIMEOUT_LOW: 50 | Serial.println(F("Timeout error on low signal, try put high pullup resistance")); 51 | break; 52 | case DHT12::ERROR_TIMEOUT_HIGH: 53 | Serial.println(F("Timeout error on low signal, try put low pullup resistance")); 54 | break; 55 | case DHT12::ERROR_CONNECT: 56 | Serial.println(F("Connect error")); 57 | break; 58 | case DHT12::ERROR_ACK_L: 59 | Serial.println(F("AckL error")); 60 | break; 61 | case DHT12::ERROR_ACK_H: 62 | Serial.println(F("AckH error")); 63 | break; 64 | case DHT12::ERROR_UNKNOWN: 65 | Serial.println(F("Unknown error DETECTED")); 66 | break; 67 | case DHT12::NONE: 68 | Serial.println(F("No result")); 69 | break; 70 | default: 71 | Serial.println(F("Unknown error")); 72 | break; 73 | } 74 | 75 | // Read temperature as Celsius (the default) 76 | float t12 = dht12.readTemperature(); 77 | // Read temperature as Fahrenheit (isFahrenheit = true) 78 | float f12 = dht12.readTemperature(true); 79 | // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 80 | float h12 = dht12.readHumidity(); 81 | 82 | bool dht12Read = true; 83 | // Check if any reads failed and exit early (to try again). 84 | 85 | if (isnan(h12) || isnan(t12) || isnan(f12)) { 86 | Serial.println("Failed to read from DHT12 sensor!"); 87 | 88 | dht12Read = false; 89 | } 90 | 91 | if (dht12Read){ 92 | // Compute heat index in Fahrenheit (the default) 93 | float hif12 = dht12.computeHeatIndex(f12, h12); 94 | // Compute heat index in Celsius (isFahreheit = false) 95 | float hic12 = dht12.computeHeatIndex(t12, h12, false); 96 | // Compute dew point in Fahrenheit (the default) 97 | float dpf12 = dht12.dewPoint(f12, h12); 98 | // Compute dew point in Celsius (isFahreheit = false) 99 | float dpc12 = dht12.dewPoint(t12, h12, false); 100 | 101 | 102 | Serial.print("DHT12=> Humidity: "); 103 | Serial.print(h12); 104 | Serial.print(" %\t"); 105 | Serial.print("Temperature: "); 106 | Serial.print(t12); 107 | Serial.print(" *C "); 108 | Serial.print(f12); 109 | Serial.print(" *F\t"); 110 | Serial.print(" Heat index: "); 111 | Serial.print(hic12); 112 | Serial.print(" *C "); 113 | Serial.print(hif12); 114 | Serial.print(" *F"); 115 | Serial.print(" Dew point: "); 116 | Serial.print(dpc12); 117 | Serial.print(" *C "); 118 | Serial.print(dpf12); 119 | Serial.println(" *F"); 120 | 121 | 122 | } 123 | timeSinceLastRead = 0; 124 | 125 | } 126 | delay(100); 127 | timeSinceLastRead += 100; 128 | 129 | } 130 | -------------------------------------------------------------------------------- /examples/esp32TwoWire/esp32I2CDHT12.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/DHT12_sensor_library/a07f2cee5b2b9eb95ee3efdeec5ce9ac3536a2df/examples/esp32TwoWire/esp32I2CDHT12.fzz -------------------------------------------------------------------------------- /examples/esp32TwoWire/esp32I2CDHT12_bb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/DHT12_sensor_library/a07f2cee5b2b9eb95ee3efdeec5ce9ac3536a2df/examples/esp32TwoWire/esp32I2CDHT12_bb.jpg -------------------------------------------------------------------------------- /examples/esp32TwoWire/esp32TwoWire.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * DHT12 3 | * esp32 implicit read on second i2c channel 4 | * by Mischianti Renzo 5 | * 6 | * https://www.mischianti.org/2019/01/01/dht12-library-en/ 7 | * 8 | * 9 | * DHT12 ----- esp32 10 | * SDA ----- 21 11 | * SCL ----- 22 12 | * 13 | */ 14 | 15 | #include "Arduino.h" 16 | #include "Wire.h" 17 | #include 18 | 19 | // Instantiate Wire for generic use at 400kHz 20 | TwoWire I2Cone = TwoWire(0); 21 | // Instantiate Wire for generic use at 100kHz 22 | TwoWire I2Ctwo = TwoWire(1); 23 | 24 | // Set dht12 i2c comunication with second Wire using 21 22 as SDA SCL 25 | DHT12 dht12(&I2Ctwo); 26 | //DHT12 dht12(&I2Ctwo, 21,22); 27 | //DHT12 dht12(&I2Ctwo, 0x5C); 28 | //DHT12 dht12(&I2Ctwo, 21,22,0x5C); 29 | 30 | void setup() 31 | { 32 | I2Cone.begin(16,17,400000); // SDA pin 16, SCL pin 17, 400kHz frequency 33 | 34 | Serial.begin(112560); 35 | // Start sensor 36 | dht12.begin(); 37 | } 38 | int timeSinceLastRead = 0; 39 | 40 | void loop() 41 | { 42 | // Report every 2 seconds. 43 | if(timeSinceLastRead > 2000) { 44 | // Read temperature as Celsius (the default) 45 | float t12 = dht12.readTemperature(); 46 | // Read temperature as Fahrenheit (isFahrenheit = true) 47 | float f12 = dht12.readTemperature(true); 48 | // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 49 | float h12 = dht12.readHumidity(); 50 | 51 | bool dht12Read = true; 52 | // Check if any reads failed and exit early (to try again). 53 | 54 | if (isnan(h12) || isnan(t12) || isnan(f12)) { 55 | Serial.println("Failed to read from DHT12 sensor!"); 56 | 57 | dht12Read = false; 58 | } 59 | 60 | if (dht12Read){ 61 | // Compute heat index in Fahrenheit (the default) 62 | float hif12 = dht12.computeHeatIndex(f12, h12); 63 | // Compute heat index in Celsius (isFahreheit = false) 64 | float hic12 = dht12.computeHeatIndex(t12, h12, false); 65 | // Compute dew point in Fahrenheit (the default) 66 | float dpf12 = dht12.dewPoint(f12, h12); 67 | // Compute dew point in Celsius (isFahreheit = false) 68 | float dpc12 = dht12.dewPoint(t12, h12, false); 69 | 70 | 71 | Serial.print("DHT12=> Humidity: "); 72 | Serial.print(h12); 73 | Serial.print(" %\t"); 74 | Serial.print("Temperature: "); 75 | Serial.print(t12); 76 | Serial.print(" *C "); 77 | Serial.print(f12); 78 | Serial.print(" *F\t"); 79 | Serial.print(" Heat index: "); 80 | Serial.print(hic12); 81 | Serial.print(" *C "); 82 | Serial.print(hif12); 83 | Serial.print(" *F"); 84 | Serial.print(" Dew point: "); 85 | Serial.print(dpc12); 86 | Serial.print(" *C "); 87 | Serial.print(dpf12); 88 | Serial.println(" *F"); 89 | 90 | 91 | } 92 | timeSinceLastRead = 0; 93 | 94 | } 95 | delay(100); 96 | timeSinceLastRead += 100; 97 | } 98 | -------------------------------------------------------------------------------- /examples/esp8266I2CDHT12/esp8266I2CDHT12.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/DHT12_sensor_library/a07f2cee5b2b9eb95ee3efdeec5ce9ac3536a2df/examples/esp8266I2CDHT12/esp8266I2CDHT12.fzz -------------------------------------------------------------------------------- /examples/esp8266I2CDHT12/esp8266I2CDHT12.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * DHT12 3 | * esp8266 i2c communication example 4 | * by Mischianti Renzo 5 | * 6 | * https://www.mischianti.org/2019/01/01/dht12-library-en/ 7 | * 8 | * 9 | * DHT12 ----- Esp8266 10 | * SDL ----- D1 11 | * SDA ----- D2 12 | * 13 | */ 14 | 15 | #include "Arduino.h" 16 | 17 | #include 18 | 19 | // Set dht12 i2c comunication on default Wire pin 20 | DHT12 dht12; 21 | 22 | void setup() 23 | { 24 | Serial.begin(112560); 25 | // Start sensor 26 | dht12.begin(); 27 | } 28 | int timeSinceLastRead = 0; 29 | 30 | void loop() 31 | { 32 | // Report every 2 seconds. 33 | if(timeSinceLastRead > 2000) { 34 | // Read temperature as Celsius (the default) 35 | float t12 = dht12.readTemperature(); 36 | // Read temperature as Fahrenheit (isFahrenheit = true) 37 | float f12 = dht12.readTemperature(true); 38 | // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 39 | float h12 = dht12.readHumidity(); 40 | 41 | bool dht12Read = true; 42 | // Check if any reads failed and exit early (to try again). 43 | 44 | if (isnan(h12) || isnan(t12) || isnan(f12)) { 45 | Serial.println("Failed to read from DHT12 sensor!"); 46 | 47 | dht12Read = false; 48 | } 49 | 50 | if (dht12Read){ 51 | // Compute heat index in Fahrenheit (the default) 52 | float hif12 = dht12.computeHeatIndex(f12, h12); 53 | // Compute heat index in Celsius (isFahreheit = false) 54 | float hic12 = dht12.computeHeatIndex(t12, h12, false); 55 | // Compute dew point in Fahrenheit (the default) 56 | float dpf12 = dht12.dewPoint(f12, h12); 57 | // Compute dew point in Celsius (isFahreheit = false) 58 | float dpc12 = dht12.dewPoint(t12, h12, false); 59 | 60 | 61 | Serial.print("DHT12=> Humidity: "); 62 | Serial.print(h12); 63 | Serial.print(" %\t"); 64 | Serial.print("Temperature: "); 65 | Serial.print(t12); 66 | Serial.print(" *C "); 67 | Serial.print(f12); 68 | Serial.print(" *F\t"); 69 | Serial.print(" Heat index: "); 70 | Serial.print(hic12); 71 | Serial.print(" *C "); 72 | Serial.print(hif12); 73 | Serial.print(" *F"); 74 | Serial.print(" Dew point: "); 75 | Serial.print(dpc12); 76 | Serial.print(" *C "); 77 | Serial.print(dpf12); 78 | Serial.println(" *F"); 79 | 80 | 81 | } 82 | timeSinceLastRead = 0; 83 | 84 | } 85 | delay(100); 86 | timeSinceLastRead += 100; 87 | 88 | } 89 | -------------------------------------------------------------------------------- /examples/esp8266I2CDHT12/esp8266I2CDHT12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/DHT12_sensor_library/a07f2cee5b2b9eb95ee3efdeec5ce9ac3536a2df/examples/esp8266I2CDHT12/esp8266I2CDHT12.png -------------------------------------------------------------------------------- /examples/esp8266OneWireDHT12/esp8266OneWireDHT12.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/DHT12_sensor_library/a07f2cee5b2b9eb95ee3efdeec5ce9ac3536a2df/examples/esp8266OneWireDHT12/esp8266OneWireDHT12.fzz -------------------------------------------------------------------------------- /examples/esp8266OneWireDHT12/esp8266OneWireDHT12.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * DHT12 3 | * esp8266 one wire communication example 4 | * by Mischianti Renzo 5 | * 6 | * https://www.mischianti.org/2019/01/01/dht12-library-en/ 7 | * 8 | * 9 | * DHT12 ----- Esp8266 10 | * SDA ----- D1 11 | * SCL ----- D2 12 | * 13 | */ 14 | 15 | #include "Arduino.h" 16 | 17 | #include 18 | 19 | // Set dht12 pin to 5 and specify that is oneWire comunication (not default i2c) 20 | DHT12 dht12(D5, true); 21 | 22 | //The setup function is called once at startup of the sketch 23 | void setup() 24 | { 25 | Serial.begin(112560); 26 | // Add your initialization code here 27 | dht12.begin(); 28 | } 29 | int timeSinceLastRead = 0; 30 | 31 | void loop() 32 | { 33 | // Report every 2 seconds. 34 | if(timeSinceLastRead > 2000) { 35 | // Read temperature as Celsius (the default) 36 | float t12 = dht12.readTemperature(); 37 | // Read temperature as Fahrenheit (isFahrenheit = true) 38 | float f12 = dht12.readTemperature(true); 39 | // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 40 | float h12 = dht12.readHumidity(); 41 | 42 | bool dht12Read = true; 43 | // Check if any reads failed and exit early (to try again). 44 | if (isnan(h12) || isnan(t12) || isnan(f12)) { 45 | Serial.println("Failed to read from DHT12 sensor!"); 46 | 47 | dht12Read = false; 48 | } 49 | 50 | if (dht12Read){ 51 | // Compute heat index in Fahrenheit (the default) 52 | float hif12 = dht12.computeHeatIndex(f12, h12); 53 | // Compute heat index in Celsius (isFahreheit = false) 54 | float hic12 = dht12.computeHeatIndex(t12, h12, false); 55 | // Compute dew point in Fahrenheit (the default) 56 | float dpf12 = dht12.dewPoint(f12, h12); 57 | // Compute dew point in Celsius (isFahreheit = false) 58 | float dpc12 = dht12.dewPoint(t12, h12, false); 59 | 60 | 61 | Serial.print("DHT12=> Humidity: "); 62 | Serial.print(h12); 63 | Serial.print(" %\t"); 64 | Serial.print("Temperature: "); 65 | Serial.print(t12); 66 | Serial.print(" *C "); 67 | Serial.print(f12); 68 | Serial.print(" *F\t"); 69 | Serial.print(" Heat index: "); 70 | Serial.print(hic12); 71 | Serial.print(" *C "); 72 | Serial.print(hif12); 73 | Serial.print(" *F"); 74 | Serial.print(" Dew point: "); 75 | Serial.print(dpc12); 76 | Serial.print(" *C "); 77 | Serial.print(dpf12); 78 | Serial.println(" *F"); 79 | } 80 | timeSinceLastRead = 0; 81 | } 82 | delay(100); 83 | timeSinceLastRead += 100; 84 | } 85 | -------------------------------------------------------------------------------- /examples/esp8266OneWireDHT12/esp8266OneWireDHT12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/DHT12_sensor_library/a07f2cee5b2b9eb95ee3efdeec5ce9ac3536a2df/examples/esp8266OneWireDHT12/esp8266OneWireDHT12.png -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ########################################### 2 | # Syntax Coloring Map For DHT12-sensor-library 3 | ########################################### 4 | 5 | ########################################### 6 | # Datatypes (KEYWORD1) 7 | ########################################### 8 | 9 | DHT12 KEYWORD1 10 | 11 | ########################################### 12 | # Methods and Functions (KEYWORD2) 13 | ########################################### 14 | 15 | begin KEYWORD2 16 | readTemperature KEYWORD2 17 | convertCtoF KEYWORD2 18 | convertFtoC KEYWORD2 19 | computeHeatIndex KEYWORD2 20 | readHumidity KEYWORD2 21 | dewPoint KEYWORD2 22 | readStatus KEYWORD2 23 | read KEYWORD2 24 | 25 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=DHT12 sensor library 2 | version=1.0.2 3 | author=Renzo Mischianti 4 | maintainer=Renzo Mischianti 5 | sentence=DHT12 Temp & Humidity Sensors, library for Arduino, ESP8266 and ESP32 6 | paragraph=DHT12 complete library (DHT clone library with same command and some addiction). I2c and OneWire support, connection schema of Arduino UNO, esp32 and esp8266 with examples. 7 | category=Sensors 8 | url=https://www.mischianti.org/2019/01/01/dht12-library-en/ 9 | repository=https://github.com/xreef/DHT12_sensor_library.git 10 | architectures=* 11 | includes=DHT12.h --------------------------------------------------------------------------------