/elec/quadcopter

To get this branch, use:
bzr branch http://bzr.ed.am/elec/quadcopter

« back to all changes in this revision

Viewing changes to test/barometric-pressure/libs/BMP085/BMP085.cpp

  • Committer: Tim Marston
  • Date: 2013-01-16 23:02:32 UTC
  • Revision ID: tim@ed.am-20130116230232-d3od7r9g99n0ra0w
added test programs for all 4 IMU sensors

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*************************************************** 
 
2
  This is a library for the BMP085 Barometric Pressure & Temp Sensor
 
3
 
 
4
  Designed specifically to work with the Adafruit BMP085 Breakout 
 
5
  ----> https://www.adafruit.com/products/391
 
6
 
 
7
  These displays use I2C to communicate, 2 pins are required to  
 
8
  interface
 
9
  Adafruit invests time and resources providing this open source code, 
 
10
  please support Adafruit and open-source hardware by purchasing 
 
11
  products from Adafruit!
 
12
 
 
13
  Written by Limor Fried/Ladyada for Adafruit Industries.  
 
14
  BSD license, all text above must be included in any redistribution
 
15
 ****************************************************/
 
16
 
 
17
#include "BMP085.h"
 
18
#include <util/delay.h>
 
19
 
 
20
BMP085::BMP085() {
 
21
}
 
22
 
 
23
 
 
24
boolean BMP085::begin(uint8_t mode) {
 
25
  if (mode > BMP085_ULTRAHIGHRES) 
 
26
    mode = BMP085_ULTRAHIGHRES;
 
27
  oversampling = mode;
 
28
 
 
29
  Wire.begin();
 
30
 
 
31
  if (read8(0xD0) != 0x55) return false;
 
32
 
 
33
  /* read calibration data */
 
34
  ac1 = read16(BMP085_CAL_AC1);
 
35
  ac2 = read16(BMP085_CAL_AC2);
 
36
  ac3 = read16(BMP085_CAL_AC3);
 
37
  ac4 = read16(BMP085_CAL_AC4);
 
38
  ac5 = read16(BMP085_CAL_AC5);
 
39
  ac6 = read16(BMP085_CAL_AC6);
 
40
 
 
41
  b1 = read16(BMP085_CAL_B1);
 
42
  b2 = read16(BMP085_CAL_B2);
 
43
 
 
44
  mb = read16(BMP085_CAL_MB);
 
45
  mc = read16(BMP085_CAL_MC);
 
46
  md = read16(BMP085_CAL_MD);
 
47
#if (BMP085_DEBUG == 1)
 
48
  Serial.print("ac1 = "); Serial.println(ac1, DEC);
 
49
  Serial.print("ac2 = "); Serial.println(ac2, DEC);
 
50
  Serial.print("ac3 = "); Serial.println(ac3, DEC);
 
51
  Serial.print("ac4 = "); Serial.println(ac4, DEC);
 
52
  Serial.print("ac5 = "); Serial.println(ac5, DEC);
 
53
  Serial.print("ac6 = "); Serial.println(ac6, DEC);
 
54
 
 
55
  Serial.print("b1 = "); Serial.println(b1, DEC);
 
56
  Serial.print("b2 = "); Serial.println(b2, DEC);
 
57
 
 
58
  Serial.print("mb = "); Serial.println(mb, DEC);
 
59
  Serial.print("mc = "); Serial.println(mc, DEC);
 
60
  Serial.print("md = "); Serial.println(md, DEC);
 
61
#endif
 
62
}
 
63
 
 
64
uint16_t BMP085::readRawTemperature(void) {
 
65
  write8(BMP085_CONTROL, BMP085_READTEMPCMD);
 
66
  _delay_ms(5);
 
67
#if BMP085_DEBUG == 1
 
68
  Serial.print("Raw temp: "); Serial.println(read16(BMP085_TEMPDATA));
 
69
#endif
 
70
  return read16(BMP085_TEMPDATA);
 
71
}
 
