“BME280 Environmental Sensor”的版本间的差异
来自Waveshare Wiki
Waveshare-admin(讨论 | 贡献) |
小 (文本替换 - 替换“<h1>技术支持</h1>”为“=售后=”) |
||
(未显示5个用户的38个中间版本) | |||
第1行: | 第1行: | ||
+ | <div class="wiki-pages blue-color"> | ||
+ | <!--<div class="tabberlive newwsnav" id="wsnavbar"> | ||
+ | <ul class="tabbernav"> | ||
+ | <li class="nav-link">[[#myintro|说明]]</li> | ||
+ | <li class="nav-link">[[#myresources|资料]]</li> | ||
+ | <li class="nav-link">[[#myfaq|FAQ]]</li> | ||
+ | <li class="nav-link">[[#mysupport|售后]]</li> | ||
+ | </ul> | ||
+ | </div>--> | ||
<div class="tabber"> | <div class="tabber"> | ||
− | |||
− | |||
{{外围模块|colorscheme=blue | {{外围模块|colorscheme=blue | ||
|name = BME280 Environmental Sensor | |name = BME280 Environmental Sensor | ||
− | |img=[[File:BME280-Environmental-Sensor-intro.jpg|360px |alt=BME280-Environmental-Sensor|link= | + | |img=[[File:BME280-Environmental-Sensor-intro.jpg|360px |alt=BME280-Environmental-Sensor|link=https://{{SERVERNAME}}/shop/BME280-Environmental-Sensor.htm | BME280 Environmental Sensor]] |
|category1=温度/湿度 | |category1=温度/湿度 | ||
|category2=大气压强/海拔高度 | |category2=大气压强/海拔高度 | ||
第13行: | 第20行: | ||
| Product1= [[DHT22 Temperature-Humidity Sensor]] | | Product1= [[DHT22 Temperature-Humidity Sensor]] | ||
}} | }} | ||
+ | <div class="tabbertab" title="说明" id="myintro"> | ||
+ | =说明= | ||
+ | |||
+ | ==产品概述== | ||
+ | 这是一款环境传感器,可感知环境温度、湿度和大气压强,支持I2C和SPI接口,兼容3.3V/5V电平,小尺寸,低功耗,高精度和稳定性,适用于环境监测、天气预测、海拔高度监测和物联网应用场景。 | ||
+ | |||
+ | ==特点== | ||
+ | *支持I2C接口通信,可设置从机地址 | ||
+ | *支持SPI接口通信,默认为I2C接口,可通过I/O口设置为SPI | ||
+ | *板载电平转换电路,可兼容3.3V/5V的工作电平 | ||
+ | *提供完善的配套资料手册(Raspberry/Arduino/STM32示例程序和用户手册等) | ||
+ | ==产品参数== | ||
+ | {| border=1; style="width:500px; background:#eff; " | ||
+ | |-align="center" | ||
+ | |工作电压:||5V/3.3V | ||
+ | |-align="center" | ||
+ | |通信接口:||I2C/SPI | ||
+ | |-align="center" | ||
+ | |温度范围:||-40~85°C (分辨率0.01°C,误差±1°C) | ||
+ | |-align="center" | ||
+ | |湿度范围:||0~100%RH (分辨率0.008%RH,±3% RH) | ||
+ | |-align="center" | ||
+ | |压力范围:||300~1100 hPa (分辨率0.18Pa,误差±1 hPa) | ||
+ | |-align="center" | ||
+ | |产品尺寸:||27mmx20mm | ||
+ | |-align="center" | ||
+ | |过孔直径:||2.0mm | ||
+ | |}<br /> | ||
+ | |||
+ | ==接口定义== | ||
+ | {|border=2; style="background:#eeffff;width:600px;" | ||
+ | |-style="background:#ffffee" ; align="center" | ||
+ | |colspan=5|I2C接口 | ||
+ | |-style="background:#ccffcc" ; align="center" | ||
+ | |功能引脚||Arduino 接口|| STM32接口||Raspberry||描述 | ||
+ | |-align="center" | ||
+ | |VCC||3.3V/5V||3.3V /5V||3.3V /5V||电源正 | ||
+ | |-align="center" | ||
+ | |GND||GND||GND||GND||电源地 | ||
+ | |-align="center" | ||
+ | |SDA||A4||PB7||SDA||I2C数据线 | ||
+ | |-align="center" | ||
+ | |SCL||A5||PB6||SCL||I2C时钟线 | ||
+ | |-align="center" | ||
+ | |ADDR||NC/GND||NC/GND||NC/GND||地址片选(默认为高电平):<br />为高电平时,地址为:0x77<br />为低电平时,地址为:0x76 | ||
+ | |-align="center" | ||
+ | |CS||NC||NC||NC||NC | ||
+ | |} | ||
+ | -------------------------- | ||
+ | {|border=2; style="background:#eeffff;width:600px;" | ||
+ | |-style="background:#ffdddd" ; align="center" | ||
+ | |colspan=5|SPI接口 | ||
+ | |-style="background:#eeffcc" ; align="center" | ||
+ | |功能引脚||Arduino 接口||STM32接口||Raspberry||描述 | ||
+ | |-align="center" | ||
+ | |VCC||3.3V /5V||3.3V /5V||3.3V /5V||3.3V电源正 | ||
+ | |-align="center" | ||
+ | |GND||GND||GND||GND||电源地 | ||
+ | |-align="center" | ||
+ | |MOSI||D11||PA7||MOSI||SPI数据输入 | ||
+ | |-align="center" | ||
+ | |SCK||D13||PA5||SCK||SPI时钟输入 | ||
+ | |-align="center" | ||
+ | |MISO||D12||PA6||MISO||SPI数据输出 | ||
+ | |-align="center" | ||
+ | |CS||D10||PB6||27||SPI片选,低电平有效 | ||
+ | |} | ||
+ | |||
+ | ==用于树莓派== | ||
+ | ===安装必要的函数库=== | ||
+ | *需要安装必要的函数库,否则以下的示例程序可能无法正常工作。安装方法详见:<br /> | ||
+ | https://{{SERVERNAME}}/wiki/Pioneer600_Datasheets<br /> | ||
+ | *在官网上找到对应产品,在产品资料打开下载路径,在wiki中下载示例程序:<br /> | ||
+ | [[File:BMP388-Barometric-Pressure-Sensor-user-manual-1.png|800px]]<br /> | ||
+ | *得到解压包,解压得到如下:<br /> | ||
+ | [[File:BMP388-Barometric-Pressure-Sensor-user-manual-2.png|800px]]<br /> | ||
+ | *将Raspberry文件夹拷至树莓派。<br /> | ||
+ | ===前置工作及演示=== | ||
+ | ====前置工作==== | ||
+ | *执行如下命令进行树莓派配置:<br /> | ||
+ | sudo raspi-config | ||
+ | *选择Interfacing Options -> I2C -> yes 启动I2C内核驱动<br /> | ||
+ | *选择Interfacing Options -> SPI -> yes启动SPI内核驱动<br /> | ||
+ | *保存退出后,重启树莓派:<br /> | ||
+ | sudo reboot | ||
+ | *重启后,运行命令查看,I2C,SPI模块是否已启动: | ||
+ | lsmod | ||
+ | *将会有如下的打印信息: | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-3.png|800px]]<br /> | ||
+ | *如果显示i2c_bcm2835和spi_bcm2835则表示I2C,SPI模块已启动。 | ||
+ | *将BME280模块按照前述I2C总线接口说明连接至树莓派。 | ||
+ | *BME280模块的默认I2C器件地址是0x77,若将ADDR接地则器件地址更变为0x76。 | ||
+ | *安装i2c-tools工具进行确认: | ||
+ | sudo apt-get install i2c-tools | ||
+ | *查询已连接的I2C设备 | ||
+ | i2cdetect -y 1 | ||
+ | *将会有如下打印信息: | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-4.png|800px]]<br /> | ||
+ | *若显示77则表示BME280模块成功连接至树莓派成功。 | ||
+ | *若将ADDR连接至GND则打印出76: | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-5.png|800px]]<br /> | ||
+ | <font color=red>注意:以上测试确保I2C总线上没有其它地址和该器件地址重合的设备。如果以上测试成功则I2C模块加载成功,同时BME280模块成功连接至树莓派。 | ||
+ | 同时,BME280模块支持SPI驱动,可参考SPI接口说明部分将BME280连接至树莓派。</font> | ||
+ | ====演示==== | ||
+ | *成功将BME280模块连接至树莓派后: | ||
+ | *如果采用I2C驱动:则先确定I2C器件地址,<u>BME280模块默认I2C器件地址为0X77</u>,若将ADDR接地(或用0欧姆电阻将焊桥连接),则其I2C器件地址变更为0X76。 | ||
+ | *打开main.c文件: | ||
+ | *进入到BME280-Environmental-Sensor-Demo-Code路径下: | ||
+ | cd BME280-Environmental-Sensor-Demo-Code | ||
+ | *打开main.c文件: | ||
+ | vim main.c | ||
+ | *确保main.c中的USEIIC的宏定义为1,以采用I2C驱动。 | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-6.png|800px]]<br /> | ||
+ | *同时检查main.c中的I2C器件地址,确保和当前BME280模块器件地址一致(默认I2C器件地址为0x77,若将ADDR接地则其器件地址为0x76): | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-7.png|800px]]<br /> | ||
+ | *如果采用SPI驱动:则将BME280模块按照接口说明中的SPI总线接线方式进行接线,并将main.c文件中的USEIIC宏定义改为0。 | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-8.png|800px]]<br /> | ||
+ | *保存并退出编辑,然后重新编译:<br /> | ||
+ | sudo make clean | ||
+ | sudo make | ||
+ | *运行: | ||
+ | sudo ./bme280 | ||
+ | *将显示如下数据: | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-9.png|800px]]<br /> | ||
+ | *从左至右分别显示了BME280测得的温度(摄氏度),大气压(百帕斯卡),相对湿(%RH)。若未成功显示数据,或数据显示不正常请检查连线,通信方式,以及器件地址是否有误。 | ||
+ | |||
+ | ==用于Arduino== | ||
+ | *将下载的示例程序的压缩包解压后,将Arduino文件夹下的BME280-Arduino-Library拷贝至Arduino第三方库目录下.之后重启ArduinoIDE,进入并打开文件->实例->BME280_Libreay->bme280test | ||
+ | *按照接口说明中Arduino接口部分接线。 | ||
+ | *默认采用I2C驱动BME280模块,默认I2C器件地址为0X77。 | ||
+ | *如需采用SPI驱动BME280模块,请将bme280test.ino中的宏定义USEIIC改为0: | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-10.png|800px]]<br /> | ||
+ | *如需更改I2C器件的地址为0X76,则将ADDR引脚接至GND(或用0欧姆电阻将焊桥连接),同时将Adafruit.h中的BME280_ADDRESS器件地址改为0X76: | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-11.png|800px]]<br /> | ||
+ | *如需获取准测量的准确海拔,还需测得当地海平面的大气压,并修改SEALEVELPRESSURE_HPA宏定义: | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-12.png|800px]]<br /> | ||
+ | *在正确接线,确定通信方式以及器件地址之后,编译,下载到Arduino。 | ||
+ | *打开:工具 -> 串口监视器,选择波特率为115200,可得如下信息 | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-13.png|800px]]<br /> | ||
+ | *其中从左至右分别显示了BME280传感器测得的温度(摄氏度),大气压(百帕斯卡),相对湿度(%RH),海拔(m)。 | ||
+ | *若未成功显示数据,或数据显示不正常请检查连线,通信方式,以及器件地址是否有误。 | ||
+ | |||
+ | ==用于STM32== | ||
+ | *将下载的示例程序的压缩包解压后,打开STM32文件夹下的STM32-STM32_BME280->USR路径下的工程文件:按照接口说明中STM32接口部分接线。默认采用I2C驱动BME280模块,默认I2C器件地址为0X77。 | ||
+ | *如需采用SPI驱动BME280模块,请将main.c中的宏定义USEIIC改为0: | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-14.png|800px]]<br /> | ||
+ | *如需更改I2C器件的地址为0X76,则将ADDR引脚接至GND(或用0欧姆电阻将焊桥连接),并将dev.dev_id = BME280_I2C_ADDR_SEC;注释: | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-15.png|800px]]<br /> | ||
+ | *编译,下载,本次采用的芯片是STM32F103RBT6,采用USART2输出获得的传感器数据。 | ||
+ | *打开串口调试助手,选择对应的COM口,设置波特率为115200,数据位8位,停止位1位,无奇偶校验位,可得如下数据: | ||
+ | [[File:BME280-Environmental-Sensor-user-manual-16.png|800px]]<br /> | ||
+ | *其中从左至右分别显示了BME280传感器测得的温度(摄氏度),大气压(百帕斯卡),相对湿度(%RH)。 | ||
+ | *若未成功显示数据,或数据显示不正常请检查连线,通信方式,以及器件地址是否有误。 | ||
+ | ===代码分析=== | ||
+ | *例程主要采用了官方(Bosch Sensortec)提供的库:https://github.com/BoschSensortec/BME280_driver | ||
+ | 针对不同平台实现其底层函数,供上层调用。 | ||
+ | *采用SPI驱动BME280的初始化部分为: | ||
+ | <pre> | ||
+ | struct bme280_dev dev; | ||
+ | int8_t rslt = BME280_OK; | ||
+ | |||
+ | /* Sensor_0 interface over SPI with native chip select line */ | ||
+ | dev.dev_id = 0; | ||
+ | dev.intf = BME280_SPI_INTF; | ||
+ | dev.read = user_spi_read; | ||
+ | dev.write = user_spi_write; | ||
+ | dev.delay_ms = user_delay_ms; | ||
+ | |||
+ | rslt = bme280_init(&dev); | ||
+ | </pre> | ||
+ | *采用I2C驱动BME280初始化部分: | ||
+ | <pre> | ||
+ | struct bme280_dev dev; | ||
+ | int8_t rslt = BME280_OK; | ||
+ | |||
+ | dev.dev_id = BME280_I2C_ADDR_PRIM; | ||
+ | dev.intf = BME280_I2C_INTF; | ||
+ | dev.read = user_i2c_read; | ||
+ | dev.write = user_i2c_write; | ||
+ | dev.delay_ms = user_delay_ms; | ||
+ | |||
+ | rslt = bme280_init(&dev); | ||
+ | </pre> | ||
+ | *其中bme280_dev为官方库中给定的BME280设备结构体,用于初始化以及获取数据用,需要针对不同的平台实现以下函数: | ||
+ | <pre> | ||
+ | user_i2c_read() | ||
+ | user_i2c_write() | ||
+ | user_spi_read() | ||
+ | user_spi_write() | ||
+ | user_delay_ms() | ||
+ | </pre> | ||
+ | *并将该函数的函数指针传递给结构体bme280_dev。 | ||
+ | 读取BME280数据的函数为: | ||
+ | int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev) | ||
+ | int8_t stream_sensor_data_normal_mode(struct bme280_dev *dev) | ||
+ | *并且以上函数均调用了打印函数: | ||
+ | void print_sensor_data(struct bme280_data *comp_data) | ||
+ | *不同平台的延时函数,I2C读,I2C写,SPI读,SPI写的实现思路为: | ||
+ | <pre> | ||
+ | void user_delay_ms(uint32_t period) | ||
+ | { | ||
+ | /* | ||
+ | * Return control or wait, | ||
+ | * for a period amount of milliseconds | ||
+ | */ | ||
+ | } | ||
+ | |||
+ | int8_t user_spi_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) | ||
+ | { | ||
+ | int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */ | ||
+ | |||
+ | /* | ||
+ | * The parameter dev_id can be used as a variable to select which Chip Select pin has | ||
+ | * to be set low to activate the relevant device on the SPI bus | ||
+ | */ | ||
+ | |||
+ | /* | ||
+ | * Data on the bus should be like | ||
+ | * |----------------+---------------------+-------------| | ||
+ | * | MOSI | MISO | Chip Select | | ||
+ | * |----------------+---------------------|-------------| | ||
+ | * | (don't care) | (don't care) | HIGH | | ||
+ | * | (reg_addr) | (don't care) | LOW | | ||
+ | * | (don't care) | (reg_data[0]) | LOW | | ||
+ | * | (....) | (....) | LOW | | ||
+ | * | (don't care) | (reg_data[len - 1]) | LOW | | ||
+ | * | (don't care) | (don't care) | HIGH | | ||
+ | * |----------------+---------------------|-------------| | ||
+ | */ | ||
+ | |||
+ | return rslt; | ||
+ | } | ||
+ | |||
+ | int8_t user_spi_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) | ||
+ | { | ||
+ | int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */ | ||
+ | |||
+ | /* | ||
+ | * The parameter dev_id can be used as a variable to select which Chip Select pin has | ||
+ | * to be set low to activate the relevant device on the SPI bus | ||
+ | */ | ||
+ | |||
+ | /* | ||
+ | * Data on the bus should be like | ||
+ | * |---------------------+--------------+-------------| | ||
+ | * | MOSI | MISO | Chip Select | | ||
+ | * |---------------------+--------------|-------------| | ||
+ | * | (don't care) | (don't care) | HIGH | | ||
+ | * | (reg_addr) | (don't care) | LOW | | ||
+ | * | (reg_data[0]) | (don't care) | LOW | | ||
+ | * | (....) | (....) | LOW | | ||
+ | * | (reg_data[len - 1]) | (don't care) | LOW | | ||
+ | * | (don't care) | (don't care) | HIGH | | ||
+ | * |---------------------+--------------|-------------| | ||
+ | */ | ||
+ | |||
+ | return rslt; | ||
+ | } | ||
+ | |||
+ | int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) | ||
+ | { | ||
+ | int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */ | ||
+ | |||
+ | /* | ||
+ | * The parameter dev_id can be used as a variable to store the I2C address of the device | ||
+ | */ | ||
+ | |||
+ | /* | ||
+ | * Data on the bus should be like | ||
+ | * |------------+---------------------| | ||
+ | * | I2C action | Data | | ||
+ | * |------------+---------------------| | ||
+ | * | Start | - | | ||
+ | * | Write | (reg_addr) | | ||
+ | * | Stop | - | | ||
+ | * | Start | - | | ||
+ | * | Read | (reg_data[0]) | | ||
+ | * | Read | (....) | | ||
+ | * | Read | (reg_data[len - 1]) | | ||
+ | * | Stop | - | | ||
+ | * |------------+---------------------| | ||
+ | */ | ||
+ | |||
+ | return rslt; | ||
+ | } | ||
+ | |||
+ | int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) | ||
+ | { | ||
+ | int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */ | ||
+ | |||
+ | /* | ||
+ | * The parameter dev_id can be used as a variable to store the I2C address of the device | ||
+ | */ | ||
+ | |||
+ | /* | ||
+ | * Data on the bus should be like | ||
+ | * |------------+---------------------| | ||
+ | * | I2C action | Data | | ||
+ | * |------------+---------------------| | ||
+ | * | Start | - | | ||
+ | * | Write | (reg_addr) | | ||
+ | * | Write | (reg_data[0]) | | ||
+ | * | Write | (....) | | ||
+ | * | Write | (reg_data[len - 1]) | | ||
+ | * | Stop | - | | ||
+ | * |------------+---------------------| | ||
+ | */ | ||
+ | |||
+ | return rslt; | ||
+ | } | ||
+ | </pre> | ||
+ | 综上,基于官方库,针对不同平台,获取BME280数据的基本流程为: | ||
+ | --------- | ||
+ | *第一步:不同平台的系统及外设初始化。 | ||
+ | *第二步:实现不同平台的I2C读,I2C写,SPI读,SPI写,延时函数,并将函数指针赋值给bme280_dev结构体成员变量,将该结构体指针传递给初始*化函数int8_t bme280_init(struct bme280_dev *dev),初始化BME280设备。 | ||
+ | *第三步:调用int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev)或 | ||
+ | int8_t stream_sensor_data_normal_mode(struct bme280_dev *dev)函数获取BME280传感器数据并打印到上位机或控制台。 | ||
+ | </div> | ||
+ | <div class="tabbertab" title="资料" id="myresources"> | ||
+ | |||
+ | <h1>资料</h1> | ||
+ | |||
===文档=== | ===文档=== | ||
− | *[ | + | <!--*[https://{{SERVERNAME}}/w/upload/3/3a/BME280-Environmental-Sensor-user-manual-cn.pdf 用户手册]<br>--> |
− | *[ | + | *[https://{{SERVERNAME}}/w/upload/4/42/BME280-Environmental-Sensor-Schematic.pdf 原理图] |
===程序=== | ===程序=== | ||
− | *[ | + | *[https://{{SERVERNAME}}/w/upload/b/ba/BME280-Environmental-Sensor-Demo-Code.7z 示例程序] |
===软件=== | ===软件=== | ||
*[https://www.arduino.cc/en/Main/Software Arduino IDE] | *[https://www.arduino.cc/en/Main/Software Arduino IDE] | ||
− | *[ | + | *[https://{{SERVERNAME}}/w/upload/5/5f/Sscom.7z 串口调试助手] |
+ | |||
===相关资料=== | ===相关资料=== | ||
− | *[ | + | *[https://{{SERVERNAME}}/w/upload/9/91/BME280_datasheet.pdf BME280数据手册] |
+ | |||
+ | </div> | ||
+ | |||
+ | |||
+ | <div class="tabbertab" title="FAQ" id="myfaq"> | ||
+ | |||
+ | <h1>FAQ</h1> | ||
+ | |||
+ | <br /> | ||
+ | {{BME280-Environmental-Sensor-FAQ}} | ||
+ | </div> | ||
+ | |||
+ | <div class="tabbertab" title="售后" id="mysupport"> | ||
+ | |||
+ | =售后= | ||
+ | |||
+ | <br /> | ||
+ | {{Service18}} | ||
+ | </div> | ||
+ | |||
+ | </div> | ||
</div> | </div> | ||
− | |||
− |
2023年1月14日 (六) 14:42的最新版本
| |||||||||||||||||||||
| |||||||||||||||||||||
说明
产品概述
这是一款环境传感器,可感知环境温度、湿度和大气压强,支持I2C和SPI接口,兼容3.3V/5V电平,小尺寸,低功耗,高精度和稳定性,适用于环境监测、天气预测、海拔高度监测和物联网应用场景。
特点
- 支持I2C接口通信,可设置从机地址
- 支持SPI接口通信,默认为I2C接口,可通过I/O口设置为SPI
- 板载电平转换电路,可兼容3.3V/5V的工作电平
- 提供完善的配套资料手册(Raspberry/Arduino/STM32示例程序和用户手册等)
产品参数
工作电压: | 5V/3.3V |
通信接口: | I2C/SPI |
温度范围: | -40~85°C (分辨率0.01°C,误差±1°C) |
湿度范围: | 0~100%RH (分辨率0.008%RH,±3% RH) |
压力范围: | 300~1100 hPa (分辨率0.18Pa,误差±1 hPa) |
产品尺寸: | 27mmx20mm |
过孔直径: | 2.0mm |
接口定义
I2C接口 | ||||
功能引脚 | Arduino 接口 | STM32接口 | Raspberry | 描述 |
VCC | 3.3V/5V | 3.3V /5V | 3.3V /5V | 电源正 |
GND | GND | GND | GND | 电源地 |
SDA | A4 | PB7 | SDA | I2C数据线 |
SCL | A5 | PB6 | SCL | I2C时钟线 |
ADDR | NC/GND | NC/GND | NC/GND | 地址片选(默认为高电平): 为高电平时,地址为:0x77 为低电平时,地址为:0x76 |
CS | NC | NC | NC | NC |
SPI接口 | ||||
功能引脚 | Arduino 接口 | STM32接口 | Raspberry | 描述 |
VCC | 3.3V /5V | 3.3V /5V | 3.3V /5V | 3.3V电源正 |
GND | GND | GND | GND | 电源地 |
MOSI | D11 | PA7 | MOSI | SPI数据输入 |
SCK | D13 | PA5 | SCK | SPI时钟输入 |
MISO | D12 | PA6 | MISO | SPI数据输出 |
CS | D10 | PB6 | 27 | SPI片选,低电平有效 |
用于树莓派
安装必要的函数库
- 需要安装必要的函数库,否则以下的示例程序可能无法正常工作。安装方法详见:
https://www.waveshare.net/wiki/Pioneer600_Datasheets
- 在官网上找到对应产品,在产品资料打开下载路径,在wiki中下载示例程序:
- 得到解压包,解压得到如下:
- 将Raspberry文件夹拷至树莓派。
前置工作及演示
前置工作
- 执行如下命令进行树莓派配置:
sudo raspi-config
- 选择Interfacing Options -> I2C -> yes 启动I2C内核驱动
- 选择Interfacing Options -> SPI -> yes启动SPI内核驱动
- 保存退出后,重启树莓派:
sudo reboot
- 重启后,运行命令查看,I2C,SPI模块是否已启动:
lsmod
- 将会有如下的打印信息:
- 如果显示i2c_bcm2835和spi_bcm2835则表示I2C,SPI模块已启动。
- 将BME280模块按照前述I2C总线接口说明连接至树莓派。
- BME280模块的默认I2C器件地址是0x77,若将ADDR接地则器件地址更变为0x76。
- 安装i2c-tools工具进行确认:
sudo apt-get install i2c-tools
- 查询已连接的I2C设备
i2cdetect -y 1
- 将会有如下打印信息:
- 若显示77则表示BME280模块成功连接至树莓派成功。
- 若将ADDR连接至GND则打印出76:
注意:以上测试确保I2C总线上没有其它地址和该器件地址重合的设备。如果以上测试成功则I2C模块加载成功,同时BME280模块成功连接至树莓派。
同时,BME280模块支持SPI驱动,可参考SPI接口说明部分将BME280连接至树莓派。
演示
- 成功将BME280模块连接至树莓派后:
- 如果采用I2C驱动:则先确定I2C器件地址,BME280模块默认I2C器件地址为0X77,若将ADDR接地(或用0欧姆电阻将焊桥连接),则其I2C器件地址变更为0X76。
- 打开main.c文件:
- 进入到BME280-Environmental-Sensor-Demo-Code路径下:
cd BME280-Environmental-Sensor-Demo-Code
- 打开main.c文件:
vim main.c
- 确保main.c中的USEIIC的宏定义为1,以采用I2C驱动。
- 同时检查main.c中的I2C器件地址,确保和当前BME280模块器件地址一致(默认I2C器件地址为0x77,若将ADDR接地则其器件地址为0x76):
- 如果采用SPI驱动:则将BME280模块按照接口说明中的SPI总线接线方式进行接线,并将main.c文件中的USEIIC宏定义改为0。
- 保存并退出编辑,然后重新编译:
sudo make clean sudo make
- 运行:
sudo ./bme280
- 将显示如下数据:
- 从左至右分别显示了BME280测得的温度(摄氏度),大气压(百帕斯卡),相对湿(%RH)。若未成功显示数据,或数据显示不正常请检查连线,通信方式,以及器件地址是否有误。
用于Arduino
- 将下载的示例程序的压缩包解压后,将Arduino文件夹下的BME280-Arduino-Library拷贝至Arduino第三方库目录下.之后重启ArduinoIDE,进入并打开文件->实例->BME280_Libreay->bme280test
- 按照接口说明中Arduino接口部分接线。
- 默认采用I2C驱动BME280模块,默认I2C器件地址为0X77。
- 如需采用SPI驱动BME280模块,请将bme280test.ino中的宏定义USEIIC改为0:
- 如需更改I2C器件的地址为0X76,则将ADDR引脚接至GND(或用0欧姆电阻将焊桥连接),同时将Adafruit.h中的BME280_ADDRESS器件地址改为0X76:
- 如需获取准测量的准确海拔,还需测得当地海平面的大气压,并修改SEALEVELPRESSURE_HPA宏定义:
- 在正确接线,确定通信方式以及器件地址之后,编译,下载到Arduino。
- 打开:工具 -> 串口监视器,选择波特率为115200,可得如下信息
- 其中从左至右分别显示了BME280传感器测得的温度(摄氏度),大气压(百帕斯卡),相对湿度(%RH),海拔(m)。
- 若未成功显示数据,或数据显示不正常请检查连线,通信方式,以及器件地址是否有误。
用于STM32
- 将下载的示例程序的压缩包解压后,打开STM32文件夹下的STM32-STM32_BME280->USR路径下的工程文件:按照接口说明中STM32接口部分接线。默认采用I2C驱动BME280模块,默认I2C器件地址为0X77。
- 如需采用SPI驱动BME280模块,请将main.c中的宏定义USEIIC改为0:
- 如需更改I2C器件的地址为0X76,则将ADDR引脚接至GND(或用0欧姆电阻将焊桥连接),并将dev.dev_id = BME280_I2C_ADDR_SEC;注释:
- 编译,下载,本次采用的芯片是STM32F103RBT6,采用USART2输出获得的传感器数据。
- 打开串口调试助手,选择对应的COM口,设置波特率为115200,数据位8位,停止位1位,无奇偶校验位,可得如下数据:
- 其中从左至右分别显示了BME280传感器测得的温度(摄氏度),大气压(百帕斯卡),相对湿度(%RH)。
- 若未成功显示数据,或数据显示不正常请检查连线,通信方式,以及器件地址是否有误。
代码分析
- 例程主要采用了官方(Bosch Sensortec)提供的库:https://github.com/BoschSensortec/BME280_driver
针对不同平台实现其底层函数,供上层调用。
- 采用SPI驱动BME280的初始化部分为:
struct bme280_dev dev; int8_t rslt = BME280_OK; /* Sensor_0 interface over SPI with native chip select line */ dev.dev_id = 0; dev.intf = BME280_SPI_INTF; dev.read = user_spi_read; dev.write = user_spi_write; dev.delay_ms = user_delay_ms; rslt = bme280_init(&dev);
- 采用I2C驱动BME280初始化部分:
struct bme280_dev dev; int8_t rslt = BME280_OK; dev.dev_id = BME280_I2C_ADDR_PRIM; dev.intf = BME280_I2C_INTF; dev.read = user_i2c_read; dev.write = user_i2c_write; dev.delay_ms = user_delay_ms; rslt = bme280_init(&dev);
- 其中bme280_dev为官方库中给定的BME280设备结构体,用于初始化以及获取数据用,需要针对不同的平台实现以下函数:
user_i2c_read() user_i2c_write() user_spi_read() user_spi_write() user_delay_ms()
- 并将该函数的函数指针传递给结构体bme280_dev。
读取BME280数据的函数为:
int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev) int8_t stream_sensor_data_normal_mode(struct bme280_dev *dev)
- 并且以上函数均调用了打印函数:
void print_sensor_data(struct bme280_data *comp_data)
- 不同平台的延时函数,I2C读,I2C写,SPI读,SPI写的实现思路为:
void user_delay_ms(uint32_t period) { /* * Return control or wait, * for a period amount of milliseconds */ } int8_t user_spi_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) { int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */ /* * The parameter dev_id can be used as a variable to select which Chip Select pin has * to be set low to activate the relevant device on the SPI bus */ /* * Data on the bus should be like * |----------------+---------------------+-------------| * | MOSI | MISO | Chip Select | * |----------------+---------------------|-------------| * | (don't care) | (don't care) | HIGH | * | (reg_addr) | (don't care) | LOW | * | (don't care) | (reg_data[0]) | LOW | * | (....) | (....) | LOW | * | (don't care) | (reg_data[len - 1]) | LOW | * | (don't care) | (don't care) | HIGH | * |----------------+---------------------|-------------| */ return rslt; } int8_t user_spi_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) { int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */ /* * The parameter dev_id can be used as a variable to select which Chip Select pin has * to be set low to activate the relevant device on the SPI bus */ /* * Data on the bus should be like * |---------------------+--------------+-------------| * | MOSI | MISO | Chip Select | * |---------------------+--------------|-------------| * | (don't care) | (don't care) | HIGH | * | (reg_addr) | (don't care) | LOW | * | (reg_data[0]) | (don't care) | LOW | * | (....) | (....) | LOW | * | (reg_data[len - 1]) | (don't care) | LOW | * | (don't care) | (don't care) | HIGH | * |---------------------+--------------|-------------| */ return rslt; } int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) { int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */ /* * The parameter dev_id can be used as a variable to store the I2C address of the device */ /* * Data on the bus should be like * |------------+---------------------| * | I2C action | Data | * |------------+---------------------| * | Start | - | * | Write | (reg_addr) | * | Stop | - | * | Start | - | * | Read | (reg_data[0]) | * | Read | (....) | * | Read | (reg_data[len - 1]) | * | Stop | - | * |------------+---------------------| */ return rslt; } int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) { int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */ /* * The parameter dev_id can be used as a variable to store the I2C address of the device */ /* * Data on the bus should be like * |------------+---------------------| * | I2C action | Data | * |------------+---------------------| * | Start | - | * | Write | (reg_addr) | * | Write | (reg_data[0]) | * | Write | (....) | * | Write | (reg_data[len - 1]) | * | Stop | - | * |------------+---------------------| */ return rslt; }
综上,基于官方库,针对不同平台,获取BME280数据的基本流程为:
- 第一步:不同平台的系统及外设初始化。
- 第二步:实现不同平台的I2C读,I2C写,SPI读,SPI写,延时函数,并将函数指针赋值给bme280_dev结构体成员变量,将该结构体指针传递给初始*化函数int8_t bme280_init(struct bme280_dev *dev),初始化BME280设备。
- 第三步:调用int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev)或
int8_t stream_sensor_data_normal_mode(struct bme280_dev *dev)函数获取BME280传感器数据并打印到上位机或控制台。
FAQ
气压传感器计算得到的高度一般用在短周期内的相对值。比如坐垂直电梯,电梯启动前记录一个高度,电梯上升到3层,记录一个高度,两个高度的高度差是准确的。
如果需要用在绝对场合,可以输入当前位置的高度作为计算的初始值,然后运动观察高度变化就是准确的。不过如果时间长了,也会容易出现高度漂移的问题。
如果项目要求长时间获取准确高度值且频率要求高,就需要融合其他传感器进行处理,比如GPS。