37款傳感器與執(zhí)行器的提法,在網(wǎng)絡(luò)上廣泛流傳,其實Arduino能夠兼容的傳感器模塊肯定是不止這37種的迹卢。鑒于本人手頭積累了一些傳感器和執(zhí)行器模塊,依照實踐出真知(一定要動手做)的理念徒仓,以學習和交流為目的腐碱,這里準備逐一動手嘗試系列實驗,不管成功(程序走通)與否掉弛,都會記錄下來---小小的進步或是搞不掂的問題症见,希望能夠拋磚引玉。
【Arduino】168種傳感器模塊系列實驗(資料+代碼+圖形+仿真)
實驗六十七: GY-68 BMP180 新款 BOSCH溫度模塊氣壓傳感器(替代BMP085)
BMP180
是博世Sensortec的新數(shù)字氣壓傳感器狰晚,具有很高的性能筒饰,使應(yīng)用先進的移動設(shè)備,如智能手機壁晒、平板電腦和體育設(shè)備瓷们。它遵循了BMP085帶來了很多改進,像小尺寸和數(shù)字接口的擴張秒咐。超低功耗降至3μA使BMP180節(jié)電為您的移動設(shè)備的領(lǐng)導者谬晕。BMP180也是杰出的非常穩(wěn)定的性能,最好有獨立電源供電携取。BMP180是一款高精度攒钳、小體積、超低能耗的壓力傳感器雷滋,可以應(yīng)用在移動設(shè)備中它的性能卓越不撑,絕對精度最低可以達到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規(guī)范
MSL 1反應(yīng)時間:7.5ms
待機電流:0.1μA
無需外部時鐘電路
BMP180技術(shù)數(shù)據(jù)
壓力范圍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刷新率數(shù)據(jù))
峰值電流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典型應(yīng)用
GPS精準導航(航位推算勉失,上下橋檢測等)
室內(nèi)室外導航
休閑羹蚣、體育和醫(yī)療健康等監(jiān)測
天氣預(yù)報
垂直速度指示(上升/下沉速度)
風扇功率控制
體育設(shè)備,如高度剖面
BMP180氣壓模塊是一款高精度乱凿、小體積顽素、低能耗的壓力傳感器,可以應(yīng)用在移動設(shè)備中徒蟆,它的性能卓越胁出,絕對精度最低可以達到0.03hPa,并且耗電極低段审,只有3μA全蝶。BMP180采用強大的8-pin陶瓷無引線芯片承載(LCC)超薄封裝,可以通過I2C總線直接與各種微處理器相連寺枉。
特性曲線
模塊電原理圖
需要用的 “SFE_BMP180” 庫文件如下
SFE_BMP180.h
/*
【Arduino】66種傳感器模塊系列實驗(68)
實驗六十八: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
/*
【Arduino】66種傳感器模塊系列實驗(68)
實驗六十八:BMP180 新款 BOSCH溫度模塊氣壓傳感器(代替BMP085)
SFE_BMP180.cp
*/
#include <SFE_BMP180.h>
#include <Wire.h>
#include <stdio.h>
#include <math.h>
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<length;x++)
? ?? ???{
? ?? ?? ?? ?values[x] = Wire.read();
? ?? ???}
? ?? ???return(1);
? ? }
? ? return(0);
}
char SFE_BMP180::writeBytes(unsigned char *values, char length)
{
? ? char x;
? ? Wire.beginTransmission(BMP180_ADDR);
? ? Wire.write(values,length);
? ? _error = Wire.endTransmission();
? ? if (_error == 0)
? ?? ???return(1);
? ? else
? ?? ???return(0);
}
char SFE_BMP180::startTemperature(void)
{
? ? unsigned char data[2], result;
? ? data[0] = BMP180_REG_CONTROL;
? ? data[1] = BMP180_COMMAND_TEMPERATURE;
? ? result = writeBytes(data, 2);
if (result)?
return(5);?
? ? else
return(0);?
}
char SFE_BMP180::getTemperature(double &T)
{
? ? unsigned char data[2];
? ? char result;
? ? double tu, a;
? ? data[0] = BMP180_REG_RESULT;
? ? result = readBytes(data, 2);
if (result)?
? ? {
? ?? ???tu = (data[0] * 256.0) + data[1];
? ?? ???a = c5 * (tu - c6);
? ?? ???T = a + (mc / (a + md));
? ? }
? ? return(result);
}
char SFE_BMP180::startPressure(char oversampling)
{
? ? unsigned char data[2], result, delay;
? ? data[0] = BMP180_REG_CONTROL;
? ? switch (oversampling)
? ? {
? ?? ???case 0:
? ?? ?? ?? ?data[1] = BMP180_COMMAND_PRESSURE0;
? ?? ?? ?? ?delay = 5;
? ?? ???break;
? ?? ???case 1:
? ?? ?? ?? ?data[1] = BMP180_COMMAND_PRESSURE1;
? ?? ?? ?? ?delay = 8;
? ?? ???break;
? ?? ???case 2:
? ?? ?? ?? ?data[1] = BMP180_COMMAND_PRESSURE2;
? ?? ?? ?? ?delay = 14;
? ?? ???break;
? ?? ???case 3:
? ?? ?? ?? ?data[1] = BMP180_COMMAND_PRESSURE3;
? ?? ?? ?? ?delay = 26;
? ?? ???break;
? ?? ???default:
? ?? ?? ?? ?data[1] = BMP180_COMMAND_PRESSURE0;
? ?? ?? ?? ?delay = 5;
? ?? ???break;
? ? }
? ? result = writeBytes(data, 2);
? ? if (result)
return(delay);?
? ? else
return(0);?
}
char SFE_BMP180::getPressure(double &P, double &T)
sealevel().
{
? ? unsigned char data[3];
? ? char result;
? ? double pu,s,x,y,z;
? ? data[0] = BMP180_REG_RESULT;
? ? result = readBytes(data, 3);
if (result)?
? ? {
? ?? ???pu = (data[0] * 256.0) + data[1] + (data[2]/256.0);
? ?? ???s = T - 25.0;
? ?? ???x = (x2 * pow(s,2)) + (x1 * s) + x0;
? ?? ???y = (y2 * pow(s,2)) + (y1 * s) + y0;
? ?? ???z = (pu - x) / y;
? ?? ???P = (p2 * pow(z,2)) + (p1 * z) + p0;
? ? }
? ? return(result);
}
double SFE_BMP180::sealevel(double P, double A)
{
? ? return(P/pow(1-(A/44330.0),5.255));
}
double SFE_BMP180::altitude(double P, double P0)
{
? ? return(44330.0*(1-pow(P/P0,1/5.255)));
}
char SFE_BMP180::getError(void)
{
? ? return(_error);
}
模塊接線方式
1.先連接芯片與單片機(通過I2C接口)抑淫,按照如下方式連接
5V—VIN
GND–GND
A5—SCL
A4—SDA
2.然后UNO通過usb與PC電腦連接
3.拷貝后面的代碼燒錄進Arduino
實驗開源代碼
/*
【Arduino】66種傳感器模塊系列實驗(68)
實驗六十八:BMP180 新款 BOSCH溫度模塊氣壓傳感器(代替BMP085)
程序之一
*/
#include <SFE_BMP180.h>
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);
}
/*
【Arduino】66種傳感器模塊系列實驗(68)
實驗六十八:BMP180 新款 BOSCH溫度模塊氣壓傳感器(代替BMP085)
程序之二,氣溫姥闪、氣壓與海拔值可以調(diào)整并校準
*/
#include <Wire.h>
#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)<<OSS) + 2)>>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<<OSS));??????????????
??
??Wire.beginTransmission(BMP180ADD);
??Wire.write(0xF6);????????????????
??Wire.endTransmission();
??
??Wire.requestFrom(BMP180ADD, 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);//16 to 19 bit
??return up;
}
/*
【Arduino】168種傳感器模塊系列實驗(67)
實驗六十七:BMP180 新款 BOSCH溫度模塊氣壓傳感器(代替BMP085)
程序之三始苇,溫度、實時氣壓筐喳、已知海拔計算的海平面的氣壓催式、已知海平面氣壓計算的高度
只是算法有點爛,做做實驗而已
*/
#include <SFE_BMP180.h>?
#include <Wire.h>?
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);?
}