居家实验:为phyphox插上压强计的翅膀(一)
居家实验:为phyphox插上压强计的翅膀(一)
零. 背景说明
使用phyphox已经有一段时间了,它里面带了一个气压计实验,但是是灰色的,即使你点击它,它也只会提示这个实验不可用。据说有气压计的手机,要么是旗舰机,要么是商务机,据说华为Mate上面就有,可是P系列上面就没有。苹果不了解。一个封闭的系统以安全自居,但是可玩性、开放性和所带来的创造的热情与火花就差得远了。
phyphox团队队长塞巴斯蒂安(我记不住那人名字)好多个宣传视频里都有phyphox结合气压计的实验,这里使用常用常见的GY68-BMP180气压传感器在phyphox体外嫁接一个气压计——当然,研究BMP180并不是为了phyphox,而是打算琢磨一下热学实验。
这个记录,是没有规划的。写哪算哪,只是整理。整理的原因,一方面BMP180有好几款封装,而且有的已经不再受到官方支持,有的会在网上由微弱的力量支持着一些Arduino扩展库,甚至还能看到51的、STM32的扩展库——因为是开源的,所以用起来并不容易。这里整理的,都是我亲自试验过的,要保证它们能用。此外,看起来简单的东西,往往并不简单,整理下来,可备未来自己用,亦可为他人参照之。内容只两片,一为BMP180与国际压强方程的应用,另一为蓝牙BLE与phyphox通讯。
一. BMP180与国际压强方程
1.BMP180气压传感器
BMP180气压传感是最为常用常见的气压传感器,如图1。介绍它的文章特别多,挑几个重点列在这里:压强可测范围300hPa至1100hPa(hPa百帕),高度可测范围从海拔以下数百米至海拔9000米,分辨率可达0.03hPa(0.25米) 0.06hPa(0.5米),这和设置模型有关。
需特别注意的是,BMP180电源为3.3V,万不可将其与Arduino 5V相接,虽然有不少文章说可以接5V,说有稳压及电平转换云云,未免于电子市场之极大丰富尚缺乏想象。
BMP180有温度输出和温度补偿功能,这在价格平易使用方便的传感器里是不多见的。
图1 BMP180的常见封装
2.测量数据
先上测量数据。从最简单的场景开始。
BMP180与Arduino连接完毕,直接测量家里室内压强和温度(7楼):
BMP180直接放置在桌子上,压强1000.49hPa,温度26.01C。
举到一臂高处,大约上升0.5cm,压强显示1000.45hPa,温度显示26.02C。
放在桌子下方,位置下降大约1.0米,压强显示1000.62hPa,温度显示25.90C。
这确实灵敏得令人难以置信!!!
十分显然,我们可以猜测phyphox气压计实验的原理了。我们知道,国际压强方程为
其中h是海拔高度,P为当前位置大气压,为海平面大气压强,均以hPa为单位。那么,我们只要能够知道就能够让BMP180向我们汇报高度了,去哪里得到呢?当然最好的办法是到地面测量一下,另一个办法是到https://www.weatheronline.co.uk查询实时海平面气压图,如图2,这个网站有中文。
图2 海平面气压图
我整理这些文字时,我家里的气压已经变化了,大约1001.50hPa,如图3,于是
确实暴露了7楼的位置,比较符合实际。
图3 大气压强瞬息五变~~
但是这里面也有一些问题:
(1)一个是从气压分布图看,若北京海平面气压取1003hPa,那么得到的高度只有12米,这和BMP180强大的分辨率是不相符的;
(2)北京地区虽地处平原,但海拔也并非零米,大概是从地表面算起的。
(3)一个校准的方法,是把h替换成,这样从数据拟合里可以把提取出来。
3.接线图
这个小板需要自己焊排针,好在只有4根。然后按照以下的针脚对应。图省了。
BMP180> Arduino Uno
VIN > 3V3 #<------要超级小心,不能使用5V,还是要尊重DataSheet数据
GND > GND
SCL > A5
SDA > A4
4.实验图
图4 实验图
5.串口监视器
图5 串口监视器
6.计划研究
有的动了,有的还没动,有的可能已经没兴趣了。
(1)通过国际压强方程得到压强与海拔的正或逆的关系;
(2)嫁接到手机,完成著名的phyphox手机压强计电梯高度实验;
(3)可以尝试气体三定律实验,可简易完成PT关系
(4)实验测量阿伏伽德罗常数
7.技术补充
条目式列举如下。
(1)BMP180通讯方式是I2C,可以查看Arduino电路图知道它与BMP180的接线方法;
(2)部分BMP180是5针、甚至6针的,似乎是过时的产品,它们的支持库特别杂乱,且经 常与wire库冲突,尽量不用这些杂牌支持库;
(3)所有的支持库里最好的,是Sparkfun的开源支持库BMP180_Breakout_Arduino_Library;
(4)电源电压3.3V,没有保证的情况下,先别用5V。
(5)本例代码及解释,更详细的,请自行去阅读支持库源码。
#include <Wire.h>
#include <SFE_BMP180.h>
SFE_BMP180 bmp180;
void setup() {
Serial.begin(9600);
bool success = bmp180.begin();
if (success) {
Serial.println("BMP180 init success");
}
}
void loop() {
char status;
double T, P;
bool success = false;
status = bmp180.startTemperature();
if (status != 0) {
delay(1000);
status = bmp180.getTemperature(T);
if (status != 0) {
status = bmp180.startPressure(3);
if (status != 0) {
delay(status);
status = bmp180.getPressure(P, T);
if (status != 0) {
Serial.print("Pressure: ");
Serial.println(P);
Serial.println(" hPa");
Serial.print("Temperature: ");
Serial.print(T);
Serial.println(" C");
}
}
}
}
}
有了扩展库的支持,我们只需start和get去循环读数就可以了。