Hardware components:
- Raspberry Pi 3
- DHT11 Temperature and Humidity Sensor [1] (I use DHT11 because this is what I have now. Also, it’s good enough for my environment – 0 ~ 40 degrees Celsius.)
Pin 1: Output
Pin 2: VCC
Pin 3: GND
- SainSmart LCD Module For Arduino 20 X 4 [2]
Pin 1 : GND
Pin 2 : 5V
Pin 3 : Contrast (0-5V)
Pin 4 : RS (Register Select)
Pin 5 : R/W (Read Write)
Pin 6 : Enable or Strobe
Pin 7 : Data Bit 0
Pin 8 : Data Bit 1
Pin 9 : Data Bit 2
Pin 10: Data Bit 3
Pin 11: Data Bit 4
Pin 12: Data Bit 5
Pin 13: Data Bit 6
Pin 14: Data Bit 7
Pin 15: LCD Backlight +5V**
Pin 16: LCD Backlight GND
Reference site:
https://www.hackster.io/porrey/dht11-dht22-temperature-sensor-077790
http://www.circuitbasics.com/how-to-set-up-the-dht11-humidity-sensor-on-the-raspberry-pi/
Code:
(Reference: [3])
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
import socket
import fcntl
import struct
import logging
import Adafruit_DHT
# Define GPIO to LCD mapping
LCD_RS = 7
LCD_E = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18
LED_ON = 15
# Define some device constants
LCD_WIDTH = 20 # Maximum characters per line
LCD_CHR = True
LCD_CMD = False
LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line
LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line
# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005
def main():
# Main program block
logging.basicConfig(filename='/home/cywang/sensor.log', format='%(asctime)s %(message)s', level=logging.DEBUG, datefmt='%Y.%m.%d %I:%M:%S')
logging.debug("Start temperature and humidity monitor")
GPIO.setmode(GPIO.BCM) # Use BCM GPIO numbers
GPIO.setup(LCD_E, GPIO.OUT) # E
GPIO.setup(LCD_RS, GPIO.OUT) # RS
GPIO.setup(LCD_D4, GPIO.OUT) # DB4
GPIO.setup(LCD_D5, GPIO.OUT) # DB5
GPIO.setup(LCD_D6, GPIO.OUT) # DB6
GPIO.setup(LCD_D7, GPIO.OUT) # DB7
# Initialise display
logging.debug("Initialize LCD")
lcd_init()
logging.debug("Retrieving IP address")
hasIp = False
retry = 3
while hasIp != True and retry > 0:
lanIp = get_ip_address('enxb827eb936cc3')
wirelessIp = get_ip_address('wlan0')
if lanIp != 'N/A':
lcd_string("LAN IP",LCD_LINE_1,1)
lcd_string(lanIp,LCD_LINE_2,1)
hasIp = True
elif wirelessIp != 'N/A':
lcd_string("Wireless IP",LCD_LINE_1,1)
lcd_string(wirelessIp,LCD_LINE_2,1)
hasIp = True
else:
lcd_string("IP Address",LCD_LINE_1,1)
lcd_string(" N'A" ,LCD_LINE_2,1)
retry = retry - 1
logging.debug('Retry time: {0:d}'.format(3 - retry))
time.sleep(60)
logging.debug("Monitoring temperature and humidity...")
lcd_string("Temperature/Humidity",LCD_LINE_3,1)
while True:
sensor_data = get_temperature_and_humidity()
lcd_string(sensor_data,LCD_LINE_4,1)
#logging.debug(sensor_data)
#print sensor_data
time.sleep(10)
def get_temperature_and_humidity():
sensor = Adafruit_DHT.DHT11
pin = 4
try:
humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
if humidity is not None and temperature is not None:
deg = u'\xb0'
logging.debug('Temperature: {0:0.1f} {1:s}C - Humidity: {2:0.1f}%'.format(temperature, deg.encode('utf8'), humidity))
return '{0:0.1f} C / {1:0.1f}%'.format(temperature, humidity)
else:
return "Failed to get temperature/humidity"
except:
return "Failed to get temperature/humidity"
def get_ip_address(ifname):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15])
)[20:24])
except:
return "N/A"
def lcd_init():
# Initialise display
lcd_byte(0x33,LCD_CMD) # 110011 Initialise
lcd_byte(0x32,LCD_CMD) # 110010 Initialise
lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
lcd_byte(0x01,LCD_CMD) # 000001 Clear display
time.sleep(E_DELAY)
def lcd_byte(bits, mode):
# Send byte to data pins
# bits = data
# mode = True for character
# False for command
GPIO.output(LCD_RS, mode) # RS
# High bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x10==0x10:
GPIO.output(LCD_D4, True)
if bits&0x20==0x20:
GPIO.output(LCD_D5, True)
if bits&0x40==0x40:
GPIO.output(LCD_D6, True)
if bits&0x80==0x80:
GPIO.output(LCD_D7, True)
# Toggle 'Enable' pin
lcd_toggle_enable()
# Low bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x01==0x01:
GPIO.output(LCD_D4, True)
if bits&0x02==0x02:
GPIO.output(LCD_D5, True)
if bits&0x04==0x04:
GPIO.output(LCD_D6, True)
if bits&0x08==0x08:
GPIO.output(LCD_D7, True)
# Toggle 'Enable' pin
lcd_toggle_enable()
def lcd_toggle_enable():
# Toggle enable
time.sleep(E_DELAY)
GPIO.output(LCD_E, True)
time.sleep(E_PULSE)
GPIO.output(LCD_E, False)
time.sleep(E_DELAY)
def lcd_string(message,line,style):
if style==1:
message = message.ljust(LCD_WIDTH," ")
elif style==2:
message = message.center(LCD_WIDTH," ")
elif style==3:
message = message.rjust(LCD_WIDTH," ")
lcd_byte(line, LCD_CMD)
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]),LCD_CHR)
def lcd_backlight(flag):
GPIO.output(LED_ON, flag)
if __name__ == '__main__':
main()
logging.debug("Exit")
[1] Elegoo EL-KIT-000 37-in-1 Sensor Module Kit: Amazon Link
[2] SainSmart LCD Module For Arduino 20 X 4: Amazon Link
[3] https://github.com/brantje/rpi-16×2-lcd/blob/master/lcd.py