树莓派RaspberryPi使用DHT11、GP2Y1026、TSL2561测量温湿度、光照强度、空气质量监测并在12864屏幕上刷新显示

########Install wiringpi library########

sudo apt-get install wiringpi

sudo apt-get install python3-pip
pip3 install wiringpi


########Install Adafruit DHT Library####

sudo apt-get update
sudo apt-get install build-essential python-dev

sudo git clone https://github.com/adafruit/Adafruit_Python_DHT.git


cd Adafruit_Python_DHT
 
sudo python setup.py install
sudo python3 setup.py install


 

########Install I2C Library#######

sudo apt-get install i2c-tools

########configure 12864#######

命令行驱动12864  来源:教程 - 树莓派Bash脚本串行控制12864液晶屏 - MAKE 趣无尽

#!/bin/bash
################################
#   树莓派 bash 12864驱动
#   By  PokeBox
################################

##引脚定义
declare -ir CS=21       ##使能线;声明CS为只读整型变量
declare -ir SID=20      ##数据线
declare -ir CLK=16      ##时钟线

##引脚控制相关路径
PINDIR=/sys/class/gpio      ##树莓派引脚控制相关映射目录
PIN_INIT=$PINDIR/export     ##树莓派引脚控制映射文件
PIN_UNIT=$PINDIR/unexport   ##撤销引脚控制映射的文件

##脚本程序参数
declare -i EY=$1       ##列控制参数
declare -i EX=$2       ##行控制参数
declare CHR=$3      ##要显示的字符串参数
declare OT=$4       ##其他参数

##子函数体
init_pin()		##引脚初始化函数
{
	for pin in $CS $SID $CLK			##分别初始化三个引脚
	do
		if [ ! -e $PINDIR/gpio${pin}/direction ];then	##判断这个引脚是否已经初始化过
			##echo "初始化$pin"
			echo "$pin" > $PIN_INIT		##如果没有初始化则把对应的引脚号暴露出来
		fi
		echo "out" > $PINDIR/gpio${pin}/direction	##把初始化好的引脚设置为输出模式
		##echo "$pin输出模式"
	done
}

unpin()		##撤销引脚的控制访问
{
	for pin in $CS $SID $CLK
	do
		if [ -e $PINDIR/gpio${pin}/direction ];then
			echo "卸载$pin"
			echo "$pin" > $PIN_UNIT
		fi
	done
}

outpin()		##引脚输出电平控制;用法:outpin <引脚号> <值>
{
	local PIN="$1"
	local VALUE="$2"
	echo "$VALUE" > $PINDIR/gpio${PIN}/value
}

sendbyte()		##发送数据给屏幕;用法:sendbyte <值>
{
	local data="$1"
	for ((i=0;i<8;i++))
	do
		(( DATABIT=(data&0x80) ))
		outpin ${SID} ${DATABIT}	##发数据
		outpin ${CLK} 1			##拉时钟线
		outpin ${CLK} 0
		(( data<<=1 ))			##SPI数据左移一个字节
	done
}

write()		##写数据或写指令;用法:write <[dat/cmd]写数据/指令> <值>
{
	local ddata="${2}"
	if [ "$1" == "cmd" ];then	##判断是发命令还是数据
		sendDATA='0xf8'		##写指令参数
	else	sendDATA='0xfa'		##写数据参数
	fi
	(( Hdata=(ddata&0xf0) ))	##高位数据
	(( Ldata=((ddata<<4)&0xf0) ))	##低位数据
	sendbyte sendDATA
	sendbyte Hdata
	sendbyte Ldata
}

clGRAM()	##清屏
{
	write cmd 0x30
	write cmd 0x01
}

lcdinit()	##屏幕初始化
{
	outpin ${CS} 1	##片选(其实可以直接接到电源上)
	write cmd 0x30	##初始化屏幕指令
	write cmd 0x0c
	write cmd 0x01
	clGRAM
}