72
 
 
73
uint32_t BMP085::readRawPressure(void) {
 
74
  uint32_t raw;
 
75
 
 
76
  write8(BMP085_CONTROL, BMP085_READPRESSURECMD + (oversampling << 6));
 
77
 
 
78
  if (oversampling == BMP085_ULTRALOWPOWER) 
 
79
    _delay_ms(5);
 
80
  else if (oversampling == BMP085_STANDARD) 
 
81
    _delay_ms(8);
 
82
  else if (oversampling == BMP085_HIGHRES) 
 
83
    _delay_ms(14);
 
84
  else 
 
85
    _delay_ms(26);
 
86
 
 
87
  raw = read16(BMP085_PRESSUREDATA);
 
88
 
 
89
  raw <<= 8;
 
90
  raw |= read8(BMP085_PRESSUREDATA+2);
 
91
  raw >>= (8 - oversampling);
 
92
 
 
93
 /* this pull broke stuff, look at it later?
 
94
  if (oversampling==0) {
 
95
    raw <<= 8;
 
96
    raw |= read8(BMP085_PRESSUREDATA+2);
 
97
    raw >>= (8 - oversampling);
 
98
  }
 
99
 */
 
100
 
 
101
#if BMP085_DEBUG == 1
 
102
  Serial.print("Raw pressure: "); Serial.println(raw);
 
103
#endif
 
104
  return raw;
 
105
}
 
106
 
 
107
 
 
108
int32_t BMP085::readPressure(void) {
 
109
  int32_t UT, UP, B3, B5, B6, X1, X2, X3, p;
 
110
  uint32_t B4, B7;
 
111
 
 
112
  UT = readRawTemperature();
 
113
  UP = readRawPressure();
 
114
 
 
115
#if BMP085_DEBUG == 1
 
116
  // use datasheet numbers!
 
117
  UT = 27898;
 
118
  UP = 23843;
 
119
  ac6 = 23153;
 
120
  ac5 = 32757;
 
121
  mc = -8711;
 
122
  md = 2868;
 
123
  b1 = 6190;
 
124
  b2 = 4;
 
125
  ac3 = -14383;
 
126
  ac2 = -72;
 
127
  ac1 = 408;
 
128
  ac4 = 32741;
 
129
  oversampling = 0;
 
130
#endif
 
131
 
 
132
  // do temperature calculations
 
133
  X1=(UT-(int32_t)(ac6))*((int32_t)(ac5))/pow(2,15);
 
134
  X2=((int32_t)mc*pow(2,11))/(X1+(int32_t)md);
 
135
  B5=X1 + X2;
 
136
 
 
137
#if BMP085_DEBUG == 1
 
138
  Serial.print("X1 = "); Serial.println(X1);
 
139
  Serial.print("X2 = "); Serial.println(X2);
 
140
  Serial.print("B5 = "); Serial.println(B5);
 
141
#endif
 
142
 
 
143
  // do pressure calcs
 
144
  B6 = B5 - 4000;
 
145
  X1 = ((int32_t)b2 * ( (B6 * B6)>>12 )) >> 11;
 
146
  X2 = ((int32_t)ac2 * B6) >> 11;
 
147
  X3 = X1 + X2;
 
148
  B3 = ((((int32_t)ac1*4 + X3) << oversampling) + 2) / 4;
 
149
 
 
150
#if BMP085_DEBUG == 1
 
151
  Serial.print("B6 = "); Serial.println(B6);
 
152
  Serial.print("X1 = "); Serial.println(X1);
 
153
  Serial.print("X2 = "); Serial.println(X2);
 
154
  Serial.print("B3 = "); Serial.println(B3);
 
155
#endif
 
156
 
 
157
  X1 = ((int32_t)ac3 * B6) >> 13;
 
158
  X2 = ((int32_t)b1 * ((B6 * B6) >> 12)) >> 16;
 
159
  X3 = ((X1 + X2) + 2) >> 2;
 
160
  B4 = ((uint32_t)ac4 * (uint32_t)(X3 + 32768)) >> 15;
 
161
  B7 = ((uint32_t)UP - B3) * (uint32_t)( 50000UL >> oversampling );
 
162
 
 
163
#if BMP085_DEBUG == 1
 
164
  Serial.print("X1 = "); Serial.println(X1);
 
165
  Serial.print("X2 = "); Serial.println(X2);
 
166
  Serial.print("B4 = "); Serial.println(B4);
 
167
  Serial.print("B7 = "); Serial.println(B7);
 
168
#endif
 
169
 
 
170
  if (B7 < 0x80000000) {
 
171
    p = (B7 * 2) / B4;
 
172
  } else {
 
173
    p = (B7 / B4) * 2;
 
174
  }
 
175
  X1 = (p >> 8) * (p >> 8);
 
176
  X1 = (X1 * 3038) >> 16;
 
177
  X2 = (-7357 * p) >> 16;
 
178
 
 
179
#if BMP085_DEBUG == 1
 
180
  Serial.print("p = "); Serial.println(p);
 
181
  Serial.print("X1 = "); Serial.println(X1);
 
182
  Serial.print("X2 = "); Serial.println(X2);
 
183
#endif
 
184
 
 
185
  p = p + ((X1 + X2 + (int32_t)3791)>>4);
 
186
#if BMP085_DEBUG == 1
 
187
  Serial.print("p = "); Serial.println(p);
 
188
#endif
 
189
  return p;
 
190
}
 
