树莓派通过GPIO获取温度传感器数据

1,017 阅读4分钟

传感器端:收集数据

树莓派端:读取传感器数据,定时传送数据到服务器接口,可以把树莓派封装为物联网网关,做边缘预处理。把抓到的设备数据做数据挖掘,发现设备运行的各种问题,发现生产降本增效的空间

服务器端:获取树莓派数据,数据可视化,定时刷新图标,机器学习,数据分析

  1. 树莓派和传感器安装
  2. 读取传感器数据的python程序
  3. Django网站搭建,并配置REST API
  4. 发送数据到服务器API,并让树莓派定时执行数据传输程序
  5. 网站数据可视化,并定时自动刷新图表

树莓派各个系统初始密码

官方系统 Raspberry Pi
默认用户是 pi 密码为 raspberry

FreeBSD
默认的密码是 freebsd/freebsd 和 root/root。

CentOS 7
默认主机名:rpi2 默认用户名 root 密码 centos

recalbox
默认主机名 root 密码 recalboxroot

OpenELEC
默认主机名 root 密码 openelec

VNC Viewer 连接树莓派

初次

ssh进树莓派之后,确保本地软件列表信息都是最新的,可以输入命令:sudo apt-get update 进行更新。

更新完成后,输入命令:sudo apt-get install tightvncserver,完成 VNC 服务的安装。

在完成安装后需要对 VNC 设置一个连接密码,在命令行中输入: vncpasswd,回车,提示先得输入设置连接客户端密码两次(第一次是设置密码,第二次是确认密码),然后会询问是否需要设置一个只能查看桌面(view-only)的密码,而不能进行操作。

以后

设置完成后,输入命令:vncserver ,启动 VNC 服务,回车后,系统会为 VNC 服务分配一个数字,在通过其他设备连接时需要用到该数字。

image.png

vnc viewer

File -> New connection,弹出 Properties 界面,在 VNC Server 中输入树莓派对应IP地址,后面加上在 Ubuntu 上远程控制树莓派启动 VNC 服务时生成的服务名,用 : 连接,Name 中可输入任意连接标识名,点击 OK。

传感器的连接

使用DHT11温湿度传感器,正面从左到右依次 VCC、DATA、悬空、GND 如上图所示,把温湿度传感器对应地插到树莓派的针脚。

  • VCC(正极) --- 树莓派的3v电源 (左侧第一个 3V PWR )
  • GND (负极)--- 树莓派的GND接口(左侧第五个 GND)
  • DATA (out) ---树莓派的GPIO引脚 (BCM 17,左侧第六个,记住编号,程序里要填)

image.png

