原创 【雕爷学编程】Arduino动手做(67)---BMP180气压传感器

2020-7-3 14:51 459 1 1 分类: MCU/ 嵌入式 文集: 雕爷学编程

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来---小小的进步或是搞不掂的问题,希望能够抛砖引玉。

【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)实验六十七: GY-68 BMP180 新款 BOSCH温度模块气压传感器(替代BMP085)

BMP180

是博世Sensortec的新数字气压传感器,具有很高的性能,使应用先进的移动设备,如智能手机、平板电脑和体育设备。它遵循了BMP085带来了很多改进,像小尺寸和数字接口的扩张。超低功耗降至3μA使BMP180节电为您的移动设备的领导者。BMP180也是杰出的非常稳定的性能,最好有独立电源供电。BMP180是一款高精度、小体积、超低能耗的压力传感器,可以应用在移动设备中它的性能卓越,绝对精度最低可以达到0.03hPa,并且耗电极低,只有3μA。BMP180采用强大的8-pin陶瓷无引线芯片承载(LCC)超薄封装,可以通过I2C总线直接与各种微处理器相连。


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

无需外部时钟电路

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,马克斯。

BMP180典型应用

GPS精准导航(航位推算,上下桥检测等)

室内室外导航

休闲、体育和医疗健康等监测

天气预报

垂直速度指示(上升/下沉速度)

风扇功率控制

体育设备,如高度剖面

BMP180气压模块是一款高精度、小体积、低能耗的压力传感器,可以应用在移动设备中,它的性能卓越,绝对精度最低可以达到0.03hPa,并且耗电极低,只有3μA。BMP180采用强大的8-pin陶瓷无引线芯片承载(LCC)超薄封装,可以通过I2C总线直接与各种微处理器相连。

特性曲线

模块电原理图

需要用的 “SFE_BMP180” 库文件如下

SFE_BMP180.h

  1. /*
  2. 【Arduino】66种传感器模块系列实验(68)
  3. 实验六十八:BMP180 新款 BOSCH温度模块气压传感器(代替BMP085)
  4. SFE_BMP180.h
  5. */
  6. #ifndef SFE_BMP180_h
  7. #define SFE_BMP180_h
  8. #if defined(ARDUINO) && ARDUINO >= 100
  9. #include "Arduino.h"
  10. #else
  11. #include "WProgram.h"
  12. #endif
  13. class SFE_BMP180
  14. {
  15. public:
  16. SFE_BMP180();
  17. char begin();
  18. shorted?)
  19. char startTemperature(void);
  20. char getTemperature(double &T);
  21. startTemperature command
  22. char startPressure(char oversampling);
  23. char getPressure(double &P, double &T);
  24. startPressure command
  25. double sealevel(double P, double A);
  26. weather data)
  27. double altitude(double P, double P0);
  28. sea-level, runway, etc.)
  29. char getError(void);
  30. private:
  31. char readInt(char address, int16_t &value);
  32. char readUInt(char address, uint16_t &value);
  33. char readBytes(unsigned char *values, char length);
  34. char writeBytes(unsigned char *values, char length);
  35. subsequent registers)
  36. int16_t AC1,AC2,AC3,VB1,VB2,MB,MC,MD;
  37. uint16_t AC4,AC5,AC6;
  38. double c5,c6,mc,md,x0,x1,x2,y0,y1,y2,p0,p1,p2;
  39. char _error;
  40. };
  41. #define BMP180_ADDR 0x77
  42. #define BMP180_REG_CONTROL 0xF4
  43. #define BMP180_REG_RESULT 0xF6
  44. #define BMP180_COMMAND_TEMPERATURE 0x2E
  45. #define BMP180_COMMAND_PRESSURE0 0x34
  46. #define BMP180_COMMAND_PRESSURE1 0x74
  47. #define BMP180_COMMAND_PRESSURE2 0xB4
  48. #define BMP180_COMMAND_PRESSURE3 0xF4



