这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 电源与模拟 » 利用AE-BME280和RaspberryPi读取温度、湿度和压力值

共1条 1/1 1 跳转至

利用AE-BME280和RaspberryPi读取温度、湿度和压力值

工程师
2022-08-15 12:06:23     打赏

这篇文章来源于DevicePlus.com英语网站的翻译稿。bme280


在本教程中,我们将使用一个多功能模块,协助Raspberry Pi同时测量温度、湿度和气压三种参数。

该项目需要焊接!如上图所示,该部件带有一个单独的排针,因此我们需要将其焊接到面包板上。

AE-BME280

bme280

图1:AE-BME280 / © Akizuki Denshi

使用BME280的温度/湿度/压力传感器模块套件BME280(日语)
凭借搭载Bosch Sensortec BMP280的传感器模块,您可以同时测量温度、湿度和气压。该模块还可以通过I2C或SPI与微控制器通信。

我们将在本教程中使用这款超紧凑型AE-BME280压力传感器(尺寸:16x10mm)。该模块采购于日本零件供应商Akizuki Denshi,您也可以使用具有相同芯片的Adafruit BME280模块。请注意,Adafruit的引脚布局略有不同,因此连线时请务必参考其技术规格书。

Adafruit BME280 技术规格书

BME280——一块位于元件中心的微小银芯片——承担了大部分工作。该模块表面上还有一个非常小的开口,其作用是读取数值,因此切勿遮盖这个开口。

AE-BME280板和排针本来就是分开的。连接Raspberry Pi的最简单方法就是将两者组装在一起,如图1所示。这需要焊接。我购买的排针有10个引脚,但是连接AE-BME280只需6个引脚,所以应剪掉第6个引脚后面的排针。

技术规格请参见AE-BME280的日语手册

您可以用I2C或SPI进行通信。由于我之前已经用过SPI,所以这次我将尝试使用I2C。

I2C – 维基百科
I2C(集成电路总线)是一种由Philips Semiconductor(现为NXP Semiconductors)发明的串行总线。I2C代表I-平方-C。由于纯文本环境中的字符限制,我们将其称为I2C或IIC。该协议通常用于将低速外围IC连至主板、嵌入式系统和移动电话等设备。

bme280

图2:引脚编号和功能–摘自AE-BME280技术规格书

连接I2C或SPI是不同的,所以我们必须注意引脚接法。请参阅AE-BME280 技术规格书 (日语)或Adafruit BME280 技术规格书(英语)

如图2所示,使用I2C时,我们需要焊接 J3 跳线。我们必须在此跳线处填充焊锡。请注意,这仅适用于AE-BME280芯片。Adafruit芯片不需要设置此跳线。

焊接!

bme280

图3:焊接设备

现在,是时候焊接了!首先应加热烙铁。

焊锡 – 维基百科
焊锡是一种主要由铅和锡组成的合金,与电烙铁配合使用。主要用于连接金属元件,以及将电气元件焊接到电路板上。根据其成分,焊锡会在4-10度时变成超导体。

我在这个项目中用的是这种焊锡。这种焊锡非常柔韧,容易泄漏,因此只能一点一点地送锡。我们还应准备一个吸锡器,以防万一。如果送锡过多,可以用吸锡器吸掉多余的焊锡,所以要小心!

bme280

图4:焊接J3

首先,我们应焊接图4所示的J3跳线。J3与相邻引脚靠的很近,所以要小心不要焊接在一起。送锡时要小心仔细!

 

bme280

图5:焊接排针

下一步是连接排针。我从电路板背面焊接排针。引脚之间的间隙非常小,因此很难将电烙铁塞入。电路板两端引脚的焊锡结块示例如图5所示。

焊接技巧是先用烙铁头稍稍加热引脚,然后再送锡。如果烙铁尖过热,焊锡会燃烧并形成结块。因此,我建议焊完一个引脚后,从电源插座上拔下电烙铁并冷却后再焊接下一个引脚。不必着急。小心不要将引脚焊接在一起。慢慢来!

bme280

图6:连至面包板的AE-BME280

完成!排针焊接完毕,现在电路板垂直插在面包板上。

