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 ALPHA 8F32P-U主控板 | ||
+ | - OCROBOT ALPHA BMP180 大气压传感器模块 | ||
+ | - OCROBOT ALPHA LCD1602显示屏 | ||
+ | - OCROBOT ALPHA 双路锂电池扩展板 | ||
+ | ==== 代码 ==== | ||
+ | <code cpp> | ||
+ | /* | ||
+ | 从BMP180传感器读取温度与气压数据。 | ||
+ | 通过Serial.print命令以9600波特率发送至串口监视器。 | ||
+ | */ | ||
+ | #include < | ||
+ | #include < | ||
+ | #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(); | ||
+ | // | ||
+ | Wire.begin(); | ||
+ | bmp180Calibration(); | ||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | temperature = bmp180GetTemperature(bmp180ReadUT()); | ||
+ | pressure = bmp180GetPressure(bmp180ReadUP()); | ||
+ | lcd.clear(); | ||
+ | lcd.setCursor(0, | ||
+ | lcd.print(" | ||
+ | lcd.setCursor(6, | ||
+ | lcd.print(temperature, | ||
+ | lcd.println(" | ||
+ | lcd.setCursor(0, | ||
+ | lcd.print(" | ||
+ | lcd.setCursor(5, | ||
+ | lcd.print(pressure, | ||
+ | lcd.println(" | ||
+ | |||
+ | 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)>> | ||
+ | } | ||
+ | |||
+ | // 计算压力 | ||
+ | // 校准值必须是已知的 | ||
+ | // 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)>> | ||
+ | x2 = (ac2 * b6)>> | ||
+ | x3 = x1 + x2; | ||
+ | b3 = (((((long)ac1)*4 + x3)<< | ||
+ | // 计算B4 | ||
+ | x1 = (ac3 * b6)>> | ||
+ | x2 = (b1 * ((b6 * b6)>> | ||
+ | x3 = ((x1 + x2) + 2)>> | ||
+ | b4 = (ac4 * (unsigned long)(x3 + 32768))>> | ||
+ | b7 = ((unsigned long)(up - b3) * (50000>> | ||
+ | if (b7 < 0x80000000) | ||
+ | p = (b7<< | ||
+ | else | ||
+ | p = (b7/ | ||
+ | x1 = (p>> | ||
+ | x1 = (x1 * 3038)>> | ||
+ | x2 = (-7357 * p)>> | ||
+ | p += (x1 + x2 + 3791)>> | ||
+ | return p; | ||
+ | } | ||
+ | |||
+ | // 在BMP180的' | ||
+ | char bmp180Read(unsigned char address) | ||
+ | { | ||
+ | unsigned char data; | ||
+ | Wire.beginTransmission(BMP180_ADDRESS); | ||
+ | Wire.write(address); | ||
+ | Wire.endTransmission(); | ||
+ | Wire.requestFrom(BMP180_ADDRESS, | ||
+ | while(!Wire.available()) | ||
+ | return Wire.read(); | ||
+ | } | ||
+ | // 从BMP180读取两个字节 | ||
+ | // 第一个字节是从' | ||
+ | // 第二个字节是从' | ||
+ | int bmp180ReadInt(unsigned char address) | ||
+ | { | ||
+ | unsigned char msb, lsb; | ||
+ | Wire.beginTransmission(BMP180_ADDRESS); | ||
+ | Wire.write(address); | ||
+ | Wire.endTransmission(); | ||
+ | Wire.requestFrom(BMP180_ADDRESS, | ||
+ | while(Wire.available()< | ||
+ | msb = Wire.read(); | ||
+ | lsb = Wire.read(); | ||
+ | return (int) msb<< | ||
+ | } | ||
+ | |||
+ | // 读取未补偿的温度值 | ||
+ | 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<< | ||
+ | // 请求气压数据读取 | ||
+ | Wire.beginTransmission(BMP180_ADDRESS); | ||
+ | Wire.write(0xF4); | ||
+ | Wire.write(0x34 + (OSS<< | ||
+ | Wire.endTransmission(); | ||
+ | // 等待转换,延迟时间依赖于OSS | ||
+ | delay(2 + (3<< | ||
+ | // 读取寄存器0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB) | ||
+ | Wire.beginTransmission(BMP180_ADDRESS); | ||
+ | Wire.write(0xF6); | ||
+ | Wire.endTransmission(); | ||
+ | Wire.requestFrom(BMP180_ADDRESS, | ||
+ | // 等待数据变为可用 | ||
+ | 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; | ||
+ | } | ||
+ | </ |