COSA
An Object-Oriented Platform for Arduino Programming
BMP085.cpp
Go to the documentation of this file.
1 
21 #include "BMP085.hh"
22 #include "Cosa/Watchdog.hh"
23 
24 // Pressure convertion time depending on mode (pp. 10).
25 // Watchdog::delay() with a resolution of 16 ms is used.
26 const uint8_t BMP085::PRESSURE_CONV_MS[] __PROGMEM = {
27  5,
28  8,
29  14,
30  26
31 };
32 
33 bool
35 {
36  // Set the operation mode
37  m_mode = mode;
38 
39  // Read coefficients from the device
40  twi.acquire(this);
42  twi.read(&m_param, sizeof(m_param));
43  twi.release();
44 
45  // Adjust for little endien
46  swap<param_t>(&m_param);
47  return (true);
48 }
49 
50 bool
52 {
53  // Check that a conversion request is not in process
54  if (UNLIKELY(m_cmd != 0)) return (false);
55 
56  // Start a temperature measurement and wait
58  twi.acquire(this);
59  twi.write(CMD_REG, &m_cmd, sizeof(m_cmd));
60  twi.release();
61 
62  // Set start time for completion
64  return (true);
65 }
66 
67 bool
69 {
70  // Check that a temperature conversion request was issued
71  if (UNLIKELY(m_cmd != TEMP_CONV_CMD)) return (false);
72  m_cmd = 0;
73 
74  // Check if we need to wait for the conversion to complete
75  int16_t ms = Watchdog::millis() - m_start + TEMP_CONV_MS;
76  if (ms > 0) delay(ms);
77 
78  // Read the raw temperature sensor data
79  int16_t UT;
80  twi.acquire(this);
81  twi.write(RES_REG);
82  twi.read(&UT, sizeof(UT));
83  twi.release();
84 
85  // Adjust for little endien
86  UT = swap(UT);
87 
88  // Temperature calculation
89  int32_t X1 = ((((int32_t) UT) - m_param.ac6) * m_param.ac5) >> 15;
90  int32_t X2 = (((int32_t) m_param.mc) << 11) / (X1 + m_param.md);
91  B5 = X1 + X2;
92  return (true);
93 }
94 
95 bool
97 {
98  // Check that a conversion request is not in process
99  if (UNLIKELY(m_cmd != 0)) return (false);
100 
101  // Start a pressure measurement
102  twi.acquire(this);
103  m_cmd = PRESSURE_CONV_CMD + (m_mode << 6);
104  twi.write(CMD_REG, &m_cmd, sizeof(m_cmd));
105  twi.release();
106 
107  // Set start time for completion
109  return (true);
110 }
111 
112 bool
114 {
115  // Check that a conversion request was issued
116  if (UNLIKELY(m_cmd != (PRESSURE_CONV_CMD + (m_mode << 6)))) return (false);
117  m_cmd = 0;
118 
119  // Check if we need to wait for the conversion to complete
120  int16_t ms = Watchdog::millis() - m_start;
121  ms += pgm_read_byte(&PRESSURE_CONV_MS[m_mode]);
122  if (ms > 0) delay(ms);
123 
124  // Read the raw pressure sensor data
125  univ32_t res;
126  res.as_uint8[0] = 0;
127  twi.acquire(this);
128  twi.write(RES_REG);
129  twi.read(&res.as_uint8[1], 3);
130  twi.release();
131 
132  // Adjust for little endian and resolution (oversampling mode)
133  int32_t UP = swap(res.as_int32) >> (8 - m_mode);
134  int32_t B3, B6, X1, X2, X3;
135  uint32_t B4, B7;
136 
137  // Pressure calculation
138  B6 = B5 - 4000;
139  X1 = (m_param.b2 * ((B6 * B6) >> 12)) >> 11;
140  X2 = (m_param.ac2 * B6) >> 11;
141  X3 = X1 + X2;
142  B3 = ((((((int32_t) m_param.ac1) << 2) + X3) << m_mode) + 2) >> 2;
143  X1 = (m_param.ac3 * B6) >> 13;
144  X2 = (m_param.b1 * ((B6 * B6) >> 12)) >> 16;
145  X3 = ((X1 + X2) + 2) >> 2;
146  B4 = (m_param.ac4 * (uint32_t) (X3 + 32768)) >> 15;
147  B7 = ((uint32_t) UP - B3) * (50000 >> m_mode);
148  m_pressure = (B7 < 0x80000000) ? (B7 << 1) / B4 : (B7 / B4) << 1;
149  X1 = (m_pressure >> 8) * (m_pressure >> 8);
150  X1 = (X1 * 3038) >> 16;
151  X2 = (-7357 * m_pressure) >> 16;
152  m_pressure += (X1 + X2 + 3791) >> 4;
153 
154  return (true);
155 }
156 
157 IOStream&
159 {
160  outs << PSTR("BMP085(temperature = ") << bmp.temperature()
161  << PSTR(", pressure = ") << bmp.pressure()
162  << PSTR(")");
163  return (outs);
164 }
TWI twi
Definition: TWI.cpp:27
static uint32_t millis()
Definition: Watchdog.hh:51
uint8_t as_uint8[4]
Definition: Types.h:136
static const uint8_t RES_REG
Definition: BMP085.hh:199
uint16_t ac4
Definition: BMP085.hh:182
static const uint8_t PRESSURE_CONV_CMD
Definition: BMP085.hh:205
uint16_t m_start
Definition: BMP085.hh:217
int16_t ac3
Definition: BMP085.hh:181
uint8_t m_cmd
Definition: BMP085.hh:214
int32_t B5
Definition: BMP085.hh:220
bool sample_pressure_request()
Definition: BMP085.cpp:96
#define PSTR(s)
Definition: Types.h:202
bool begin(Mode mode=ULTRA_LOW_POWER)
Definition: BMP085.cpp:34
bool read_pressure()
Definition: BMP085.cpp:113
int16_t mc
Definition: BMP085.hh:188
int32_t pressure() const
Definition: BMP085.hh:162
param_t m_param
Definition: BMP085.hh:208
int32_t m_pressure
Definition: BMP085.hh:223
int16_t md
Definition: BMP085.hh:189
int32_t as_int32
Definition: Types.h:132
Mode
Definition: BMP085.hh:59
IOStream & operator<<(IOStream &outs, BMP085 &bmp)
Definition: BMP085.cpp:158
void release()
Definition: TWI.cpp:58
int16_t ac2
Definition: BMP085.hh:180
static const uint8_t TEMP_CONV_CMD
Definition: BMP085.hh:202
void(* delay)(uint32_t ms)
int16_t ac1
Definition: BMP085.hh:179
static const uint8_t COEFF_REG
Definition: BMP085.hh:193
int read(void *buf, size_t size)
Definition: TWI.hh:326
const uint8_t BMP085::PRESSURE_CONV_MS[] __PROGMEM
Definition: BMP085.cpp:26
#define swap(a, b)
Definition: Canvas.cpp:164
int write(void *buf, size_t size)
Definition: TWI.hh:282
bool sample_temperature_request()
Definition: BMP085.cpp:51
void acquire(TWI::Driver *dev)
Definition: TWI.cpp:36
Mode m_mode
Definition: BMP085.hh:211
static const uint8_t CMD_REG
Definition: BMP085.hh:196
uint16_t ac5
Definition: BMP085.hh:183
int16_t temperature() const
Definition: BMP085.hh:151
uint16_t ac6
Definition: BMP085.hh:184
static const uint8_t TEMP_CONV_MS
Definition: BMP085.hh:169
bool read_temperature()
Definition: BMP085.cpp:68
#define UNLIKELY(x)
Definition: Types.h:153
int16_t b2
Definition: BMP085.hh:186
Definition: BMP085.hh:54
int16_t b1
Definition: BMP085.hh:185