I2C interface of Bosch BMP085 pressure/temperature sensor.
bmp085.cpp@3:9c82e6a0172a, 2013-04-14 (annotated)
- Committer:
- davernm
- Date:
- Sun Apr 14 10:39:11 2013 +0000
- Revision:
- 3:9c82e6a0172a
- Parent:
- 2:4ebe4d41b588
1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
davernm | 2:4ebe4d41b588 | 1 | /*This code was written as an example program for students advancing from C programming to C++. |
davernm | 2:4ebe4d41b588 | 2 | // |
davernm | 2:4ebe4d41b588 | 3 | // |
davernm | 2:4ebe4d41b588 | 4 | |
davernm | 2:4ebe4d41b588 | 5 | |
davernm | 2:4ebe4d41b588 | 6 | |
davernm | 2:4ebe4d41b588 | 7 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
davernm | 2:4ebe4d41b588 | 8 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
davernm | 2:4ebe4d41b588 | 9 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
davernm | 2:4ebe4d41b588 | 10 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
davernm | 2:4ebe4d41b588 | 11 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
davernm | 2:4ebe4d41b588 | 12 | * |
davernm | 2:4ebe4d41b588 | 13 | |
davernm | 2:4ebe4d41b588 | 14 | |
davernm | 2:4ebe4d41b588 | 15 | Test code: |
davernm | 0:de9de5beb7af | 16 | // |
davernm | 0:de9de5beb7af | 17 | // |
davernm | 0:de9de5beb7af | 18 | // |
davernm | 0:de9de5beb7af | 19 | // |
davernm | 0:de9de5beb7af | 20 | //this program uses a ticker to read the BMP085 every 5 seconds and updates the lcd with |
davernm | 0:de9de5beb7af | 21 | //the pressure and temperature reading |
davernm | 0:de9de5beb7af | 22 | |
davernm | 0:de9de5beb7af | 23 | #include "mbed.h" |
davernm | 0:de9de5beb7af | 24 | #include "TextLCD.h" |
davernm | 0:de9de5beb7af | 25 | #include "bmp085.h" |
davernm | 0:de9de5beb7af | 26 | |
davernm | 0:de9de5beb7af | 27 | |
davernm | 0:de9de5beb7af | 28 | void doConv(void); |
davernm | 0:de9de5beb7af | 29 | void dispVals(long T,long P); |
davernm | 0:de9de5beb7af | 30 | |
davernm | 0:de9de5beb7af | 31 | //Three different constructors: |
davernm | 0:de9de5beb7af | 32 | |
davernm | 0:de9de5beb7af | 33 | BMP085 X(p28,p27,p5,3);//create an instance,using an EOC pin and oss set to 3 |
davernm | 0:de9de5beb7af | 34 | //BMP085 X(p28,p27,3);//create an instance without an EOC pin, oss 3 |
davernm | 0:de9de5beb7af | 35 | //BMP085 X(p28,p27);//create an instance, no EOC, oss will default to 0 |
davernm | 0:de9de5beb7af | 36 | TextLCD lcd(p7, p6, p8, p9, p10, p11); |
davernm | 0:de9de5beb7af | 37 | |
davernm | 0:de9de5beb7af | 38 | Ticker myT; |
davernm | 0:de9de5beb7af | 39 | |
davernm | 0:de9de5beb7af | 40 | int main() { |
davernm | 0:de9de5beb7af | 41 | |
davernm | 0:de9de5beb7af | 42 | myT.attach(&doConv,5); //every 5 seconds |
davernm | 0:de9de5beb7af | 43 | X.readCal(); //read calibration data |
davernm | 0:de9de5beb7af | 44 | doConv(); //call once |
davernm | 0:de9de5beb7af | 45 | while(1) |
davernm | 0:de9de5beb7af | 46 | { |
davernm | 0:de9de5beb7af | 47 | //do something |
davernm | 0:de9de5beb7af | 48 | } |
davernm | 0:de9de5beb7af | 49 | |
davernm | 0:de9de5beb7af | 50 | |
davernm | 0:de9de5beb7af | 51 | } |
davernm | 0:de9de5beb7af | 52 | |
davernm | 0:de9de5beb7af | 53 | |
davernm | 0:de9de5beb7af | 54 | void dispVals(long T,long P)//display data on the lcd |
davernm | 0:de9de5beb7af | 55 | { |
davernm | 0:de9de5beb7af | 56 | lcd.locate(0,0); //lcd line 1 |
davernm | 0:de9de5beb7af | 57 | |
davernm | 0:de9de5beb7af | 58 | char buf[20],*P1="Temp:",*P2="Press:"; |
davernm | 0:de9de5beb7af | 59 | lcd.printf(P2); |
davernm | 0:de9de5beb7af | 60 | lcd.locate(strlen(P2),0); |
davernm | 0:de9de5beb7af | 61 | float p=(float)P; |
davernm | 0:de9de5beb7af | 62 | p/=100;//convert to milli bar |
davernm | 0:de9de5beb7af | 63 | sprintf(buf,"%.2f",p); |
davernm | 0:de9de5beb7af | 64 | lcd.printf("%s",buf); |
davernm | 0:de9de5beb7af | 65 | |
davernm | 0:de9de5beb7af | 66 | lcd.locate(0,1); // lcd line 2 |
davernm | 0:de9de5beb7af | 67 | lcd.printf(P1); |
davernm | 0:de9de5beb7af | 68 | float t=(float)T; |
davernm | 0:de9de5beb7af | 69 | t/=10;//convert to deg C |
davernm | 0:de9de5beb7af | 70 | sprintf(buf,"%.2f",t); |
davernm | 0:de9de5beb7af | 71 | lcd.locate(strlen(P1),1); |
davernm | 0:de9de5beb7af | 72 | lcd.printf("%s",buf); |
davernm | 0:de9de5beb7af | 73 | |
davernm | 0:de9de5beb7af | 74 | |
davernm | 0:de9de5beb7af | 75 | } |
davernm | 0:de9de5beb7af | 76 | void doConv(void) |
davernm | 0:de9de5beb7af | 77 | { |
davernm | 0:de9de5beb7af | 78 | long UT,UP,T,P; |
davernm | 0:de9de5beb7af | 79 | |
davernm | 0:de9de5beb7af | 80 | |
davernm | 0:de9de5beb7af | 81 | UT=X.readUT(); //read uncompensated temperature |
davernm | 0:de9de5beb7af | 82 | UP= X.readUP(); //read uncompensated pressure |
davernm | 0:de9de5beb7af | 83 | X.calVals(UT,UP,&T,&P); //calculate temperature and pressure |
davernm | 0:de9de5beb7af | 84 | dispVals(T,P); //dsiplay resuls on lcd |
davernm | 0:de9de5beb7af | 85 | } |
davernm | 0:de9de5beb7af | 86 | |
davernm | 0:de9de5beb7af | 87 | */ |
davernm | 0:de9de5beb7af | 88 | #include "mbed.h" |
davernm | 0:de9de5beb7af | 89 | #include "bmp085.h" |
davernm | 0:de9de5beb7af | 90 | |
davernm | 2:4ebe4d41b588 | 91 | BMP085:: BMP085(PinName sda,PinName scl,int Oss):i2c(sda,scl){ |
davernm | 0:de9de5beb7af | 92 | //this constructor does not use an end of conversion pin |
davernm | 0:de9de5beb7af | 93 | i2c.frequency(50000); |
davernm | 0:de9de5beb7af | 94 | flag=false; |
davernm | 0:de9de5beb7af | 95 | oss=Oss; |
davernm | 0:de9de5beb7af | 96 | } |
davernm | 2:4ebe4d41b588 | 97 | BMP085::BMP085(PinName sda,PinName scl):i2c(sda,scl){ |
davernm | 0:de9de5beb7af | 98 | //this version has no end of conversion, and has the oversampling |
davernm | 0:de9de5beb7af | 99 | //default to 0. |
davernm | 0:de9de5beb7af | 100 | i2c.frequency(50000); |
davernm | 0:de9de5beb7af | 101 | flag=false; |
davernm | 0:de9de5beb7af | 102 | oss=0;//default to 0 |
davernm | 0:de9de5beb7af | 103 | |
davernm | 0:de9de5beb7af | 104 | } |
davernm | 2:4ebe4d41b588 | 105 | BMP085::BMP085(PinName sda,PinName scl, PinName EOC,int Oss) : i2c(sda,scl) { |
davernm | 0:de9de5beb7af | 106 | //end of conversion pin is used as well as oss being set |
davernm | 0:de9de5beb7af | 107 | // |
davernm | 0:de9de5beb7af | 108 | EOCptr = new DigitalIn(EOC); |
davernm | 0:de9de5beb7af | 109 | i2c.frequency(50000); |
davernm | 0:de9de5beb7af | 110 | flag=true; //eoc pin is present |
davernm | 0:de9de5beb7af | 111 | oss=Oss; |
davernm | 0:de9de5beb7af | 112 | |
davernm | 0:de9de5beb7af | 113 | } |
davernm | 0:de9de5beb7af | 114 | |
davernm | 0:de9de5beb7af | 115 | |
davernm | 0:de9de5beb7af | 116 | |
davernm | 0:de9de5beb7af | 117 | void BMP085::calVals(long UT,long UP, long *Temp,long *Pre)//see data sheet for calculations |
davernm | 0:de9de5beb7af | 118 | { |
davernm | 0:de9de5beb7af | 119 | |
davernm | 0:de9de5beb7af | 120 | long X1,X2,X3,B6,B3,B7,p,B5,T; |
davernm | 0:de9de5beb7af | 121 | unsigned long B4; |
davernm | 0:de9de5beb7af | 122 | |
davernm | 0:de9de5beb7af | 123 | X1=((UT-AC6)*AC5)>>15; |
davernm | 0:de9de5beb7af | 124 | X2=(MC<<11)/(X1+MD); |
davernm | 0:de9de5beb7af | 125 | B5=X1+X2; |
davernm | 0:de9de5beb7af | 126 | T=(B5+8)>>4; |
davernm | 0:de9de5beb7af | 127 | |
davernm | 0:de9de5beb7af | 128 | *Temp=T; |
davernm | 0:de9de5beb7af | 129 | B6=B5-4000; |
davernm | 0:de9de5beb7af | 130 | X1=(B6*B6)/4096; |
davernm | 0:de9de5beb7af | 131 | X1*=B2; |
davernm | 0:de9de5beb7af | 132 | X1>>=11; |
davernm | 0:de9de5beb7af | 133 | X2=(AC2*B6)/2048; |
davernm | 0:de9de5beb7af | 134 | X3=X1+X2; |
davernm | 0:de9de5beb7af | 135 | B3=(((AC1*4+X3)<<oss)+2)/4; |
davernm | 0:de9de5beb7af | 136 | X1=(AC3*B6)>>13; |
davernm | 0:de9de5beb7af | 137 | X2=(B6*B6)>>12; |
davernm | 0:de9de5beb7af | 138 | X2*=B1; |
davernm | 0:de9de5beb7af | 139 | X2>>=16; |
davernm | 0:de9de5beb7af | 140 | X3=((X1+X2)+2)>>2; |
davernm | 0:de9de5beb7af | 141 | B4=(AC4*(unsigned long)(X3+32768))/32768; |
davernm | 0:de9de5beb7af | 142 | B7=((unsigned long)(UP-B3)*(50000>>oss)); |
davernm | 0:de9de5beb7af | 143 | |
davernm | 0:de9de5beb7af | 144 | if (B7<0x80000000) p=(B7*2)/B4; |
davernm | 0:de9de5beb7af | 145 | |
davernm | 0:de9de5beb7af | 146 | else p=(B7/B4)*2; |
davernm | 0:de9de5beb7af | 147 | X1=(p>>8)*(p>>8); |
davernm | 0:de9de5beb7af | 148 | X1=(X1*3038)>>16; |
davernm | 0:de9de5beb7af | 149 | X2=(-7357*p)>>16; |
davernm | 0:de9de5beb7af | 150 | p+=(X1+X2+3791)>>4; |
davernm | 0:de9de5beb7af | 151 | *Pre=p; |
davernm | 1:30d98c558b29 | 152 | |
davernm | 0:de9de5beb7af | 153 | |
davernm | 0:de9de5beb7af | 154 | |
davernm | 0:de9de5beb7af | 155 | } |
davernm | 0:de9de5beb7af | 156 | |
davernm | 0:de9de5beb7af | 157 | long BMP085::readUT(void) //uncompensated temperature |
davernm | 0:de9de5beb7af | 158 | { |
davernm | 0:de9de5beb7af | 159 | float delVals[]={4.5,7.5,13.5,25.5}; //data sheet values |
davernm | 0:de9de5beb7af | 160 | char wReg[2]; // write 0x2e into reg 0xf4 |
davernm | 0:de9de5beb7af | 161 | wReg[0] = 0xF4; |
davernm | 0:de9de5beb7af | 162 | wReg[1] = 0x2E; |
davernm | 0:de9de5beb7af | 163 | i2c.write(0xee, wReg, 2); |
davernm | 0:de9de5beb7af | 164 | if (!flag)wait_ms(delVals[oss]); |
davernm | 0:de9de5beb7af | 165 | //use EOC |
davernm | 0:de9de5beb7af | 166 | else while (EOCptr->read()==0); //wait for 1 |
davernm | 0:de9de5beb7af | 167 | // uncompensated temperature |
davernm | 0:de9de5beb7af | 168 | char cmd = 0xF6;// read reg 0xf6 |
davernm | 0:de9de5beb7af | 169 | i2c.write(0xee, &cmd, 1); |
davernm | 0:de9de5beb7af | 170 | |
davernm | 0:de9de5beb7af | 171 | char Arr[2]; |
davernm | 0:de9de5beb7af | 172 | i2c.read(0xef,Arr,2); |
davernm | 0:de9de5beb7af | 173 | long UT=(Arr[0]<<8)|Arr[1]; |
davernm | 0:de9de5beb7af | 174 | return UT; |
davernm | 0:de9de5beb7af | 175 | } |
davernm | 0:de9de5beb7af | 176 | |
davernm | 0:de9de5beb7af | 177 | |
davernm | 0:de9de5beb7af | 178 | |
davernm | 0:de9de5beb7af | 179 | long BMP085::readUP(void)//uncompensated pressure |
davernm | 0:de9de5beb7af | 180 | { |
davernm | 0:de9de5beb7af | 181 | float delVals[]={4.5,7.5,13.5,25.5}; //data sheet values |
davernm | 0:de9de5beb7af | 182 | char wReg[2]; // write 0x34 into reg 0xf4 |
davernm | 0:de9de5beb7af | 183 | wReg[0] = 0xF4; |
davernm | 0:de9de5beb7af | 184 | wReg[1] = 0x34+(oss<<6); |
davernm | 0:de9de5beb7af | 185 | i2c.write(0xee, wReg, 2); |
davernm | 0:de9de5beb7af | 186 | if (!flag)wait_ms(delVals[oss]); |
davernm | 0:de9de5beb7af | 187 | else while (EOCptr->read()==0); |
davernm | 0:de9de5beb7af | 188 | char cmd=0xf6; |
davernm | 0:de9de5beb7af | 189 | i2c.write(0xee,&cmd,1); |
davernm | 0:de9de5beb7af | 190 | char Arr[3]; |
davernm | 0:de9de5beb7af | 191 | i2c.read(0xef,Arr,3); //3 byte data |
davernm | 0:de9de5beb7af | 192 | long UP=((Arr[0]<<16)|(Arr[1]<<8)|Arr[2])>>(8-oss); |
davernm | 1:30d98c558b29 | 193 | |
davernm | 0:de9de5beb7af | 194 | |
davernm | 0:de9de5beb7af | 195 | return UP; |
davernm | 0:de9de5beb7af | 196 | } |
davernm | 0:de9de5beb7af | 197 | |
davernm | 0:de9de5beb7af | 198 | void BMP085::readCal(void)//read the onboard calibration data |
davernm | 0:de9de5beb7af | 199 | { |
davernm | 0:de9de5beb7af | 200 | int i; |
davernm | 0:de9de5beb7af | 201 | char addr=0xaa; |
davernm | 0:de9de5beb7af | 202 | char dumArr[1]; |
davernm | 0:de9de5beb7af | 203 | |
davernm | 0:de9de5beb7af | 204 | for (i=0;i<22;i++) |
davernm | 0:de9de5beb7af | 205 | { |
davernm | 0:de9de5beb7af | 206 | i2c.write(0xee,&addr,1); |
davernm | 0:de9de5beb7af | 207 | i2c.read(0xef,dumArr,1); |
davernm | 0:de9de5beb7af | 208 | Vals[i]=dumArr[0]; |
davernm | 0:de9de5beb7af | 209 | addr++; |
davernm | 0:de9de5beb7af | 210 | } |
davernm | 0:de9de5beb7af | 211 | AC1=(Vals[0]<<8)|Vals[1]; |
davernm | 0:de9de5beb7af | 212 | AC2=(Vals[2]<<8)|Vals[3]; |
davernm | 0:de9de5beb7af | 213 | AC3=(Vals[4]<<8)|Vals[5]; |
davernm | 0:de9de5beb7af | 214 | AC4=(Vals[6]<<8)|Vals[7]; |
davernm | 0:de9de5beb7af | 215 | AC5=(Vals[8]<<8)|Vals[9]; |
davernm | 0:de9de5beb7af | 216 | AC6=(Vals[10]<<8)|Vals[11]; |
davernm | 0:de9de5beb7af | 217 | B1=(Vals[12]<<8)|Vals[13]; |
davernm | 0:de9de5beb7af | 218 | B2=(Vals[14]<<8)|Vals[15]; |
davernm | 0:de9de5beb7af | 219 | MB=(Vals[16]<<8)|Vals[17]; |
davernm | 0:de9de5beb7af | 220 | MC=(Vals[18]<<8)|Vals[19]; |
davernm | 1:30d98c558b29 | 221 | MD=(Vals[20]<<8)|Vals[21]; |
davernm | 0:de9de5beb7af | 222 | |
davernm | 0:de9de5beb7af | 223 | } |