Arduino --- BMP180大氣壓強(qiáng)傳感器的使用

前言

大氣壓強(qiáng)傳感器,故名思議豺型,是一款檢測(cè)氣壓的傳感器,其使用代碼如下:

#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)
    {
      //當(dāng)前氣壓
      Serial.print("Current Preasure: ");
      Serial.print(presureP);
      Serial.println(" bar");

      //換算成標(biāo)準(zhǔn)大氣壓
      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);
}

需要用的 “SFE_BMP180” 庫(kù)文件如下:

SFE_BMP180.h

/*
    SFE_BMP180.h
    Bosch BMP180 pressure sensor library for the Arduino microcontroller
    Mike Grusin, SparkFun Electronics

    Uses floating-point equations from the Weather Station Data Logger project
    http://wmrx00.sourceforge.net/
    http://wmrx00.sourceforge.net/Arduino/BMP085-Calcs.pdf

    Forked from BMP085 library by M.Grusin

    version 1.0 2013/09/20 initial version
    Verison 1.1.2 - Updated for Arduino 1.6.4 5/2015
    
    Our example code uses the "beerware" license. You can do anything
    you like with this code. No really, anything. If you find it useful,
    buy me a (root) beer someday.
*/

#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(); // base type

        char begin();
            // call pressure.begin() to initialize BMP180 before use
            // returns 1 if success, 0 if failure (bad component or I2C bus shorted?)
        
        char startTemperature(void);
            // command BMP180 to start a temperature measurement
            // returns (number of ms to wait) for success, 0 for fail

        char getTemperature(double &T);
            // return temperature measurement from previous startTemperature command
            // places returned value in T variable (deg C)
            // returns 1 for success, 0 for fail

        char startPressure(char oversampling);
            // command BMP180 to start a pressure measurement
            // oversampling: 0 - 3 for oversampling value
            // returns (number of ms to wait) for success, 0 for fail

        char getPressure(double &P, double &T);
            // return absolute pressure measurement from previous startPressure command
            // note: requires previous temperature measurement in variable T
            // places returned value in P variable (mbar)
            // returns 1 for success, 0 for fail

        double sealevel(double P, double A);
            // convert absolute pressure to sea-level pressure (as used in weather data)
            // P: absolute pressure (mbar)
            // A: current altitude (meters)
            // returns sealevel pressure in mbar

        double altitude(double P, double P0);
            // convert absolute pressure to altitude (given baseline pressure; sea-level, runway, etc.)
            // P: absolute pressure (mbar)
            // P0: fixed baseline pressure (mbar)
            // returns signed altitude in meters

        char getError(void);
            // If any library command fails, you can retrieve an extended
            // error code using this command. Errors are from the wire library: 
            // 0 = Success
            // 1 = Data too long to fit in transmit buffer
            // 2 = Received NACK on transmit of address
            // 3 = Received NACK on transmit of data
            // 4 = Other error

    private:
    
        char readInt(char address, int16_t &value);
            // read an signed int (16 bits) from a BMP180 register
            // address: BMP180 register address
            // value: external signed int for returned value (16 bits)
            // returns 1 for success, 0 for fail, with result in value

        char readUInt(char address, uint16_t &value);
            // read an unsigned int (16 bits) from a BMP180 register
            // address: BMP180 register address
            // value: external unsigned int for returned value (16 bits)
            // returns 1 for success, 0 for fail, with result in value

        char readBytes(unsigned char *values, char length);
            // read a number of bytes from a BMP180 register
            // values: array of char with register address in first location [0]
            // length: number of bytes to read back
            // returns 1 for success, 0 for fail, with read bytes in values[] array
            
        char writeBytes(unsigned char *values, char length);
            // write a number of bytes to a BMP180 register (and consecutive subsequent registers)
            // values: array of char with register address in first location [0]
            // length: number of bytes to write
            // returns 1 for success, 0 for fail
            
        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 // 7-bit address

#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

#endif

SFE_BMP180.cp

