HTU21D是一个尺寸小、低功耗、响应快、性价比高的温湿度传感器,同时具有较高的精度。本次实验调用HTU21D获取温度和湿度,并保存到MySQL数据库中。
一、实验内容
- 通过树莓派读取HTU21D的温度、湿度信息,使用并将数据存储到MySQL数据库中。
- 使用脚本实现定时采集数据,用于后续展示和分析。
二、实验准备
硬件设备
- 树莓派3B
- HTU21D温湿度传感器1个(可能需要焊接排针,下图就是焊接之前的)
- 母对母杜邦线若干,用于连接树莓派和传感器
软件环境
- 树莓派搭载官方操作系统
- 使用Python3 来读取和采集数据
- 使用MySQL来存储采集到的数据
三、硬件连接
- HTU21D一共有4个引脚,分别是数据信号线SDA、时钟信号线SCL、电源输入3.3v和接地端GND,如下图所示:
- 树莓派3B的引脚定义如下图所示:
- 观察上图可以看出,3号引脚是SDA、5号引脚是SCL。所以接线方法如下:
3.3V <-------> 1号引脚
SDA <-------> 3号引脚
SCL <-------> 5号引脚
GND <-------> 9号引脚
当然,3.3V和GND也可以接到其它引脚。 接线完成后如下图所示:
四、读取温度、湿度数据
HTU21D模块使用I²C与树莓派进行通信,I²C仅使用2条线(SDA和SCL)就能进行双向的信息交换。如果想进一步了解,可以查看维基百科I²C的介绍。 当然,不用了解I²C,也能完成这次实验。
首先启用树莓派I²C模块:
sudo raspi-config
,进入Interfacing Options
,然后选择I2C
并启用。检查Python3 和 pip3是否安装:
python3 --version
pip3 --version
能够输出版本号,则说明已经安装:pi@raspberrypi:~ $ python3 –version
Python 3.5.3
pi@raspberrypi:~ $** pip3 –version **
pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.5)如果没有安装,则先安装python3和pip3 :
sudo apt-get install python3 python3-pip
检查git是否安装:
git --version
如果能够输出版本号,则说明已经安装:pi@raspberrypi:~ $** git –version**
git version 2.11.0否则,请先安装git:
sudo apt-get install git
使用pip安装sensor:
sudo pip3 install sensor
使用命令行
i2cdetect -y 1
查看传感器的地址,一般来说是0x40
,输出结果如下:pi@raspberrypi:~ $ i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
创建一个
htu21d.py
文件,用于读取温度湿度数据,文件内容如下:from sensor.HTU21D import HTU21D # 0x40 是第6步中获取到的传感器地址 htu = HTU21D(1, 0x40) h = htu.humidity() # 读取湿度 print(h.RH) # 打印相对湿度 t = htu.temperature() # 读取温度 print(t.C) # 打印温度(摄氏度)
保存以上代码后,执行脚本:
python3 htu21d.py
:pi@raspberrypi:~ $ python3 htu21d.py 96.386474609375 16.89998046875
其中96开头的表示相对湿度,16开头的表示温度。到这里,温度和湿度就读取完成啦。
五、将数据存入数据库
安装数据库,安装了可以跳过。没有安装请参考在树莓派3B上安装PHP 7.3 + Nginx + Mariadb中的第四节:
安装Mariadb数据库
。创建数据库。在本次实验中,数据库名为
sensor
,数据表为htu21d
,可以自行修改。
创建并切换到sensor数据库:create database sensor;
use sensor
pi@raspberrypi:~ $ mysql -u root -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 12 Server version: 10.3.12-MariaDB-2 Raspbian testing-staging Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> create database sensor; Query OK, 1 row affected (0.001 sec) MariaDB [(none)]> use sensor Database changed MariaDB [sensor]>
创建数据表
htu21d
。在此时实验中,表格共有4个字段:id
、humidity
、temperature
、time
,分别表示流水号、湿度、温度和记录时间。
其中温度和湿度保存两位小数,数据类型为DECIMAL(5,2),记录时间类型为datetime,格式为:2018-08-08 12:34:56
。
创建表格的SQL如下:create table htu21d ( id int primary key, humidity decimal(5, 2), temperature decimal(5, 2), time datetime );
创建完成后使用SQL
desc htu21d;
查看表格结构如下:MariaDB [sensor]> desc htu21d; +-------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | humidity | decimal(5,2) | YES | | NULL | | | temperature | decimal(5,2) | YES | | NULL | | | time | datetime | YES | | NULL | | +-------------+--------------+------+-----+---------+-------+ 4 rows in set (0.011 sec)
安装python的MySQL数据库驱动PyMySQL :
sudo pip3 install PyMySQL
编写python代码,获取温湿度数据并存入数据库中:
from sensor.HTU21D import HTU21D import pymysql import time #0x40 是第6步中获取到的传感器地址 htu = HTU21D(1, 0x40) h = htu.humidity() # 读取湿度 t = htu.temperature() # 读取温度 #打开数据库连接,用户名密码改成自己的 db = pymysql.connect("localhost","root","password","sensor") #使用 cursor() 方法创建一个游标对象 cursor cursor = db.cursor() #数据采集时间 record_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) #生成SQL sql = "INSERT INTO htu21d (humidity, temperature, time)"\ "VALUES ('%.2f', '%.2f', '%s')" % (h.RH, t.C, record_time) #插入数据库 cursor.execute(sql) #提交结果 db.commit() #关闭数据库连接 db.close()
保存并执行上述代码,没有任何输出表示执行成功。然后登录数据库查看是否有数据,SQL:
select * from htu21d;
执行结果如下,可以看到,温度、湿度和采集时间已经被记录到数据库中:MariaDB [sensor]> select * from htu21d; +----+----------+-------------+---------------------+ | id | humidity | temperature | time | +----+----------+-------------+---------------------+ | 1 | 78.44 | 18.92 | 2019-03-10 10:01:38 | +----+----------+-------------+---------------------+ 1 row in set (0.001 sec) MariaDB [sensor]>
六、定时采集数据
测试完数据采集和存储后,定时采集就是小菜一碟了。例如将执行python脚本的命令放入crontab中,然后完事,不用继续往下看。但是这样有一个缺点,就是每次执行python脚本可能会消耗一两秒时间,导致每次采集数据的间隔不均匀。
如果想获得比较均匀的采集时间,可以继续往下看。
步骤分两步:循环采集、后台执行。
循环采集只需要将采集和存储数据的部分用放到while中执行即可:
while True: 1. 采集温湿度数据 2. 连接数据库 3. 存入数据库 4. 断开数据库连接 5. 暂停10秒
如上所示, 如果需要每30秒采集1次,就暂停30秒,以此类推。不过,为什么要将连接数据库和断开数据库的代码写进循环中呢,放到循环外面不是更省事吗?
因为程序暂停太久,数据库连接可能会超时断开。
完整代码如下:
from sensor.HTU21D import HTU21D import pymysql import time htu = HTU21D(1, 0x40) while True: h = htu.humidity() # 获取温度 t = htu.temperature() # 获取湿度 db = pymysql.connect("localhost","root","password","sensor") cursor = db.cursor() record_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) sql = "INSERT INTO htu21d (humidity, temperature, time) "\ "VALUES ('%.2f', '%.2f', '%s')" % (h.RH, t.C, record_time) cursor.execute(sql) db.commit() db.close() time.sleep(10)
使用
python3 htu21d.py
执行上面的代码后,新建另外一个命令行窗口,再查看数据库,发现每隔10秒采集一次的数据已经存入数据库中:MariaDB [sensor]> select * from htu21d; +----+----------+-------------+---------------------+ | id | humidity | temperature | time | +----+----------+-------------+---------------------+ | 1 | 78.43 | 18.52 | 2019-03-10 10:46:17 | | 2 | 79.85 | 18.52 | 2019-03-10 10:46:27 | | 3 | 80.70 | 18.53 | 2019-03-10 10:46:37 | | 4 | 80.04 | 18.52 | 2019-03-10 10:46:47 | | 5 | 79.14 | 18.51 | 2019-03-10 10:46:57 | | 6 | 78.79 | 18.50 | 2019-03-10 10:47:08 | +----+----------+-------------+---------------------+ 6 rows in set (0.001 sec)
但是使用命令
python3 htu21d.py
执行采集数据,程序会一直在前台运行,并且当命令行窗口关闭后,程序就会停止执行。怎样才能让程序后台运行,且关闭命令行窗口也不中断呢?下面介绍2种通用的方法,通用,意味着你可以将此方法应用到其它程序上,并且不需要修改程序代码。
第一种方法:使用nohup。
nohup 要后台执行的命令 > /dev/null 2>&1 &
所以,在本次实验中,命令行为:nohup python3 htu21d.py > /dev/null 2>&1 &
第二种方法: Linux使用systemctl创建自定义服务及开机启动。