[How to] connect a DHT12 I2c humidity and temperature sensor to OpenWrt and display values on LCD

This is the quick and simple How To about connecting a I2C DHT12, cheap but very accurate humidity and temperature sensor to Openwrt.

For Python, I2C installation and I2C hardware configuration tips, please read my previous post here: [How To] Add 20x4 LCD (HD44780) to a OpenWrt router via I2C


NOTE: this device operates at 3.3V and does not need a voltage level shifter, so you can connect SDA and SCL pins of this device directly to the correspondent Gpio pins of the router :grinning:
You can connect many I2c devices to the same bus (SDA and SCL), just wire them in parallel, but pay attention to the total current consumption and operating voltage of each device, you cannot connnect in parallel devices operating at different voltages!

Connections:

VCC = 3.3V from the router
SDA = SDA GPIO of the router
SCL = SCL GPIO of the router
GND = GND from the router


let's start:

to check if the system detects the device and to check the I2C address (it should be 5c), do the following:

i2cdetect -y 0

test if everything worked. A device should be displayed. For me it looks like this:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- 5c -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

python DHT12 Software

dht12.py

import smbus

DEVICE     = 0x5C #device address
bus = smbus.SMBus(0) 

def readdata(addr=DEVICE):

  #read 5 bytes of data from the device address (0x05C) starting from an offset of zero
  data = bus.read_i2c_block_data(addr,0x00, 5)

  print "Humidity = " + str(data[0]) + "." + str(data[1]) + "%"
  print "Temperature : " + str(data[2]) + "." + str(data[3]) + "C"

  if (data[0] + data[1] + data[2] + data[3] ==  data[4]):
    print "checksum is correct"
  else:
    print "checksum is incorrect, data error"

if __name__=="__main__":
    readdata()

Then we can do the first test:

python dht12.py

The script will provide an output similar to this one:

Humidity = 12.8%
Temperature : 38.8C
checksum is correct


if you don't want to open your router and solder any pin inside, simply buy an USB to I2C dongle and use kmod-i2c-tiny-usb :grinning:

4 Likes

If you want temperature & humidity measurements and the current time/date displayed on the I2C LCD 20x4, this is the python script you need:

note: check here for I2c LCD installation: [How To] Add 20x4 LCD (HD44780) to a OpenWrt router via I2C

vi /etc/test.py

import smbus
import I2C_LCD_driver
import time
import sys
import commands
import locale

from subprocess import check_output
from shlex import split
locale.setlocale(locale.LC_ALL, "us_US")

mylcd = I2C_LCD_driver.lcd()

mylcd.lcd_display_string(" --- OpenWrt --- ", 1)
mylcd.lcd_display_string(" I2c: DHT12 + LCD ", 2)
mylcd.lcd_display_string("by Lovisolo PM 2019", 3)
mylcd.lcd_display_string("parknat12@yahoo.com", 4)
time.sleep(5)

mylcd.lcd_clear() 

while True:
 DEVICE     = 0x5C #device address
 bus = smbus.SMBus(0)  # Rev 2 Pi uses 1

 def readdata(addr=DEVICE):

  #read 5 bytes of data from the device address (0x05C) starting from an offset of zero
  data = bus.read_i2c_block_data(addr,0x00, 5)

  umid=("Humidity: " + str(data[0]) + "." + str(data[1]) + "%")
  temp= ("Temperature: " + str(data[2]) + "." + str(data[3]) + "C")

  
  #print (umid) 
  #print (temp)
  
  #if (data[0] + data[1] + data[2] + data[3] ==  data[4]):
  #  print "checksum is correct"
  #else:
  #  print "checksum is incorrect, data error"


  mylcd.lcd_display_string(temp, 1)
  mylcd.lcd_display_string(umid, 2)
  #mylcd.lcd_display_string("put here whatever else you might need and remove comment", 3)
  mylcd.lcd_display_string("%s" %time.strftime("%a %H:%M" " " "%d/%m/%Y"), 4)
  
  time.sleep(15)

 if __name__=="__main__":
    readdata()

Then launch it directly from /etc/rc.local:

/usr/bin/python /etc/test.py

1 Like

reference: [How To] Add barometric pressure and temperature sensor to Openwrt

If you also want to add a barometric sensor (I2c) and display the pressure on the LCD, this is the python script modified:

from Adafruit_BMP085 import BMP085
import smbus
import I2C_LCD_driver
import Adafruit_BMP085
import time
import sys
import commands
import locale

from subprocess import check_output
from shlex import split
# change the following line to adapt it to your locale settings
locale.setlocale(locale.LC_ALL, "it_IT")

mylcd = I2C_LCD_driver.lcd()

mylcd.lcd_display_string(sys.argv[1], 1)
mylcd.lcd_display_string(sys.argv[2], 2)
mylcd.lcd_display_string(sys.argv[3], 3)
mylcd.lcd_display_string(sys.argv[4], 4)

time.sleep(5)

mylcd.lcd_clear() 

while True:
 DEVICE     = 0x5C #device address
 bus = smbus.SMBus(0)  # Rev 2 Pi uses 1

 bmp = BMP085(0x77)

 def readdata(addr=DEVICE):

  #read 5 bytes of data from the device address (0x05C) starting from an offset of zero
  data = bus.read_i2c_block_data(addr,0x00, 5)

  umid=("Humidity: " + str(data[0]) + "." + str(data[1]) + " %")
  temp= ("Temperature: " + str(data[2]) + "." + str(data[3]) + " C")

  pressure= bmp.readPressure()
  pressione=("Pressure: %.1f hPa" % (pressure / 100.0))  
  
  mylcd.lcd_display_string(temp, 1)
  mylcd.lcd_display_string(umid, 2)
  mylcd.lcd_display_string(pressione, 3)
  mylcd.lcd_display_string("%s" %time.strftime("%a %H:%M" " " "%d/%m/%Y"), 4)
  
  time.sleep(5)

 if __name__=="__main__":
    readdata()

1 Like