用户工具

站点工具


ocrobot:sensor_suite:bmp180:main

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
ocrobot:sensor_suite:bmp180:main [2019/12/23 03:24] – [代码] 董凯萍ocrobot:sensor_suite:bmp180:main [2023/06/07 04:23] (当前版本) – 外部编辑 127.0.0.1
行 1: 行 1:
 +====== 大气压强测量仪 ======
 +OCROBOT 大气压强测量仪采用OCROBOT ALPHA系列模块堆叠而成。
 +本模型采用高精度、超低能耗的BMP180压力传感器,可以实时测量当前位置的大气压强。
  
 +  * 测量压力范围:300 - 1100hPa
 +  * 低功耗模式精度:0.06hPa(0.5m)
 +  * 高精度模式精度:0.02hPa(0.17m)
 +
 +=====图片展示=====
 +{{:ocrobot:sensor_suite:bmp180:气压计435.png?400|}}
 +=====主要硬件=====
 +  - OCROBOT ALPHA 8F32P-U主控板
 +  - OCROBOT ALPHA BMP180 大气压传感器模块
 +  - OCROBOT ALPHA LCD1602显示屏
 +  - OCROBOT ALPHA 双路锂电池扩展板
 +==== 代码 ====
 +<code cpp>
 +/*
 +  从BMP180传感器读取温度与气压数据。
 +  通过Serial.print命令以9600波特率发送至串口监视器。
 + */
 +#include <LiquidCrystal_I2C.h> 
 +#include <Wire.h>
 +#define BMP180_ADDRESS 0x77  // BMP180的I2C地址
 +const unsigned char OSS = 0;  // 采样设置
 +LiquidCrystal_I2C lcd(0x20, 16, 2);
 +// 校准值
 +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;
 + 
 +// b5用于计算bmp180GetTemperature(...),它也同时用于bmp180GetPressure(...)
 +// 所以Temperature(...)必须在Pressure(...)之前声明
 + 
 +long b5; 
 +short temperature;
 +long pressure;
 + 
 +void setup()
 +{lcd.init();                   //初始化屏幕
 +  lcd.backlight();
 +  //Serial.begin(9600);
 +  Wire.begin();
 +  bmp180Calibration();
 +}
 + 
 +void loop()
 +{
 +  temperature = bmp180GetTemperature(bmp180ReadUT());
 +  pressure = bmp180GetPressure(bmp180ReadUP());
 +  lcd.clear();
 +  lcd.setCursor(0, 0);
 +  lcd.print("Temp: ");
 +  lcd.setCursor(6, 0);
 +  lcd.print(temperature, DEC);
 +  lcd.println(" C");
 +  lcd.setCursor(0, 1);
 +  lcd.print("Pressure: ");
 +  lcd.setCursor(5, 1);
 +  lcd.print(pressure, DEC);
 +  lcd.println(" Pa");
 +
 +  delay(1000);
 +}
 + 
 +// 存储所有的BMP180的校准值到全局变量
 +// 校准值用来计算温度与气压
 +// 这个函数应该放在程序的开头
 + 
 +void bmp180Calibration()
 +{
 +  ac1 = bmp180ReadInt(0xAA);
 +  ac2 = bmp180ReadInt(0xAC);
 +  ac3 = bmp180ReadInt(0xAE);
 +  ac4 = bmp180ReadInt(0xB0);
 +  ac5 = bmp180ReadInt(0xB2);
 +  ac6 = bmp180ReadInt(0xB4);
 +  b1 = bmp180ReadInt(0xB6);
 +  b2 = bmp180ReadInt(0xB8);
 +  mb = bmp180ReadInt(0xBA);
 +  mc = bmp180ReadInt(0xBC);
 +  md = bmp180ReadInt(0xBE);
 +}
 + 
 +// 计算温度赋值给变量ut
 +// 返回值的精度在0.1摄氏度
 + 
 +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);  
 +}
 + 
 +// 计算压力
 +// 校准值必须是已知的
 +// B5在bmp180GetTemperature(...)需要使用,所以必须先调用。
 +// 返回值以Pa为单位
 + 
 +long bmp180GetPressure(unsigned long up)
 + 
 +{
 +  long x1, x2, x3, b3, b6, p;
 +  unsigned long b4, b7;
 +  b6 = b5 - 4000;
 +  // 计算B3
 +  x1 = (b2 * (b6 * b6)>>12)>>11;
 +  x2 = (ac2 * b6)>>11;
 +  x3 = x1 + x2;
 +  b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
 +  // 计算B4
 +  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;
 +}
 + 
 +// 在BMP180的'address'中读取一个字节
 +char bmp180Read(unsigned char address)
 +{
 +  unsigned char data;
 +  Wire.beginTransmission(BMP180_ADDRESS);
 +  Wire.write(address);
 +  Wire.endTransmission();
 +  Wire.requestFrom(BMP180_ADDRESS, 1);
 +  while(!Wire.available())  ;
 +  return Wire.read();
 +}
 +// 从BMP180读取两个字节
 +// 第一个字节是从'address'
 +// 第二个字节是从'address'+1
 +int bmp180ReadInt(unsigned char address)
 +{
 +  unsigned char msb, lsb;
 +  Wire.beginTransmission(BMP180_ADDRESS);
 +  Wire.write(address);
 +  Wire.endTransmission();
 +  Wire.requestFrom(BMP180_ADDRESS, 2);
 +  while(Wire.available()<2);
 +  msb = Wire.read();
 +  lsb = Wire.read();
 +  return (int) msb<<8 | lsb;
 +}
 + 
 +// 读取未补偿的温度值
 +unsigned int bmp180ReadUT()
 + 
 +{
 +  unsigned int ut;
 +  // 在寄存器0xF4写入0x2E
 +  // 这个用来请求进行温度读取
 +  Wire.beginTransmission(BMP180_ADDRESS);
 + 
 +  Wire.write(0xF4);
 + 
 +  Wire.write(0x2E);
 +  Wire.endTransmission();
 +  // 至少等待4.5ms
 +  delay(5);
 +  // 从寄存器0xF6与0xF7读取两个字节
 +  ut = bmp180ReadInt(0xF6);
 +  return ut;
 +}
 + 
 +// 读取未补偿的压力值
 +unsigned long bmp180ReadUP()
 +{
 +  unsigned char msb, lsb, xlsb;
 +  unsigned long up = 0;
 +  // 写入0x34+(OSS<<6)到寄存器0xF4
 +  // 请求气压数据读取
 +  Wire.beginTransmission(BMP180_ADDRESS);
 +  Wire.write(0xF4);
 +  Wire.write(0x34 + (OSS<<6));
 +  Wire.endTransmission();
 +  // 等待转换,延迟时间依赖于OSS
 +  delay(2 + (3<<OSS));
 +  // 读取寄存器0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
 +  Wire.beginTransmission(BMP180_ADDRESS);
 +  Wire.write(0xF6);
 +  Wire.endTransmission();
 +  Wire.requestFrom(BMP180_ADDRESS, 3);
 +  // 等待数据变为可用
 +  while(Wire.available() < 3);
 +  msb = Wire.read();
 +  lsb = Wire.read();
 +  xlsb = Wire.read();
 +  up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
 +  return up;
 +}
 +</code>
ocrobot/sensor_suite/bmp180/main.txt · 最后更改: 2023/06/07 04:23 由 127.0.0.1