191
 
 
192
 
 
193
float BMP085::readTemperature(void) {
 
194
  int32_t UT, X1, X2, B5;     // following ds convention
 
195
  float temp;
 
196
 
 
197
  UT = readRawTemperature();
 
198
 
 
199
#if BMP085_DEBUG == 1
 
200
  // use datasheet numbers!
 
201
  UT = 27898;
 
202
  ac6 = 23153;
 
203
  ac5 = 32757;
 
204
  mc = -8711;
 
205
  md = 2868;
 
206
#endif
 
207
 
 
208
  // step 1
 
209
  X1 = (UT - (int32_t)ac6) * ((int32_t)ac5) / pow(2,15);
 
210
  X2 = ((int32_t)mc * pow(2,11)) / (X1+(int32_t)md);
 
211
  B5 = X1 + X2;
 
212
  temp = (B5+8)/pow(2,4);
 
213
  temp /= 10;
 
214
  
 
215
  return temp;
 
216
}
 
217
 
 
218
float BMP085::readAltitude(float sealevelPressure) {
 
219
  float altitude;
 
220
 
 
221
  float pressure = readPressure();
 
222
 
 
223
  altitude = 44330 * (1.0 - pow(pressure /sealevelPressure,0.1903));
 
224
 
 
225
  return altitude;
 
226
}
 
227
 
 
228
 
 
229
/*********************************************************************/
 
230
 
 
231
uint8_t BMP085::read8(uint8_t a) {
 
232
  uint8_t ret;
 
233
 
 
234
  Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device 
 
235
#if (ARDUINO >= 100)
 
236
  Wire.write(a); // sends register address to read from
 
237
#else
 
238
  Wire.send(a); // sends register address to read from
 
239
#endif
 
240
  Wire.endTransmission(); // end transmission
 
241
  
 
242
  Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device 
 
243
  Wire.requestFrom(BMP085_I2CADDR, 1);// send data n-bytes read
 
244
#if (ARDUINO >= 100)
 
245
  ret = Wire.read(); // receive DATA
 
246
#else
 
247
  ret = Wire.receive(); // receive DATA
 
248
#endif
 
249
  Wire.endTransmission(); // end transmission
 
250
 
 
251
  return ret;
 
252
}
 
253
 
 
254
uint16_t BMP085::read16(uint8_t a) {
 
255
  uint16_t ret;
 
256
 
 
257
  Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device 
 
258
#if (ARDUINO >= 100)
 
259
  Wire.write(a); // sends register address to read from
 
260
#else
 
261
  Wire.send(a); // sends register address to read from
 
262
#endif
 
263
  Wire.endTransmission(); // end transmission
 
264
  
 
265
  Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device 
 
266
  Wire.requestFrom(BMP085_I2CADDR, 2);// send data n-bytes read
 
267
#if (ARDUINO >= 100)
 
268
  ret = Wire.read(); // receive DATA
 
269
  ret <<= 8;
 
270
  ret |= Wire.read(); // receive DATA
 
271
#else
 
272
  ret = Wire.receive(); // receive DATA
 
273
  ret <<= 8;
 
274
  ret |= Wire.receive(); // receive DATA
 
275
#endif
 
276
  Wire.endTransmission(); // end transmission
 
277
 
 
278
  return ret;
 
279
}
 
280
 
 
281
void BMP085::write8(uint8_t a, uint8_t d) {
 
282
  Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device 
 
283
#if (ARDUINO >= 100)
 
284
  Wire.write(a); // sends register address to read from
 
285
  Wire.write(d);  // write data
 
286
#else
 
287
  Wire.send(a); // sends register address to read from
 
288
  Wire.send(d);  // write data
 
289
#endif
 
290
  Wire.endTransmission(); // end transmission
 
291
}