/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: 2012-11-28 23:18:38 UTC
  • Revision ID: tim@ed.am-20121128231838-r2t1dyawkzb6nxhe
initial commit, and a couple of receiver test programs

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
 
}