焊接时,我不小心碰到了排针末端并稍微烫了一下,但幸运的是这并没有影响读数。

接线

现在,让我们将Raspberry Pi连接到AE-BME280。连接示意图如图7所示,因为我们使用的是I2C通信。

bme280

图7:I2C连接方法–摘自AE-BME280技术规格书

在Raspberry Pi上,“SDA”连至GPIO2(引脚3),“SCL”连到GPIO3(引脚5)。VDD连接到引脚1,这样前3个GPIO引脚按顺序排列(参见图8)。接线时容易记忆。

 

bme280

图8:接线示意图

我将AE-BME280上的引脚5(SDO)连至GND,您也可以将其连至VDD。(请注意,如果这样做,数据收集地址会发生变化)。

设置 Raspberry Pi

Raspberry Pi默认禁用I2C。启用I2C的方法与启用SPI的方法相同,请参阅上一个教程:Raspberry Pi WebIOPi物联网,模拟输入编程。在菜单中选择[Preferences] – [Raspberry Pi Configuration],然后打开“Settings ”屏幕。

bme280

点击[Interfaces]选项卡,将[I2C]设为[Enable]

必须重新启动系统该设置才能生效,因此请在弹出窗口中单击“Yes”。重启后,I2C传输已启用。

bme280

(OS: 2015年11月21日发布的Raspbian Jessie版本)

接下来,我们安装使用I2C所需的软件包。我们需要在命令行中使用[i2c-tools],在Python中使用[python-smbus]。

安装命令
sudo apt-get install i2c-tools
sudo apt-get python-smbus

如果运行命令“i2cdetect”,系统会检测通过I2C方式连接的所有设备。

sudo i2cdetect -y 1

bme280

76是十六进制数;代表0x76。

注:选择I2C地址时,如果电路板(SDO)上的引脚5连至GND,那么默认为[0x76];如果连至VDD,则默认为[0x77]。

我将SDO连接到GND,因此显示0x76,但如果连至VDD,则会显示0x77。

此外,i2Cdetect命令中的最后一个参数取决于Raspberry Pi的版本。Revision 1(2012年10月14日之前发货的Raspberry Pi Model B)使用0,而Revision 2指定使用1。我用的是Raspberry Pi 2 Model B,因此参数值为1。

我运行程序时发生了以下错误:

bme280

发生错误后,我查看了dev目录,看到有一个名为[i2c-1]而不是[i2c-0]的文件。我无法打开这个文件,但我认为该文件包含记录的测量值。

sudo i2cdump -y 1 0x76

bme280

上图是我用i2Cdump命令输出寄存器值的结果。看起来设备读取了很多数值,但是我无法分辨哪些值来自哪里以及为什么是这样子的。

我很难对这些值进行转换/计算,所以我从Switch Science库中借用了一些Python源代码:

SWITCHSCIENCE/BME280

单击右上角的“Download ZIP”链接,将Python27文件夹中的“bme_280_sample.py”文件放在Raspberry Pi的相应位置。注意:此程序需要“python-smbus”软件包才能运行。

python /home/pi/bme280_sample.py

准备工作完成后,运行程序!成功运行之后,您会看到三行输出:温度、压力和湿度。

bme280

注意:您必须具有root权限才能运行smbus软件包。和往常一样,我尝试用PHP运行,但是出现错误,所以我放弃了。bme_280_sample.py 源代码中有很多复杂的计算,虽然我Python经验很少,但是我仍然设法修改了输出部分。我的部分定制代码如下:

/home/pi/bme280_custom.py