SFE_BMP180.cp


  1. /*
  2. 【Arduino】66种传感器模块系列实验(68)
  3. 实验六十八:BMP180 新款 BOSCH温度模块气压传感器(代替BMP085)
  4. SFE_BMP180.cp
  5. */
  6. #include <SFE_BMP180.h>
  7. #include <Wire.h>
  8. #include <stdio.h>
  9. #include <math.h>
  10. SFE_BMP180::SFE_BMP180()
  11. {
  12. }
  13. char SFE_BMP180::begin()
  14. {
  15. double c3,c4,b1;
  16. Wire.begin();
  17. if (readInt(0xAA,AC1) &&
  18. readInt(0xAC,AC2) &&
  19. readInt(0xAE,AC3) &&
  20. readUInt(0xB0,AC4) &&
  21. readUInt(0xB2,AC5) &&
  22. readUInt(0xB4,AC6) &&
  23. readInt(0xB6,VB1) &&
  24. readInt(0xB8,VB2) &&
  25. readInt(0xBA,MB) &&
  26. readInt(0xBC,MC) &&
  27. readInt(0xBE,MD))
  28. {
  29. AC6 = 23153;
  30. Calcs.pdf
  31. 25671; AC6 = 18974;
  32. c3 = 160.0 * pow(2,-15) * AC3;
  33. c4 = pow(10,-3) * pow(2,-15) * AC4;
  34. b1 = pow(160,2) * pow(2,-30) * VB1;
  35. c5 = (pow(2,-15) / 160) * AC5;
  36. c6 = AC6;
  37. mc = (pow(2,11) / pow(160,2)) * MC;
  38. md = MD / 160.0;
  39. x0 = AC1;
  40. x1 = 160.0 * pow(2,-13) * AC2;
  41. x2 = pow(160,2) * pow(2,-25) * VB2;
  42. y0 = c4 * pow(2,15);
  43. y1 = c4 * c3;
  44. y2 = c4 * b1;
  45. p0 = (3791.0 - 8.0) / 1600.0;
  46. p1 = 1.0 - 7357.0 * pow(2,-20);
  47. p2 = 3038.0 * 100.0 * pow(2,-36);
  48. return(1);
  49. }
  50. else
  51. {
  52. return(0);
  53. }
  54. }
  55. char SFE_BMP180::readInt(char address, int16_t &value)
  56. {
  57. unsigned char data[2];
  58. data[0] = address;
  59. if (readBytes(data,2))
  60. {
  61. value = (int16_t)((data[0]<<8)|data[1]);
  62. negative
  63. return(1);
  64. }
  65. value = 0;
  66. return(0);
  67. }
  68. char SFE_BMP180::readUInt(char address, uint16_t &value)
  69. {
  70. unsigned char data[2];
  71. data[0] = address;
  72. if (readBytes(data,2))
  73. {
  74. value = (((uint16_t)data[0]<<8)|(uint16_t)data[1]);
  75. return(1);
  76. }
  77. value = 0;
  78. return(0);
  79. }
  80. char SFE_BMP180::readBytes(unsigned char *values, char length)
  81. {
  82. char x;
  83. Wire.beginTransmission(BMP180_ADDR);
  84. Wire.write(values[0]);
  85. _error = Wire.endTransmission();
  86. if (_error == 0)
  87. {
  88. Wire.requestFrom(BMP180_ADDR,length);
  89. while(Wire.available() != length) ;
  90. for(x=0;x<length;x++)
  91. {
  92. values[x] = Wire.read();
  93. }
  94. return(1);
  95. }
  96. return(0);
  97. }
  98. char SFE_BMP180::writeBytes(unsigned char *values, char length)
  99. {
  100. char x;
  101. Wire.beginTransmission(BMP180_ADDR);
  102. Wire.write(values,length);
  103. _error = Wire.endTransmission();
  104. if (_error == 0)
  105. return(1);
  106. else
  107. return(0);
  108. }
  109. char SFE_BMP180::startTemperature(void)
  110. {
  111. unsigned char data[2], result;
  112. data[0] = BMP180_REG_CONTROL;
  113. data[1] = BMP180_COMMAND_TEMPERATURE;
  114. result = writeBytes(data, 2);
  115. if (result)
  116. return(5);
  117. else
  118. return(0);
  119. }
  120. char SFE_BMP180::getTemperature(double &T)
  121. {
  122. unsigned char data[2];
  123. char result;
  124. double tu, a;
  125. data[0] = BMP180_REG_RESULT;
  126. result = readBytes(data, 2);
  127. if (result)
  128. {
  129. tu = (data[0] * 256.0) + data[1];
  130. a = c5 * (tu - c6);
  131. T = a + (mc / (a + md));
  132. }
  133. return(result);
  134. }
  135. char SFE_BMP180::startPressure(char oversampling)
  136. {
  137. unsigned char data[2], result, delay;
  138. data[0] = BMP180_REG_CONTROL;
  139. switch (oversampling)
  140. {
  141. case 0:
  142. data[1] = BMP180_COMMAND_PRESSURE0;
  143. delay = 5;
  144. break;
  145. case 1:
  146. data[1] = BMP180_COMMAND_PRESSURE1;
  147. delay = 8;
  148. break;
  149. case 2:
  150. data[1] = BMP180_COMMAND_PRESSURE2;
  151. delay = 14;
  152. break;
  153. case 3:
  154. data[1] = BMP180_COMMAND_PRESSURE3;
  155. delay = 26;
  156. break;
  157. default:
  158. data[1] = BMP180_COMMAND_PRESSURE0;
  159. delay = 5;
  160. break;
  161. }
  162. result = writeBytes(data, 2);
  163. if (result)
  164. return(delay);
  165. else
  166. return(0);
  167. }
  168. char SFE_BMP180::getPressure(double &P, double &T)
  169. sealevel().
  170. {
  171. unsigned char data[3];
  172. char result;
  173. double pu,s,x,y,z;
  174. data[0] = BMP180_REG_RESULT;
  175. result = readBytes(data, 3);
  176. if (result)
  177. {
  178. pu = (data[0] * 256.0) + data[1] + (data[2]/256.0);
  179. s = T - 25.0;
  180. x = (x2 * pow(s,2)) + (x1 * s) + x0;
  181. y = (y2 * pow(s,2)) + (y1 * s) + y0;
  182. z = (pu - x) / y;
  183. P = (p2 * pow(z,2)) + (p1 * z) + p0;
  184. }
  185. return(result);
  186. }
  187. double SFE_BMP180::sealevel(double P, double A)
  188. {
  189. return(P/pow(1-(A/44330.0),5.255));
  190. }
  191. double SFE_BMP180::altitude(double P, double P0)
  192. {
  193. return(44330.0*(1-pow(P/P0,1/5.255)));
  194. }
  195. char SFE_BMP180::getError(void)
  196. {
  197. return(_error);
  198. }