/*
    SFE_BMP180.cpp
    Bosch BMP180 pressure sensor library for the Arduino microcontroller
    Mike Grusin, SparkFun Electronics

    Uses floating-point equations from the Weather Station Data Logger project
    http://wmrx00.sourceforge.net/
    http://wmrx00.sourceforge.net/Arduino/BMP085-Calcs.pdf

    Forked from BMP085 library by M.Grusin

    version 1.0 2013/09/20 initial version
    Verison 1.1.2 - Updated for Arduino 1.6.4 5/2015

    Our example code uses the "beerware" license. You can do anything
    you like with this code. No really, anything. If you find it useful,
    buy me a (root) beer someday.
*/

#include <SFE_BMP180.h>
#include <Wire.h>
#include <stdio.h>
#include <math.h>


SFE_BMP180::SFE_BMP180()
// Base library type
{
}


char SFE_BMP180::begin()
// Initialize library for subsequent pressure measurements
{
    double c3,c4,b1;
    
    // Start up the Arduino's "wire" (I2C) library:
    
    Wire.begin();

    // The BMP180 includes factory calibration data stored on the device.
    // Each device has different numbers, these must be retrieved and
    // used in the calculations when taking pressure measurements.

    // Retrieve calibration data from device:
    
    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))
    {

        // All reads completed successfully!

        // If you need to check your math using known numbers,
        // you can uncomment one of these examples.
        // (The correct results are commented in the below functions.)

        // Example from Bosch datasheet
        // AC1 = 408; AC2 = -72; AC3 = -14383; AC4 = 32741; AC5 = 32757; AC6 = 23153;
        // B1 = 6190; B2 = 4; MB = -32768; MC = -8711; MD = 2868;

        // Example from http://wmrx00.sourceforge.net/Arduino/BMP180-Calcs.pdf
        // AC1 = 7911; AC2 = -934; AC3 = -14306; AC4 = 31567; AC5 = 25671; AC6 = 18974;
        // VB1 = 5498; VB2 = 46; MB = -32768; MC = -11075; MD = 2432;

        /*
        Serial.print("AC1: "); Serial.println(AC1);
        Serial.print("AC2: "); Serial.println(AC2);
        Serial.print("AC3: "); Serial.println(AC3);
        Serial.print("AC4: "); Serial.println(AC4);
        Serial.print("AC5: "); Serial.println(AC5);
        Serial.print("AC6: "); Serial.println(AC6);
        Serial.print("VB1: "); Serial.println(VB1);
        Serial.print("VB2: "); Serial.println(VB2);
        Serial.print("MB: "); Serial.println(MB);
        Serial.print("MC: "); Serial.println(MC);
        Serial.print("MD: "); Serial.println(MD);
        */
        
        // Compute floating-point polynominals:

        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);

        /*
        Serial.println();
        Serial.print("c3: "); Serial.println(c3);
        Serial.print("c4: "); Serial.println(c4);
        Serial.print("c5: "); Serial.println(c5);
        Serial.print("c6: "); Serial.println(c6);
        Serial.print("b1: "); Serial.println(b1);
        Serial.print("mc: "); Serial.println(mc);
        Serial.print("md: "); Serial.println(md);
        Serial.print("x0: "); Serial.println(x0);
        Serial.print("x1: "); Serial.println(x1);
        Serial.print("x2: "); Serial.println(x2);
        Serial.print("y0: "); Serial.println(y0);
        Serial.print("y1: "); Serial.println(y1);
        Serial.print("y2: "); Serial.println(y2);
        Serial.print("p0: "); Serial.println(p0);
        Serial.print("p1: "); Serial.println(p1);
        Serial.print("p2: "); Serial.println(p2);
        */
        
        // Success!
        return(1);
    }
    else
    {
        // Error reading calibration data; bad component or connection?
        return(0);
    }
}


char SFE_BMP180::readInt(char address, int16_t &value)
// Read a signed integer (two bytes) from device
// address: register to start reading (plus subsequent register)
// value: external variable to store data (function modifies value)
{
    unsigned char data[2];

    data[0] = address;
    if (readBytes(data,2))
    {
        value = (int16_t)((data[0]<<8)|data[1]);
        //if (*value & 0x8000) *value |= 0xFFFF0000; // sign extend if negative
        return(1);
    }
    value = 0;
    return(0);
}