lcdprint()	##在屏幕上显示字符串;用法:<X坐标> <Y坐标> <UTF8字符串>
{
	local X=$1		##函数体参数;X坐标
	local Y=$2		##函数体参数;Y坐标
	local OUTCHAR=${3}	##函数体参数;输出的字符串
	
	##DDRAM 相关资料:http://www.360doc.com/content/14/0411/10/10868223_367962970.shtml
	##
	# 80H 81H 82H 83H 84H 85H 86H 87H | 88H 89H 8AH 8BH 8CH 8DH 8EH 8FH
	# 90H 91H 92H 93H 94H 95H 96H 97H | 98H 99H 9AH 9BH 0CH 9DH 9EH 9FH
	# A0H A1H A2H A3H A4H A5H A6H A7H | A8H A9H AAH ABH ACH ADH AEH AFH
	# B0H B1H B2H B3H B4H B5H B6H B7H | B8H B9H BAH BBH BCH BDH BEH BFH
	
	case ${Y} in		##根据Y坐标值设置地址值
	0)	(( address=0x80+X )) ;;		#初始地址+坐标偏移量
	1)	(( address=0x90+X )) ;;
	2)	(( address=0x88+X )) ;;
	3)	(( address=0x98+X )) ;;
	esac
	echo "在$X行$Y列显示$OUTCHAR"
	write cmd ${address}	##写指令

	##把要输出到屏幕上的字符串转换成GB2312编码后再转成16进制数后发送
	for hex in $(echo -n "$OUTCHAR" | iconv -f utf8 -t gb2312 | od -A n -t x1 | sed 's/ / 0x/g')
	do
		write dat ${hex}	##发送一个16进制数据给屏幕
	done
}

##其他参数选项
case $OT in
reset | '-1')	lcdinit;lcdprint ${EX} ${EY} "$CHR" ;;			##重新初始化屏幕
clear | 0)	clGRAM;lcdprint ${EX} ${EY} "$CHR" ;;		##清屏
init | 1)	init_pin;lcdinit;lcdprint ${EX} ${EY} "$CHR" ;;	##全部初始化
unit | 2)	unpin;sleep 0.1 ;;					##关闭控制引脚
help)		echo "<reset> <clear> <init> <unit>" ;;		##显示帮助
*)	lcdprint ${EX} ${EY} "$CHR" ;;				##其他内容
esac

手动读取DHT11的函数 但是成功率不是很高 建议用Adafruit的库

参考自  树莓派通过DHT11温湿度传感器获得当前的温度和湿度 - 科技爱好者博客 -专注于树莓派(Raspberry Pi)      树莓派下DHT11温湿度传感器控制程序(python)_鄙人张钊_有何贵干的博客-CSDN博客_树莓派dht11python

def DHT11(GPIO_Pin):
    data = []
    j = 0

    GPIO.setmode(GPIO.BCM)
    time.sleep(1)
    GPIO.setup(GPIO_Pin, GPIO.OUT)
    GPIO.output(GPIO_Pin, GPIO.LOW)
    time.sleep(0.02)
    GPIO.output(GPIO_Pin, GPIO.HIGH)
    GPIO.setup(GPIO_Pin, GPIO.IN)

    while GPIO.input(GPIO_Pin) == GPIO.LOW:
        continue
 
    while GPIO.input(GPIO_Pin) == GPIO.HIGH:
        continue
 
    while j < 40:
        k = 0
        while GPIO.input(GPIO_Pin) == GPIO.LOW:
            continue
    
        while GPIO.input(GPIO_Pin) == GPIO.HIGH:
            k += 1
            if k > 100:
                break
    
        if k < 8:
            data.append(0)
        else:
            data.append(1)
 
        j += 1

    GPIO.cleanup() 

 
    humidity_bit = data[0:8]
    humidity_point_bit = data[8:16]
    temperature_bit = data[16:24]
    temperature_point_bit = data[24:32]
    check_bit = data[32:40]
 
    humidity = 0
    humidity_point = 0
    temperature = 0
    temperature_point = 0
    check = 0
 
    for i in range(8):
        humidity += humidity_bit[i] * 2 ** (7 - i) 
        humidity_point += humidity_point_bit[i] * 2 ** (7 - i)
        temperature += temperature_bit[i] * 2 ** (7 - i)
        temperature_point += temperature_point_bit[i] * 2 ** (7 - i)
        check += check_bit[i] * 2 ** (7 - i)
 
    tmp = humidity + humidity_point + temperature + temperature_point 
 
    if check != tmp:
        temperature = humidity = -1
        print('Failed to get DHT11 data.')

    return temperature , humidity

主程序

#!/usr/bin/python

#TSL2561:Lumination Sensor
import wiringpi
import time

#DHT11:Temperature Sensor
import Adafruit_DHT

#GP2Y1026:Dust density sensor
import serial
import time

#LCD 12864
import os