#coding: utf-8 import smbus import time bus_number  = 1 i2c_address = 0x76 bus = smbus.SMBus(bus_number) digT = [] digP = [] digH = [] t_fine = 0.0 def writeReg(reg_address, data):     bus.write_byte_data(i2c_address,reg_address,data) def get_calib_param():     calib = []     for i in range (0x88,0x88+24):         calib.append(bus.read_byte_data(i2c_address,i))     calib.append(bus.read_byte_data(i2c_address,0xA1))     for i in range (0xE1,0xE1+7):         calib.append(bus.read_byte_data(i2c_address,i))     digT.append((calib[1] << 8) | calib[0])     digT.append((calib[3] << 8) | calib[2])     digT.append((calib[5] << 8) | calib[4])     digP.append((calib[7] << 8) | calib[6])     digP.append((calib[9] << 8) | calib[8])     digP.append((calib[11]<< 8) | calib[10])     digP.append((calib[13]<< 8) | calib[12])     digP.append((calib[15]<< 8) | calib[14])     digP.append((calib[17]<< 8) | calib[16])     digP.append((calib[19]<< 8) | calib[18])     digP.append((calib[21]<< 8) | calib[20])     digP.append((calib[23]<< 8) | calib[22])     digH.append( calib[24] )     digH.append((calib[26]<< 8) | calib[25])     digH.append( calib[27] )     digH.append((calib[28]<< 4) | (0x0F & calib[29]))     digH.append((calib[30]<< 4) | ((calib[29] >> 4) & 0x0F))     digH.append( calib[31] )     for i in range(1,2):         if digT[i] & 0x8000:             digT[i] = (-digT[i] ^ 0xFFFF) + 1     for i in range(1,8):         if digP[i] & 0x8000:             digP[i] = (-digP[i] ^ 0xFFFF) + 1     for i in range(0,6):         if digH[i] & 0x8000:             digH[i] = (-digH[i] ^ 0xFFFF) + 1  def readData():     data = []     for i in range (0xF7, 0xF7+8):         data.append(bus.read_byte_data(i2c_address,i))     pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)     temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)     hum_raw  = (data[6] << 8)  |  data[7]     #compensate_T(temp_raw)     #compensate_P(pres_raw)     #compensate_H(hum_raw)     t = compensate_T(temp_raw)     p = compensate_P(pres_raw)     h = compensate_H(hum_raw)     return p + "," + t + "," + h def compensate_P(adc_P):     global  t_fine     pressure = 0.0     v1 = (t_fine / 2.0) - 64000.0     v2 = (((v1 / 4.0) * (v1 / 4.0)) / 2048) * digP[5]     v2 = v2 + ((v1 * digP[4]) * 2.0)     v2 = (v2 / 4.0) + (digP[3] * 65536.0)     v1 = (((digP[2] * (((v1 / 4.0) * (v1 / 4.0)) / 8192)) / 8)  + ((digP[1] * v1) / 2.0)) / 262144     v1 = ((32768 + v1) * digP[0]) / 32768     if v1 == 0:         return 0     pressure = ((1048576 - adc_P) - (v2 / 4096)) * 3125     if pressure < 0x80000000:         pressure = (pressure * 2.0) / v1     else:         pressure = (pressure / v1) * 2     v1 = (digP[8] * (((pressure / 8.0) * (pressure / 8.0)) / 8192.0)) / 4096     v2 = ((pressure / 4.0) * digP[7]) / 8192.0     pressure = pressure + ((v1 + v2 + digP[6]) / 16.0)        #print "pressure : %7.2f hPa" % (pressure/100)     return "%7.2f" % (pressure/100)     def compensate_T(adc_T):     global t_fine     v1 = (adc_T / 16384.0 - digT[0] / 1024.0) * digT[1]     v2 = (adc_T / 131072.0 - digT[0] / 8192.0) * (adc_T / 131072.0 - digT[0] / 8192.0) * digT[2]     t_fine = v1 + v2     temperature = t_fine / 5120.0     #print "temp : %-6.2f ℃" % (temperature)     return "%.2f" % (temperature)   def compensate_H(adc_H):     global t_fine     var_h = t_fine - 76800.0     if var_h != 0:         var_h = (adc_H - (digH[3] * 64.0 + digH[4]/16384.0 * var_h)) * (digH[1] / 65536.0 * (1.0 + digH[5] / 67108864.0 * var_h * (1.0 + digH[2] / 67108864.0 * var_h)))     else:         return 0     var_h = var_h * (1.0 - digH[0] * var_h / 524288.0)     if var_h > 100.0:         var_h = 100.0     elif var_h < 0.0:         var_h = 0.0     #print "hum : %6.2f %" % (var_h)     return "%.2f" % (var_h) def setup():     osrs_t = 1            #Temperature oversampling x 1     osrs_p = 1            #Pressure oversampling x 1     osrs_h = 1            #Humidity oversampling x 1     mode   = 3            #Normal mode     t_sb   = 5            #Tstandby 1000ms     filter = 0            #Filter off     spi3w_en = 0            #3-wire SPI Disable     ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode     config_reg    = (t_sb << 5) | (filter << 2) | spi3w_en     ctrl_hum_reg  = osrs_h     writeReg(0xF2,ctrl_hum_reg)     writeReg(0xF4,ctrl_meas_reg)     writeReg(0xF5,config_reg) setup() get_calib_param() if __name__ == '__main__':     try:         readData()     except KeyboardInterrupt:         pass

 