char SFE_BMP180::readUInt(char address, uint16_t &value)
// Read an unsigned integer (two bytes) from device
// address: register to start reading (plus subsequent register)
// value: external variable to store data (function modifies 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)
// Read an array of bytes from device
// values: external array to hold data. Put starting register in values[0].
// length: number of bytes to read
{
    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) ; // wait until bytes are ready
        for(x=0;x<length;x++)
        {
            values[x] = Wire.read();
        }
        return(1);
    }
    return(0);
}


char SFE_BMP180::writeBytes(unsigned char *values, char length)
// Write an array of bytes to device
// values: external array of data to write. Put starting register in values[0].
// length: number of bytes to write
{
    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)
// Begin a temperature reading.
// Will return delay in ms to wait, or 0 if I2C error
{
    unsigned char data[2], result;
    
    data[0] = BMP180_REG_CONTROL;
    data[1] = BMP180_COMMAND_TEMPERATURE;
    result = writeBytes(data, 2);
    if (result) // good write?
        return(5); // return the delay in ms (rounded up) to wait before retrieving data
    else
        return(0); // or return 0 if there was a problem communicating with the BMP
}


char SFE_BMP180::getTemperature(double &T)
// Retrieve a previously-started temperature reading.
// Requires begin() to be called once prior to retrieve calibration parameters.
// Requires startTemperature() to have been called prior and sufficient time elapsed.
// T: external variable to hold result.
// Returns 1 if successful, 0 if I2C error.
{
    unsigned char data[2];
    char result;
    double tu, a;
    
    data[0] = BMP180_REG_RESULT;

    result = readBytes(data, 2);
    if (result) // good read, calculate temperature
    {
        tu = (data[0] * 256.0) + data[1];

        //example from Bosch datasheet
        //tu = 27898;

        //example from http://wmrx00.sourceforge.net/Arduino/BMP085-Calcs.pdf
        //tu = 0x69EC;
        
        a = c5 * (tu - c6);
        T = a + (mc / (a + md));

        /*      
        Serial.println();
        Serial.print("tu: "); Serial.println(tu);
        Serial.print("a: "); Serial.println(a);
        Serial.print("T: "); Serial.println(*T);
        */
    }
    return(result);
}


char SFE_BMP180::startPressure(char oversampling)
// Begin a pressure reading.
// Oversampling: 0 to 3, higher numbers are slower, higher-res outputs.
// Will return delay in ms to wait, or 0 if I2C error.
{
    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) // good write?
        return(delay); // return the delay in ms (rounded up) to wait before retrieving data
    else
        return(0); // or return 0 if there was a problem communicating with the BMP
}


char SFE_BMP180::getPressure(double &P, double &T)
// Retrieve a previously started pressure reading, calculate abolute pressure in mbars.
// Requires begin() to be called once prior to retrieve calibration parameters.
// Requires startPressure() to have been called prior and sufficient time elapsed.
// Requires recent temperature reading to accurately calculate pressure.

// P: external variable to hold pressure.
// T: previously-calculated temperature.
// Returns 1 for success, 0 for I2C error.

// Note that calculated pressure value is absolute mbars, to compensate for altitude call sealevel().
{
    unsigned char data[3];
    char result;
    double pu,s,x,y,z;
    
    data[0] = BMP180_REG_RESULT;

    result = readBytes(data, 3);
    if (result) // good read, calculate pressure
    {
        pu = (data[0] * 256.0) + data[1] + (data[2]/256.0);

        //example from Bosch datasheet
        //pu = 23843;

        //example from http://wmrx00.sourceforge.net/Arduino/BMP085-Calcs.pdf, pu = 0x982FC0;   
        //pu = (0x98 * 256.0) + 0x2F + (0xC0/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;

        /*
        Serial.println();
        Serial.print("pu: "); Serial.println(pu);
        Serial.print("T: "); Serial.println(*T);
        Serial.print("s: "); Serial.println(s);
        Serial.print("x: "); Serial.println(x);
        Serial.print("y: "); Serial.println(y);
        Serial.print("z: "); Serial.println(z);
        Serial.print("P: "); Serial.println(*P);
        */
    }
    return(result);
}


