电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
【雕爷学编程】Arduino动手做(67)---BMP180气压传感器
分 享
扫描二维码分享
【雕爷学编程】Arduino动手做(67)---BMP180气压传感器
雕爷学编程
雕爷学编程
关注
发布时间: 2020-07-06
丨
阅读: 753
37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来---小小的进步或是搞不掂的问题,希望能够抛砖引玉。 #### 【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真) #### 实验六十七: GY-68 BMP180 新款 BOSCH温度模块气压传感器(替代BMP085) ![](https://cf01.ickimg.com/bbsimages/202007/a8a845e9e88570683049695dbdf2d1bc.jpg) BMP180 是博世Sensortec的新数字气压传感器,具有很高的性能,使应用先进的移动设备,如智能手机、平板电脑和体育设备。它遵循了BMP085带来了很多改进,像小尺寸和数字接口的扩张。超低功耗降至3μA使BMP180节电为您的移动设备的领导者。BMP180也是杰出的非常稳定的性能,最好有独立电源供电。BMP180是一款高精度、小体积、超低能耗的压力传感器,可以应用在移动设备中它的性能卓越,绝对精度最低可以达到0.03hPa,并且耗电极低,只有3μA。BMP180采用强大的8-pin陶瓷无引线芯片承载(LCC)超薄封装,可以通过I2C总线直接与各种微处理器相连。 ![](https://cf01.ickimg.com/bbsimages/202007/2bac0e7f55d301ce2f6c577c3c9d8d6d.jpg) ![](https://cf01.ickimg.com/bbsimages/202007/0044ab97ca2a624511c8e692e118c3e2.jpg) ![](https://cf01.ickimg.com/bbsimages/202007/45fcdf271f5352b6870f19ee48b36269.jpg) BMP180主要特点 压力范围:300~1100hPa(海拔9000米~-500米) 电源电压:1.8V~3.6V(VDDA),1.62V~3.6V(VDDD) VIN需要5V LCC8封装:无铅陶瓷载体封装(LCC) 低功耗:5μA,在标准模式 高精度:低功耗模式下,分辨率为0.06hPa(0.5米) 高线性模式下,分辨率为0.03hPa(0.25米) 含温度输出 I2C接口 温度补偿 无铅,符合RoHS规范 MSL 1反应时间:7.5ms 待机电流:0.1μA 无需外部时钟电路 ![](https://cf01.ickimg.com/bbsimages/202007/a447466668160833a104eecb0b56de4e.jpg) BMP180技术数据 压力范围300……1100 hPa 均方根噪声中表达压力0.06 hPa typ。(超低功耗模式) 0.02 hPa typ。(超高分辨率模式) 均方根噪声中表达高度0.5 m,typ。(超低功耗模式) 0.17米,typ。(超高分辨率模式) 相对精度的压力 VDD = 3.3 v 950……1050 hPa / hPa±0.12 @ 25°C / m±1.0 700年……900 hPa / hPa±0.12 25…40°C / m±1.0 绝对精度 p = 300…1100 hpa (温度= 0…+ 65°C,VDD = 3.3。-4.0 V)压力:……+ 2.0 hPa 温度:±1°C,typ。 平均电流消耗(1 Hz刷新率数据) 峰值电流3μA典型(超低功耗模式) 32μA,典型的(高级模式) 650μA,典型的 待机电流1.62……3.6 V 电源电压vddio 1.62……3.6 V 电源电压vdd 1.8……3.6 V 操作温度。 范围全面准确”40…+ 85°C 0…+ 65°C conv压力。5毫秒,典型的(标准模式) I2C传输速率3.4 MHz,马克斯。 ![](https://cf01.ickimg.com/bbsimages/202007/af9651eeb31134705203f492225e8d10.jpg) BMP180典型应用 GPS精准导航(航位推算,上下桥检测等) 室内室外导航 休闲、体育和医疗健康等监测 天气预报 垂直速度指示(上升/下沉速度) 风扇功率控制 体育设备,如高度剖面 ![](https://cf01.ickimg.com/bbsimages/202007/a8004ed9e70445968bc2b4225b406841.jpg) BMP180气压模块是一款高精度、小体积、低能耗的压力传感器,可以应用在移动设备中,它的性能卓越,绝对精度最低可以达到0.03hPa,并且耗电极低,只有3μA。BMP180采用强大的8-pin陶瓷无引线芯片承载(LCC)超薄封装,可以通过I2C总线直接与各种微处理器相连。 ![](https://cf01.ickimg.com/bbsimages/202007/6e9adc6ffbb3e0379cbe02c12bdc39ef.jpg) 特性曲线 ![](https://cf01.ickimg.com/bbsimages/202007/16e36a52be9c76567ac8f042d255fca2.jpg) 模块电原理图 ![](https://cf01.ickimg.com/bbsimages/202007/cf998ea369533453556675dbde3f2377.jpg) 需要用的 “SFE_BMP180” 库文件如下 SFE_BMP180.h ```c /@@* 【Arduino】168种传感器模块系列实验(67) 实验六十七:BMP180 新款 BOSCH温度模块气压传感器(代替BMP085) SFE_BMP180.h */ #ifndef SFE_BMP180_h #define SFE_BMP180_h #if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif class SFE_BMP180 { public: SFE_BMP180(); char begin(); shorted?) char startTemperature(void); char getTemperature(double &T); startTemperature command char startPressure(char oversampling); char getPressure(double &P, double &T); startPressure command double sealevel(double P, double A); weather data) double altitude(double P, double P0); sea-level, runway, etc.) char getError(void); private: char readInt(char address, int16_t &value); char readUInt(char address, uint16_t &value); char readBytes(unsigned char *values, char length); char writeBytes(unsigned char *values, char length); subsequent registers) int16_t AC1,AC2,AC3,VB1,VB2,MB,MC,MD; uint16_t AC4,AC5,AC6; double c5,c6,mc,md,x0,x1,x2,y0,y1,y2,p0,p1,p2; char _error; }; #define BMP180_ADDR 0x77 #define BMP180_REG_CONTROL 0xF4 #define BMP180_REG_RESULT 0xF6 #define BMP180_COMMAND_TEMPERATURE 0x2E #define BMP180_COMMAND_PRESSURE0 0x34 #define BMP180_COMMAND_PRESSURE1 0x74 #define BMP180_COMMAND_PRESSURE2 0xB4 #define BMP180_COMMAND_PRESSURE3 0xF4 ``` SFE_BMP180.cp ```c /@@* 【Arduino】168种传感器模块系列实验(67) 实验六十七:BMP180 新款 BOSCH温度模块气压传感器(代替BMP085) SFE_BMP180.cp */ #include
#include
#include
#include
SFE_BMP180::SFE_BMP180() { } char SFE_BMP180::begin() { double c3,c4,b1; Wire.begin(); if (readInt(0xAA,AC1) && readInt(0xAC,AC2) && readInt(0xAE,AC3) && readUInt(0xB0,AC4) && readUInt(0xB2,AC5) && readUInt(0xB4,AC6) && readInt(0xB6,VB1) && readInt(0xB8,VB2) && readInt(0xBA,MB) && readInt(0xBC,MC) && readInt(0xBE,MD)) { AC6 = 23153; Calcs.pdf 25671; AC6 = 18974; c3 = 160.0 * pow(2,-15) * AC3; c4 = pow(10,-3) * pow(2,-15) * AC4; b1 = pow(160,2) * pow(2,-30) * VB1; c5 = (pow(2,-15) / 160) * AC5; c6 = AC6; mc = (pow(2,11) / pow(160,2)) * MC; md = MD / 160.0; x0 = AC1; x1 = 160.0 * pow(2,-13) * AC2; x2 = pow(160,2) * pow(2,-25) * VB2; y0 = c4 * pow(2,15); y1 = c4 * c3; y2 = c4 * b1; p0 = (3791.0 - 8.0) / 1600.0; p1 = 1.0 - 7357.0 * pow(2,-20); p2 = 3038.0 * 100.0 * pow(2,-36); return(1); } else { return(0); } } char SFE_BMP180::readInt(char address, int16_t &value) { unsigned char data[2]; data[0] = address; if (readBytes(data,2)) { value = (int16_t)((data[0]<<8)|data[1]); negative return(1); } value = 0; return(0); } char SFE_BMP180::readUInt(char address, uint16_t &value) { unsigned char data[2]; data[0] = address; if (readBytes(data,2)) { value = (((uint16_t)data[0]<<8)|(uint16_t)data[1]); return(1); } value = 0; return(0); } char SFE_BMP180::readBytes(unsigned char *values, char length) { char x; Wire.beginTransmission(BMP180_ADDR); Wire.write(values[0]); _error = Wire.endTransmission(); if (_error == 0) { Wire.requestFrom(BMP180_ADDR,length); while(Wire.available() != length) ; for(x=0;x
SFE_BMP180 AirPresure; char presureDelayTime; double presureP, presureT; void setup() { Serial.begin(9600); AirPresure.begin(); } void loop() { presureDelayTime = AirPresure.startPressure(3); if (presureDelayTime != 0) { delay(presureDelayTime); presureDelayTime = AirPresure.getPressure(presureP, presureT); if (presureDelayTime != 0) { Serial.print("Current Preasure: "); Serial.print(presureP); Serial.println(" bar"); Serial.print(presureP); Serial.print(" bar is"); Serial.print(presureP / 1000.0); Serial.println(" atm"); } else { Serial.println("ERROR"); } } else { Serial.println("ERROR"); } delay(1000); } ``` ![](https://cf01.ickimg.com/bbsimages/202007/f11caf0d7867071c4775fd0fcce55a83.jpg) ```c /@@* 【Arduino】168种传感器模块系列实验(67) 实验六十七:BMP180 新款 BOSCH温度模块气压传感器(代替BMP085) 程序之二,气温、气压与海拔值可以调整并校准 */ #include
#define BMP180ADD 0x77 unsigned char OSS; int ac1; int ac2; int ac3; unsigned int ac4; unsigned int ac5; unsigned int ac6; int b1; int b2; int mb; int mc; int md; float temperature; double pressure; double pressure2; long b5; double altitude; void setup() { Serial.begin(9600); Wire.begin(); OSS = 2; BMP180start(); } void loop() { calculate(); show(); delay(1000); } void calculate() { temperature = bmp180GetTemperature(bmp180ReadUT()); temperature = temperature*0.0137; pressure = bmp180GetPressure(bmp180ReadUP()); pressure2 = pressure/115325; pressure2 = pow(pressure2,0.29029496); altitude = 39*(1+pressure2); } void show() { Serial.print("气温: "); Serial.print(temperature, 1); Serial.println(" C"); Serial.print("气压: "); Serial.print(pressure, 0); Serial.println(" Pa"); Serial.print("海拔:"); Serial.print(altitude); Serial.println("m"); } void BMP180start() { ac1 = bmp180ReadDate(0xAA); ac2 = bmp180ReadDate(0xAC); ac3 = bmp180ReadDate(0xAE); ac4 = bmp180ReadDate(0xB0); ac5 = bmp180ReadDate(0xB2); ac6 = bmp180ReadDate(0xB4); b1 = bmp180ReadDate(0xB6); b2 = bmp180ReadDate(0xB8); mb = bmp180ReadDate(0xBA); mc = bmp180ReadDate(0xBC); md = bmp180ReadDate(0xBE); } short bmp180GetTemperature(unsigned int ut) { long x1, x2; x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15; x2 = ((long)mc << 11)/(x1 + md); b5 = x1 + x2; return ((b5 + 8)>>4); } long bmp180GetPressure(unsigned long up) { long x1, x2, x3, b3, b6, p; unsigned long b4, b7; b6 = b5 - 4000; x1 = (b2 * (b6 * b6)>>12)>>11; x2 = (ac2 * b6)>>11; x3 = x1 + x2; b3 = (((((long)ac1)*4 + x3)<
>2; x1 = (ac3 * b6)>>13; x2 = (b1 * ((b6 * b6)>>12))>>16; x3 = ((x1 + x2) + 2)>>2; b4 = (ac4 * (unsigned long)(x3 + 32768))>>15; b7 = ((unsigned long)(up - b3) * (50000>>OSS)); if (b7 < 0x80000000) p = (b7<<1)/b4; else p = (b7/b4)<<1; x1 = (p>>8) * (p>>8); x1 = (x1 * 3038)>>16; x2 = (-7357 * p)>>16; p += (x1 + x2 + 3791)>>4; return p; } int bmp180Read(unsigned char address) { unsigned char data; Wire.beginTransmission(BMP180ADD); Wire.write(address); Wire.endTransmission(); Wire.requestFrom(BMP180ADD, 1); while(!Wire.available()); return Wire.read(); } int bmp180ReadDate(unsigned char address) { unsigned char msb, lsb; Wire.beginTransmission(BMP180ADD); Wire.write(address); Wire.endTransmission(); Wire.requestFrom(BMP180ADD, 2); while(Wire.available()<2); msb = Wire.read(); lsb = Wire.read(); return (int) msb<<8 | lsb; } unsigned int bmp180ReadUT() { unsigned int ut; Wire.beginTransmission(BMP180ADD); Wire.write(0xF4); Wire.write(0x2E); Wire.endTransmission(); delay(5); ut = bmp180ReadDate(0xF6); return ut; } unsigned long bmp180ReadUP() { unsigned char msb, lsb, xlsb; unsigned long up = 0; Wire.beginTransmission(BMP180ADD); Wire.write(0xF4); Wire.write(0x34 + (OSS<<6)); Wire.endTransmission(); delay(2 + (3<
> (8-OSS);//16 to 19 bit return up; } ``` ![](https://cf01.ickimg.com/bbsimages/202007/3fc992e3d618e4c645436837c6a7400d.jpg) ```c /@@* 【Arduino】168种传感器模块系列实验(67) 实验六十七:BMP180 新款 BOSCH温度模块气压传感器(代替BMP085) 程序之三,温度、实时气压、已知海拔计算的海平面的气压、已知海平面气压计算的高度 只是算法有点烂,做做实验而已 */ #include
#include
SFE_BMP180 pressure; #define ALTITUDE 255.0 unsigned long gpstimes; void setup() { Serial.begin(9600); pressure.begin(); } void loop() { gpstimes=millis(); char status; double T,P,p0,a; status = pressure.startTemperature(); delay(status); status = pressure.getTemperature(T); delay(status); Serial.print("temperature: "); Serial.print(T,2); Serial.println(" deg C, "); status = pressure.startPressure(3); delay(status); status = pressure.getPressure(P,T); // Print out the measurement: Serial.print("absolute pressure A: "); Serial.print(P,2); Serial.println(" mb, "); p0=1013.2; a = pressure.altitude(P,p0); Serial.print("computed altitude A: "); Serial.print(a,0); Serial.println(" meters, "); T=25.00; status = pressure.getPressure(P,T); Serial.print("absolute pressure B: "); Serial.print(P,2); Serial.println(" mb, "); p0=1013.2; a = pressure.altitude(P,p0); Serial.print("computed altitude B: "); Serial.print(a,0); Serial.println(" meters, "); gpstimes=millis()-gpstimes; Serial.print("gpstimes="); Serial.println(gpstimes); Serial.println(); delay(2000); } ``` ![](https://cf01.ickimg.com/bbsimages/202007/7a1e8c2a991d9df4ace5102986c0be02.jpg)
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
雕爷学编程
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交