我并没有修改太多代码,只是对主要的“处理”部分进行了一些小的调整。我将“print”改为“return”并进行了相关编辑,使得程序以CSV格式返回数值(带逗号)。

/home/pi/bme280.py

#coding: utf-8   import bme280_custom import datetime import os   dir_path = '/home/pi/bme280-data'   now = datetime.datetime.now() filename = now.strftime('%Y%m%d') label = now.strftime('%H:%M') csv = bme280_custom.readData()   if not os.path.exists('/home/pi/bme280-data'):     os.makedirs('/home/pi/bme280-data') f = open('/home/pi/bme280-data/'+filename+'.csv','a') f.write("'"+label+"',"+csv+"\n") f.close()

 

我创建了另一个py,从之前修改过的“bme280_custom.py”中调用readData()函数。这会将读取的数值保存在CSV文件中。文件的设置如下:记录一整天的数据,以日期作为文件名保存。

我用cron登记了这个程序并进行了设置,让它定期运行。现在完成了!
sudo crontab -e

0-59/10 * * * * /home/pi/bme280.py

注:我将其设置为每10分钟运行一次。

接下来,我将创建一个PHP文件来显示数据。我用 DS18B20 温度传感器制作温度计时做过类似事情。


/var/www/html/bme280.php

 

<?php $today  = date("Ymd"); $csv_dir  = '/home/pi/bme280-data/'; $csv_file = $today.'.csv'; $grapgh   = ''; if (($handle = fopen($csv_dir.$csv_file, "r")) !== false) {     while (($line = fgets($handle)) !== false) {     $grapgh .= '['.rtrim($line).'],'.PHP_EOL;     }     fclose($handle); }else{     echo 'no data'; } ?> <html> <head> <script type="text/javascript" src="https://www.google.com/jsapi"></script> <script type="text/javascript">     google.load("visualization", "1", {packages:["table"]});     google.setOnLoadCallback(drawTable);       function drawTable() {     var data = new google.visualization.DataTable();     data.addColumn('string', 'Time');     data.addColumn('number', 'Pressure');     data.addColumn('number', 'Temperature');     data.addColumn('number', 'Humidity');     data.addRows([   <?php echo $grapgh; ?>       ]);         var table = new google.visualization.Table(document.getElementById('table_div'));       table.draw(data, {showRowNumber: true});     } </script> </head> <body>   <div id="table_div"></div>   </body> </html>

 

我创建了一个简单的PHP文件,在表中显示相关数据(您必须安装“php5”软件包才能使用PHP)。

bme280

通过这种方式,我可以用浏览器——导航至 https://localhost/bme280.php ——查看CSV文件的内容。即使每隔10分钟,压力也会发生巨大变化!

Raspbian最新版本预装了一个名为“LibreOffice”的办公套件。如果您只是想查看数据,那么可以使用“LibreOffice Calc”(双击CSV文件),然后您会看到如下内容:

总结

今天,我们用AE-BME280传感器构建了一个简单模块来测量多个数值(压力、湿度和温度)。这么小的传感器可以测量多达三个不同的参数,真是太神奇了。传感器非常微小,但非常强大!

这个项目还让我提高了焊接技巧。AE-BME280上的引脚非常小,彼此非常靠近,我当时还担心可能会把多个引脚焊接在一起。最后,成品的引脚焊接得很好,我很高兴。需要焊接的项目可能比较困难,但是值得!





关键词: 利用     AE-BME280     Raspberry Pi    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]