double SFE_BMP180::sealevel(double P, double A)
// Given a pressure P (mb) taken at a specific altitude (meters),
// return the equivalent pressure (mb) at sea level.
// This produces pressure readings that can be used for weather measurements.
{
    return(P/pow(1-(A/44330.0),5.255));
}


double SFE_BMP180::altitude(double P, double P0)
// Given a pressure measurement P (mb) and the pressure at a baseline P0 (mb),
// return altitude (meters) above baseline.
{
    return(44330.0*(1-pow(P/P0,1/5.255)));
}


char SFE_BMP180::getError(void)
    // If any library command fails, you can retrieve an extended
    // error code using this command. Errors are from the wire library: 
    // 0 = Success
    // 1 = Data too long to fit in transmit buffer
    // 2 = Received NACK on transmit of address
    // 3 = Received NACK on transmit of data
    // 4 = Other error
{
    return(_error);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绑咱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子趋艘,更是在濱河造成了極大的恐慌,老刑警劉巖凶朗,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓷胧,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡棚愤,警方通過(guò)查閱死者的電腦和手機(jī)搓萧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)宛畦,“玉大人瘸洛,你說(shuō)我怎么就攤上這事〈魏停” “怎么了反肋?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)踏施。 經(jīng)常有香客問(wèn)我石蔗,道長(zhǎng),這世上最難降的妖魔是什么读规? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任抓督,我火速辦了婚禮,結(jié)果婚禮上束亏,老公的妹妹穿的比我還像新娘铃在。我一直安慰自己,他們只是感情好碍遍,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布定铜。 她就那樣靜靜地躺著,像睡著了一般怕敬。 火紅的嫁衣襯著肌膚如雪揣炕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天东跪,我揣著相機(jī)與錄音畸陡,去河邊找鬼。 笑死虽填,一個(gè)胖子當(dāng)著我的面吹牛丁恭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播斋日,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼牲览,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了恶守?” 一聲冷哼從身側(cè)響起第献,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤贡必,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后庸毫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仔拟,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年岔绸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了理逊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片橡伞。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡盒揉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出兑徘,到底是詐尸還是另有隱情刚盈,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布挂脑,位于F島的核電站檩赢,受9級(jí)特大地震影響馁痴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一掰盘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧隅津,春花似錦散劫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至如孝,卻和暖如春宪哩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背第晰。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工锁孟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人茁瘦。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓品抽,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親腹躁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子桑包,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 寫在前面 本文原標(biāo)題《以iPhone 6 為例介紹手機(jī)內(nèi)置傳感器 》,是我的《傳感器》課程的課后大作業(yè)纺非。說(shuō)來(lái)之所以...
    繼續(xù)海闊天空閱讀 29,576評(píng)論 2 17
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,520評(píng)論 25 707
  • 學(xué)習(xí)swift過(guò)程中發(fā)現(xiàn)在給一些系統(tǒng)控件擴(kuò)展分類的時(shí)候用到了convenience關(guān)鍵字哑了,比如下面這個(gè)UIButt...
    Jude_XC閱讀 5,616評(píng)論 0 2
  • 當(dāng)我們小的時(shí)候赘方,父母愛我們,關(guān)照我們弱左,呵護(hù)我們窄陡,讓我們帶著愛意和技能,更好面對(duì)未知的世界拆火。但是跳夭,有的孩子沒(méi)有得到父...
    MacQingfeng閱讀 280評(píng)論 0 0
  • 我讀三年級(jí)的時(shí)候,每天晚上總愛看動(dòng)畫片:《聰明的一休》们镜。一休哥的聰明的形象在我的腦海里留下了深深的印象币叹。我...
    XZX夏子曦閱讀 255評(píng)論 0 0