模块接线方式

1.先连接芯片与单片机(通过I2C接口),按照如下方式连接

5V—VIN

GND–GND

A5—SCL

A4—SDA

2.然后UNO通过usb与PC电脑连接

3.拷贝后面的代码烧录进Arduino


实验开源代码


  1. /*
  2. 【Arduino】168种传感器模块系列实验(67)
  3. 实验六十七:BMP180 新款 BOSCH温度模块气压传感器(代替BMP085)
  4. 程序之一
  5. */
  6. #include <SFE_BMP180.h>
  7. SFE_BMP180 AirPresure;
  8. char presureDelayTime;
  9. double presureP, presureT;
  10. void setup() {
  11. Serial.begin(9600);
  12. AirPresure.begin();
  13. }
  14. void loop()
  15. {
  16. presureDelayTime = AirPresure.startPressure(3);
  17. if (presureDelayTime != 0)
  18. {
  19. delay(presureDelayTime);
  20. presureDelayTime = AirPresure.getPressure(presureP, presureT);
  21. if (presureDelayTime != 0)
  22. {
  23. Serial.print("Current Preasure: ");
  24. Serial.print(presureP);
  25. Serial.println(" bar");
  26. Serial.print(presureP);
  27. Serial.print(" bar is");
  28. Serial.print(presureP / 1000.0);
  29. Serial.println(" atm");
  30. }
  31. else
  32. {
  33. Serial.println("ERROR");
  34. }
  35. }
  36. else
  37. {
  38. Serial.println("ERROR");
  39. }
  40. delay(1000);
  41. }



  1. /*
  2. 【Arduino】168种传感器模块系列实验(67)
  3. 实验六十七:BMP180 新款 BOSCH温度模块气压传感器(代替BMP085)
  4. 程序之二,气温、气压与海拔值可以调整并校准
  5. */
  6. #include <Wire.h>
  7. #define BMP180ADD 0x77
  8. unsigned char OSS;
  9. int ac1;
  10. int ac2;
  11. int ac3;
  12. unsigned int ac4;
  13. unsigned int ac5;
  14. unsigned int ac6;
  15. int b1;
  16. int b2;
  17. int mb;
  18. int mc;
  19. int md;
  20. float temperature;
  21. double pressure;
  22. double pressure2;
  23. long b5;
  24. double altitude;
  25. void setup()
  26. {
  27. Serial.begin(9600);
  28. Wire.begin();
  29. OSS = 2;
  30. BMP180start();
  31. }
  32. void loop()
  33. {
  34. calculate();
  35. show();
  36. delay(1000);
  37. }
  38. void calculate()
  39. {
  40. temperature = bmp180GetTemperature(bmp180ReadUT());
  41. temperature = temperature*0.0137;
  42. pressure = bmp180GetPressure(bmp180ReadUP());
  43. pressure2 = pressure/115325;
  44. pressure2 = pow(pressure2,0.29029496);
  45. altitude = 39*(1+pressure2);
  46. }
  47. void show()
  48. {
  49. Serial.print("气温: ");
  50. Serial.print(temperature, 1);
  51. Serial.println(" C");
  52. Serial.print("气压: ");
  53. Serial.print(pressure, 0);
  54. Serial.println(" Pa");
  55. Serial.print("海拔:");
  56. Serial.print(altitude);
  57. Serial.println("m");
  58. }
  59. void BMP180start()
  60. {
  61. ac1 = bmp180ReadDate(0xAA);
  62. ac2 = bmp180ReadDate(0xAC);
  63. ac3 = bmp180ReadDate(0xAE);
  64. ac4 = bmp180ReadDate(0xB0);
  65. ac5 = bmp180ReadDate(0xB2);
  66. ac6 = bmp180ReadDate(0xB4);
  67. b1 = bmp180ReadDate(0xB6);
  68. b2 = bmp180ReadDate(0xB8);
  69. mb = bmp180ReadDate(0xBA);
  70. mc = bmp180ReadDate(0xBC);
  71. md = bmp180ReadDate(0xBE);
  72. }
  73. short bmp180GetTemperature(unsigned int ut)
  74. {
  75. long x1, x2;
  76. x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
  77. x2 = ((long)mc << 11)/(x1 + md);
  78. b5 = x1 + x2;
  79. return ((b5 + 8)>>4);
  80. }
  81. long bmp180GetPressure(unsigned long up)
  82. {
  83. long x1, x2, x3, b3, b6, p;
  84. unsigned long b4, b7;
  85. b6 = b5 - 4000;
  86. x1 = (b2 * (b6 * b6)>>12)>>11;
  87. x2 = (ac2 * b6)>>11;
  88. x3 = x1 + x2;
  89. b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
  90. x1 = (ac3 * b6)>>13;
  91. x2 = (b1 * ((b6 * b6)>>12))>>16;
  92. x3 = ((x1 + x2) + 2)>>2;
  93. b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
  94. b7 = ((unsigned long)(up - b3) * (50000>>OSS));
  95. if (b7 < 0x80000000)
  96. p = (b7<<1)/b4;
  97. else
  98. p = (b7/b4)<<1;
  99. x1 = (p>>8) * (p>>8);
  100. x1 = (x1 * 3038)>>16;
  101. x2 = (-7357 * p)>>16;
  102. p += (x1 + x2 + 3791)>>4;
  103. return p;
  104. }
  105. int bmp180Read(unsigned char address)
  106. {
  107. unsigned char data;
  108. Wire.beginTransmission(BMP180ADD);
  109. Wire.write(address);
  110. Wire.endTransmission();
  111. Wire.requestFrom(BMP180ADD, 1);
  112. while(!Wire.available());
  113. return Wire.read();
  114. }
  115. int bmp180ReadDate(unsigned char address)
  116. {
  117. unsigned char msb, lsb;
  118. Wire.beginTransmission(BMP180ADD);
  119. Wire.write(address);
  120. Wire.endTransmission();
  121. Wire.requestFrom(BMP180ADD, 2);
  122. while(Wire.available()<2);
  123. msb = Wire.read();
  124. lsb = Wire.read();
  125. return (int) msb<<8 | lsb;
  126. }
  127. unsigned int bmp180ReadUT()
  128. {
  129. unsigned int ut;
  130. Wire.beginTransmission(BMP180ADD);
  131. Wire.write(0xF4);
  132. Wire.write(0x2E);
  133. Wire.endTransmission();
  134. delay(5);
  135. ut = bmp180ReadDate(0xF6);
  136. return ut;
  137. }
  138. unsigned long bmp180ReadUP()
  139. {
  140. unsigned char msb, lsb, xlsb;
  141. unsigned long up = 0;
  142. Wire.beginTransmission(BMP180ADD);
  143. Wire.write(0xF4);
  144. Wire.write(0x34 + (OSS<<6));
  145. Wire.endTransmission();
  146. delay(2 + (3<<OSS));
  147. Wire.beginTransmission(BMP180ADD);
  148. Wire.write(0xF6);
  149. Wire.endTransmission();
  150. Wire.requestFrom(BMP180ADD, 3);
  151. while(Wire.available() < 3);
  152. msb = Wire.read();
  153. lsb = Wire.read();
  154. xlsb = Wire.read();
  155. up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);//16 to 19 bit
  156. return up;
  157. }




  1. /*
  2. 【Arduino】168种传感器模块系列实验(67)
  3. 实验六十七:BMP180 新款 BOSCH温度模块气压传感器(代替BMP085)
  4. 程序之三,温度、实时气压、已知海拔计算的海平面的气压、已知海平面气压计算的高度
  5. 只是算法有点烂,做做实验而已
  6. */
  7. #include <SFE_BMP180.h>
  8. #include <Wire.h>
  9. SFE_BMP180 pressure;
  10. #define ALTITUDE 255.0
  11. unsigned long gpstimes;
  12. void setup()
  13. {
  14. Serial.begin(9600);
  15. pressure.begin();
  16. }
  17. void loop()
  18. {
  19. gpstimes=millis();
  20. char status;
  21. double T,P,p0,a;
  22. status = pressure.startTemperature();
  23. delay(status);
  24. status = pressure.getTemperature(T);
  25. delay(status);
  26. Serial.print("temperature: ");
  27. Serial.print(T,2);
  28. Serial.println(" deg C, ");
  29. status = pressure.startPressure(3);
  30. delay(status);
  31. status = pressure.getPressure(P,T);
  32. // Print out the measurement:
  33. Serial.print("absolute pressure A: ");
  34. Serial.print(P,2);
  35. Serial.println(" mb, ");
  36. p0=1013.2;
  37. a = pressure.altitude(P,p0);
  38. Serial.print("computed altitude A: ");
  39. Serial.print(a,0);
  40. Serial.println(" meters, ");
  41. T=25.00;
  42. status = pressure.getPressure(P,T);
  43. Serial.print("absolute pressure B: ");
  44. Serial.print(P,2);
  45. Serial.println(" mb, ");
  46. p0=1013.2;
  47. a = pressure.altitude(P,p0);
  48. Serial.print("computed altitude B: ");
  49. Serial.print(a,0);
  50. Serial.println(" meters, ");
  51. gpstimes=millis()-gpstimes;
  52. Serial.print("gpstimes=");
  53. Serial.println(gpstimes);
  54. Serial.println();
  55. delay(2000);
  56. }