3.3V、5V(VCC):电源正极
GND:接地用,负极负极负极
SDA.0、SDA.1:这个是 I2C(I方C)总线数据传输口
SCL.0、SCL.1:I2C总线的时钟信号
GPIO.x(x = 0,1,2,3,4,5,6,7;21,22,23,24,25,26,27,28,29):
通用输入输出接口,GPIO端口,可通过软件分别配置成输入或输出
TXD:用来发送数据
RXD:用来接收数据(一般用于单片机与计算机或者芯片通信,单片机与计算机进行串口通信时,单片机的RXD接计算机的TXD,单片机的TXD接计算机的RXD。详解:https://blog.csdn.net/sdwuyulunbi/article/details/6632382)
MOSI:主输出 从输入
MISO:主输入 从输出
SCLK:系统时钟,指晶振频率
CE0、CE1:片选信号(芯片有效)-表示低电平有效

树莓派读取传感器数据的python程序

总体思路是根据针脚编号,读取到传感器的数据,先把数据保存到本地的文本,以此来检验程序是否正确执行。 后面我们会摒弃这种方法,直接通过REST API把数据传给服务器。这个传感器可以收集温度和湿度。我们主要使用温度数据演示。

import RPi.GPIO as GPIO
import time

channel = 11
data = []
j = 0

GPIO.setmode(GPIO.BOARD)
# 一秒后开始工作
time.sleep(1)
# 设置GPIO接口为写入数据模式
GPIO.setup(channel, GPIO.OUT)
# 输出一个低电平信号
GPIO.output(channel, GPIO.LOW)
time.sleep(0.02)
# 0.02秒后输出一个高电平信号,启动模块测量
GPIO.output(channel, GPIO.HIGH)
# 设置GPIO接口为读取读取数据模式
GPIO.setup(channel, GPIO.IN)

# 等待,获取到高电平信号
while GPIO.input(channel) == GPIO.LOW:
    continue
# 等待,获取到低电平信号
while GPIO.input(channel) == GPIO.HIGH:
    continue

# 获取到高低电平信号后,开始读取模块获取数据
while j < 40:
    k = 0
    while GPIO.input(channel) == GPIO.LOW:
        continue
    while GPIO.input(channel) == GPIO.HIGH:
        k += 1
    if k > 100:
        break
    # 把获取数据放到list中
    if k < 20:
        data.append(0)
    else:
        data.append(1)
    j += 1

# 模块数据读取完毕,打印显示
print("sensor is working.")
print(data)

# 根据获取数据定义解析数据(5组二进制数据)
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:
#     print("temperature :", temperature, "*C, humidity :", humidity, "%")
#
#     # 将内容写进txt文件
#     res = '{value:%f}' % temperature
#     import json
#     with open('/home/pi/Desktop/data.txt', 'a') as outfile:
#         json.dump(res, outfile)
#     outest = open('/home/pi/Desktop/data.txt', 'a')
#     outest.write(res)
#     outest.close
#     print(res)
# else:
#     print("wrong")
#     print("temperature :", temperature, "*C, humidity :", humidity, "% check :", check, ",tmp :", tmp)


print("temperature :", temperature, "*C, humidity :", humidity, "%")
# 将内容写进txt文件
res = '{value:%f}' % temperature
import json

with open('/home/pi/data.txt', 'a') as outfile:
    json.dump(res, outfile)
outest = open('/home/pi/data.txt', 'a')
outest.write(res)
outest.close
print(res)

# 结束进程,释放GPIO引脚
GPIO.cleanup()

image.png

除了自己编写程序外,还可以使用已经编译好的库:

使用 Adafruit 读取 DHT11 温湿度传感器

*更新软件包*

sudo apt-get update

sudo apt-get install build-essential python-dev

*从GitHub获取Adafruit库*

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

*安装完成后pi文件夹下新增Adafruit_Python_DHT文件夹,进入该文件夹安装该库。*

cd Adafruit_Python_DHT

sudo python setup.py install

sudo python3 setup.py install

*安装完成后进入examples文件夹运行AdfruitDHT.py可以获得结果。*

cd examples

sudo python AdafruitDHT.py 11 24

*后面两个数值11代表使用的是DHT11模块,24代表着所接的GIPO引脚编号(BCM)。

在其他Python 程序中使用这个库

参照下面的方法引入Adafruit库,可以使用 “read_retry” 方法来读取 DHT11 数据:

import Adafruit_DHT

*# Set sensor type : Options are DHT11,DHT22 or AM2302*

sensor=Adafruit_DHT.DHT11

*# Set GPIO sensor is connected to*

GPIO=24

*# Use read_retry method. This will retry up to 15 times to*

*# get a sensor reading (waiting 2 seconds between each retry).*

humidity, temperature = Adafruit_DHT.read_retry(sensor, GPIO)

*# Reading the DHT11 is very sensitive to timings and occasionally*

*# the Pi might fail to get a valid reading. So check if readings are valid.*

if humidity is not None and temperature is not None:

print('Temp={0:0.1f}*C Humidity={1:0.1f}%'.format(temperature, humidity))

else:

print('Failed to get reading. Try again!')

DHT11 数据结构

DHT11数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输入输出双向传输。其数据包由5Byte(40Bit)组成。数据分小数部分和整数部分,具体格式在下面说明。一次完整的数据传输为40bit,高位先出。

数据格式:

8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验和(40bit)

校验和数据为前四个字节相加。

传感器数据输出的是未编码的二进制数据。数据(湿度、温度、整数、小数)之间应该分开处理。如果,某次从传感器中读取如下5Byte数据:

byte4    byte3    byte2    byte1    byte0

00101101 00000000 00011100 00000000 01001001

整数     小数      整数     小数      校验和
湿度              温度               

由以上数据就可得到湿度和温度的值,计算方法:

humi (湿度)= byte4 . byte3=45.0 (%RH)

temp (温度)= byte2 . byte1=28.0 ( ℃)

check(校验)= byte4+ byte3+ byte2+ byte1=73(=humi+temp)(校验正确)

注意:DHT11一次通讯时间最大3ms,主机连续采样间隔建议不小于100ms。

有的时候传输会出现一些错误如下

image.png

这单线传数据还能传错啊,直接不校验了