0%

树莓派3B通过HTU21D温湿度传感器获取温度和湿度详细教程

HTU21D是一个尺寸小、低功耗、响应快、性价比高的温湿度传感器,同时具有较高的精度。本次实验调用HTU21D获取温度和湿度,并保存到MySQL数据库中。

一、实验内容

  1. 通过树莓派读取HTU21D的温度、湿度信息,使用并将数据存储到MySQL数据库中。
  2. 使用脚本实现定时采集数据,用于后续展示和分析。

二、实验准备

硬件设备

  1. 树莓派3B
  2. HTU21D温湿度传感器1个(可能需要焊接排针,下图就是焊接之前的)
  3. 母对母杜邦线若干,用于连接树莓派和传感器

软件环境

  1. 树莓派搭载官方操作系统
  2. 使用Python3 来读取和采集数据
  3. 使用MySQL来存储采集到的数据

三、硬件连接

  1. HTU21D一共有4个引脚,分别是数据信号线SDA、时钟信号线SCL、电源输入3.3v和接地端GND,如下图所示:
  2. 树莓派3B的引脚定义如下图所示:
  3. 观察上图可以看出,3号引脚是SDA、5号引脚是SCL。所以接线方法如下:
    3.3V <-------> 1号引脚
    SDA <-------> 3号引脚
    SCL <-------> 5号引脚
    GND <-------> 9号引脚
    当然,3.3V和GND也可以接到其它引脚。 接线完成后如下图所示:

四、读取温度、湿度数据

  1. HTU21D模块使用I²C与树莓派进行通信,I²C仅使用2条线(SDA和SCL)就能进行双向的信息交换。如果想进一步了解,可以查看维基百科I²C的介绍。 当然,不用了解I²C,也能完成这次实验

  2. 首先启用树莓派I²C模块:sudo raspi-config,进入Interfacing Options,然后选择I2C并启用。

  3. 检查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

  4. 检查git是否安装:
    git --version
    如果能够输出版本号,则说明已经安装:

    pi@raspberrypi:~ $** git –version**
    git version 2.11.0

    否则,请先安装git:
    sudo apt-get install git

  5. 使用pip安装sensor:
    sudo pip3 install sensor

  6. 使用命令行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: -- -- -- -- -- -- -- --
  7. 创建一个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)             # 打印温度(摄氏度)
  8. 保存以上代码后,执行脚本: python3 htu21d.py:

    pi@raspberrypi:~ $ python3 htu21d.py 
    96.386474609375
    16.89998046875

    其中96开头的表示相对湿度,16开头的表示温度。到这里,温度和湿度就读取完成啦。

五、将数据存入数据库

  1. 安装数据库,安装了可以跳过。没有安装请参考在树莓派3B上安装PHP 7.3 + Nginx + Mariadb中的第四节: 安装Mariadb数据库

  2. 创建数据库。在本次实验中,数据库名为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]> 
  3. 创建数据表htu21d。在此时实验中,表格共有4个字段:idhumiditytemperaturetime,分别表示流水号、湿度、温度和记录时间。
    其中温度和湿度保存两位小数,数据类型为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)
  4. 安装python的MySQL数据库驱动PyMySQL :
    sudo pip3 install PyMySQL

  5. 编写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()
  6. 保存并执行上述代码,没有任何输出表示执行成功。然后登录数据库查看是否有数据,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]> 

六、定时采集数据

  1. 测试完数据采集和存储后,定时采集就是小菜一碟了。例如将执行python脚本的命令放入crontab中,然后完事,不用继续往下看。但是这样有一个缺点,就是每次执行python脚本可能会消耗一两秒时间,导致每次采集数据的间隔不均匀。

    如果想获得比较均匀的采集时间,可以继续往下看。

    步骤分两步:循环采集、后台执行。

  2. 循环采集只需要将采集和存储数据的部分用放到while中执行即可:

     while True:
         1. 采集温湿度数据
         2. 连接数据库
         3. 存入数据库
         4. 断开数据库连接
         5. 暂停10秒

    如上所示, 如果需要每30秒采集1次,就暂停30秒,以此类推。不过,为什么要将连接数据库和断开数据库的代码写进循环中呢,放到循环外面不是更省事吗?

    因为程序暂停太久,数据库连接可能会超时断开。

  3. 完整代码如下:

     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)
  4. 使用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)
  5. 但是使用命令python3 htu21d.py执行采集数据,程序会一直在前台运行,并且当命令行窗口关闭后,程序就会停止执行。怎样才能让程序后台运行,且关闭命令行窗口也不中断呢?

    下面介绍2种通用的方法,通用,意味着你可以将此方法应用到其它程序上,并且不需要修改程序代码。

  6. 第一种方法:使用nohup。
    nohup 要后台执行的命令 > /dev/null 2>&1 &
    所以,在本次实验中,命令行为:
    nohup python3 htu21d.py > /dev/null 2>&1 &

  7. 第二种方法: Linux使用systemctl创建自定义服务及开机启动