#Given IO address
I2Caddr_TSL2561 = 0x39
GPIO_DHT11 = 26
SerialAddr_GP2Y1026 = "/dev/ttyAMA0"

def dust(Serial_addr):
    recv = None
    data = [0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    Vout_H = Vout_L =  Vref_H = Vref_L = -1
    
    ser = serial.Serial(Serial_addr, 2400)
    while True:
        time.sleep(1)
        count = ser.inWaiting()
        if count >= 14:
            recv = ser.read(14)
            break
    ser.flushInput()
    

    for i in range(0,14):
        data[i] = int(recv[i])
    
    for start_byte in range(0,14):
        if data[start_byte] == 170:
            Vout_H = data[start_byte + 1]
            Vout_L = data[start_byte + 2]
            Vref_H = data[start_byte + 3]
            Vref_L = data[start_byte + 4]
            checksum = data[start_byte + 5]
            break

    
    Vout = (Vout_H*256+Vout_L)/1024*5
    ser.close()
    return Vout 



def TSL2561(i2c_addr):

    reg_addr=0x8C
    reg_data=[0,0,0,0]
    ch=[0,0]

    i2cfd=wiringpi.wiringPiI2CSetup(i2c_addr)
    wiringpi.wiringPiI2CWriteReg8(i2cfd,0x80,0x03)
    time.sleep(0.5)

    for i in [0,1,2,3]:
        wiringpi.wiringPiI2CWrite(i2cfd,reg_addr)
        reg_data[i]=wiringpi.wiringPiI2CReadReg8(i2cfd,reg_addr)
        reg_addr+=1

    ch[0]=256*reg_data[1]+reg_data[0]
    ch[1]=256*reg_data[3]+reg_data[2]

    ratio=ch[1]/ch[0]
    if(ratio<=0):
      return -1
    elif ratio<=0.50:
      Lux_full = 0.0304*ch[0]
      Lux_infrared = 0.062*ch[0]*((ch[1]/ch[0])**1.4)
      Lux_visible=(0.0304*ch[0]-0.062*ch[0]*((ch[1]/ch[0])**1.4))
    elif ratio<=0.61:
      Lux_full = 0.0224*ch[0]
      Lux_infrared = 0.031*ch[1]
      Lux_visible=(0.0224*ch[0]-0.031*ch[1])
    elif ratio<=0.80:
      Lux_full = 0.0128*ch[0]
      Lux_infrared = 0.0153*ch[1]
      Lux_visible=(0.0128*ch[0]-0.0153*ch[1])
    elif ratio<=1.3:
      Lux_full=0.00146*ch[0]
      Lux_infrared = 0.00112*ch[1]
      Lux_visible=(0.00146*ch[0]-0.00112*ch[1])
    else:
      Lux_visible = Lux_infrared = Lux_full =0
    return Lux_visible , Lux_infrared , Lux_full

print("#################################")
temp_max = float(input("input temp_max:"))
temp_min = float(input("input temp_min:"))

lux_max = float(input("input lux_max:"))
lux_min = float(input("input lux_min:"))

hum_max = float(input("input hum_max:"))
hum_min = float(input("input hum_min:"))

dust_max = float(input("input dust_max:"))

 
while True:
    print("##################################")
    print("-----Detecting...Please wait-----")

    lum , lum_infr , lum_full = TSL2561(I2Caddr_TSL2561)
    print("Visibile Lumination:%flux" % (lum))
    os.system('sudo ./12864.sh 0 0 "lumination:'+str(int(lum))+'lux" init')
    print("Infrafred Lumination:%flux" % (lum_infr))
    print("Full-Spectrum Lumination:%flux" % (lum_full))

    dust_density = 0
    while dust_density == 0:
        dust_density = dust(SerialAddr_GP2Y1026)/3*1000
    print("Dust Density:%fμg/m3" % (dust_density))
    os.system('sudo ./12864.sh 1 0 "dust:'+str(int(dust_density))+'ug/m3"')

    hum, temp = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11, GPIO_DHT11)
    print("Temperature:%d°C" % (temp))
    print("Humidity:%d%%" % (hum))
    os.system('sudo ./12864.sh 2 0 "Temperature:'+str(int(temp))+'°"')
    os.system('sudo ./12864.sh 3 0 "Humidity:'+str(int(hum))+'%"')
    
    
    print("##################################")
    time.sleep(10)

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值