作者: 雕爷学编程, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-3894459.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

文章评论0条评论)

登录后参与讨论
相关推荐阅读
雕爷学编程 2020-06-17 13:14
【雕爷学编程】Arduino动手做(66)---SR501热释电红外模块
37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为...
雕爷学编程 2020-06-07 19:06
【雕爷学编程】Arduino动手做(65)---红外寻迹传感器
37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为...
雕爷学编程 2020-06-07 16:40
【雕爷学编程】MicroPython动手做(08)——零基础学MaixPy之识别颜色
早上用百度搜了一下“颜色识别”,多少有了一点大致的概念,还是老办法,动手做,多实验,往前走,还请各位老师多多指点。OpenCV(百度百科)是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行...
雕爷学编程 2020-05-20 13:00
【雕爷学编程】MicroPython动手做(07)——零基础学MaixPy之机器视觉
机器视觉 machine vision机器视觉是人工智能正在快速发展的一个分支。机器视觉作为生产过程中关键技术之一,在机器或者生产线上,机器视觉可以检测产品质量以便将不合格的产品剔除,或者指导机器人完...
雕爷学编程 2020-05-11 10:19
【雕爷学编程】MicroPython动手做(06)——零基础学MaixPy之单目摄像头
配套 OV2640摄像头:200W像素通用24P摄像头具有200万像素(1632x1232像素),其体积小、工作电压低,提供单片UXGA摄像和影像处理器的所有功能。通过SCCB总线控制,可以输出整帧、...
广告
EE直播间
更多
我要评论
0
1
广告
关闭 热点推荐上一条 /6 下一条