Class: Denko::Sensor::BMP180
Constant Summary
collapse
- SOFT_RESET =
Write this to register 0xE0 for soft reset
0xB6
- OVERSAMPLE_FACTORS =
Pressure Oversample Setting Values
General formula:
2 ** n, where n is the decimal value of the bits, up to 8x pressure oversampling.
{
1 => 0b00,
2 => 0b01,
4 => 0b10,
8 => 0b11,
}
Instance Attribute Summary collapse
#interrupts_enabled, #thread
#callback_mutex
#i2c_frequency, #i2c_repeated_start
#address
#board
Instance Method Summary
collapse
#poll, #poll_using, #stop
#enable_interrupts, included, #stop, #stop_thread, #threaded, #threaded_loop
#read, #read_using, #wait_for_read
#add_callback, #callbacks, #initialize, #remove_callback, #update
#initialize, #state
#i2c_read, #i2c_write
#atomically
#initialize, #micro_delay
Instance Attribute Details
#calibration_data_loaded ⇒ Object
196
197
198
|
# File 'lib/denko/sensor/bmp180.rb', line 196
def calibration_data_loaded
@calibration_data_loaded
end
|
#measurement_time ⇒ Object
Returns the value of attribute measurement_time.
53
54
55
|
# File 'lib/denko/sensor/bmp180.rb', line 53
def measurement_time
@measurement_time
end
|
Instance Method Details
#[](key) ⇒ Object
133
134
135
136
137
|
# File 'lib/denko/sensor/bmp180.rb', line 133
def [](key)
@state_mutex.synchronize do
return @state[key]
end
end
|
#_read ⇒ Object
91
92
93
94
95
96
97
98
99
100
101
|
# File 'lib/denko/sensor/bmp180.rb', line 91
def _read
get_calibration_data unless calibration_data_loaded
_start_read_temperature
sleep(@measurement_time)
i2c_read 0xF6, 2
_start_read_pressure
sleep(@measurement_time)
i2c_read 0xF6, 3
end
|
#_start_read_pressure ⇒ Object
86
87
88
89
|
# File 'lib/denko/sensor/bmp180.rb', line 86
def _start_read_pressure
@register = 0x34 | (@oss << 6)
write_settings
end
|
#_start_read_temperature ⇒ Object
81
82
83
84
|
# File 'lib/denko/sensor/bmp180.rb', line 81
def _start_read_temperature
@register = 0x2E
write_settings
end
|
#after_initialize(options = {}) ⇒ Object
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
# File 'lib/denko/sensor/bmp180.rb', line 28
def after_initialize(options={})
super(options)
@reading = { temperature: nil, pressure: nil }
self.state = { temperature: nil, pressure: nil }
@register = 0b00001110
@calibration_data_loaded = false
@oss = 0b00
@raw_bytes = [0, 0, 0, 0, 0]
soft_reset
end
|
#before_initialize(options = {}) ⇒ Object
23
24
25
26
|
# File 'lib/denko/sensor/bmp180.rb', line 23
def before_initialize(options={})
@i2c_address = 0x77
super(options)
end
|
#decode_pressure(bytes, b5) ⇒ Object
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
# File 'lib/denko/sensor/bmp180.rb', line 166
def decode_pressure(bytes, b5)
up = ((bytes[2] << 16) | (bytes[3] << 8) | (bytes[4])) >> (8 - @oss)
b6 = b5 - 4000
x1 = (@calibration[:b2] * (b6 * b6 / 4096)) / 2048
x2 = @calibration[:ac2] * b6 / 2048
x3 = x1 + x2
b3 = (((@calibration[:ac1]*4 + x3) << @oss) + 2) / 4
x1 = @calibration[:ac3] * b6 / 8192
x2 = (@calibration[:b1] * (b6 * b6 / 4096)) / 65536
x3 = (x1 + x2 + 2) / 4
b4 = (@calibration[:ac4] * ((x3+32768) & 0xFFFF_FFFF)) / 32768
b7 = ((up & 0xFFFF_FFFF) - b3) * (50000 >> @oss)
if (b7 < 0x8000_0000)
p = (b7 * 2) / b4
else
p = (b7 / b4) * 2
end
x1 = (p / 256) * (p / 256)
x1 = (x1 * 3038) / 65536
x2 = (-7357 * p) / 65536
p = p + (x1 + x2 + 3791) / 16
pressure = p.to_f
end
|
#decode_reading(bytes) ⇒ Object
142
143
144
145
146
147
|
# File 'lib/denko/sensor/bmp180.rb', line 142
def decode_reading(bytes)
temperature, b5 = decode_temperature(bytes)
@reading[:temperature] = temperature
@reading[:pressure] = decode_pressure(bytes, b5)
@reading
end
|
#decode_temperature(bytes) ⇒ Object
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
# File 'lib/denko/sensor/bmp180.rb', line 149
def decode_temperature(bytes)
ut = bytes[0] << 8 | bytes[1]
x1 = (ut - @calibration[:ac6]) * @calibration[:ac5] / 32768
x2 = (@calibration[:mc] * 2048) / (x1 + @calibration[:md])
b5 = x1 + x2
temperature = (b5 + 8) / 160.0
[temperature, b5]
end
|
#get_calibration_data ⇒ Object
198
199
200
201
|
# File 'lib/denko/sensor/bmp180.rb', line 198
def get_calibration_data
read_using -> { i2c_read(0xAA, 22) }
end
|
#pre_callback_filter(data) ⇒ Object
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/denko/sensor/bmp180.rb', line 103
def pre_callback_filter(data)
if data.length == 2
@raw_bytes[0] = data[0]
@raw_bytes[1] = data[1]
elsif data.length == 3
@raw_bytes[2] = data[0]
@raw_bytes[3] = data[1]
@raw_bytes[4] = data[2]
return decode_reading(@raw_bytes)
elsif data.length == 22
process_calibration(data)
end
return nil
end
|
#pressure_samples=(factor) ⇒ Object
68
69
70
71
|
# File 'lib/denko/sensor/bmp180.rb', line 68
def pressure_samples=(factor)
raise ArgumentError, "invalid oversampling factor: #{factor}" unless OVERSAMPLE_FACTORS.keys.include? factor
@oss = OVERSAMPLE_FACTORS[factor]
end
|
#process_calibration(bytes) ⇒ Object
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
# File 'lib/denko/sensor/bmp180.rb', line 203
def process_calibration(bytes)
if bytes
@calibration = {
ac1: bytes[0..1].pack('C*').unpack('s>')[0],
ac2: bytes[2..3].pack('C*').unpack('s>')[0],
ac3: bytes[4..5].pack('C*').unpack('s>')[0],
ac4: bytes[6..7].pack('C*').unpack('S>')[0],
ac5: bytes[8..9].pack('C*').unpack('S>')[0],
ac6: bytes[10..11].pack('C*').unpack('S>')[0],
b1: bytes[12..13].pack('C*').unpack('s>')[0],
b2: bytes[14..15].pack('C*').unpack('s>')[0],
mb: bytes[16..17].pack('C*').unpack('s>')[0],
mc: bytes[18..19].pack('C*').unpack('s>')[0],
md: bytes[20..21].pack('C*').unpack('s>')[0],
}
@calibration_data_loaded = true
end
end
|
#soft_reset ⇒ Object
49
50
51
|
# File 'lib/denko/sensor/bmp180.rb', line 49
def soft_reset
i2c_write(SOFT_RESET)
end
|
#update_measurement_time ⇒ Object
55
56
57
58
59
60
61
62
63
64
65
66
|
# File 'lib/denko/sensor/bmp180.rb', line 55
def update_measurement_time
oversample_exponent = (@register & 0b11000000) >> 6
= (2 ** oversample_exponent) - 1
= * 3
total_time = 4.5 +
@measurement_time = (total_time + 1) / 1000.0
end
|
#update_state(reading) ⇒ Object
123
124
125
126
127
128
129
130
131
|
# File 'lib/denko/sensor/bmp180.rb', line 123
def update_state(reading)
if reading.class == Hash
@state_mutex.synchronize do
@state[:temperature] = reading[:temperature]
@state[:pressure] = reading[:pressure]
end
end
end
|
#write_settings ⇒ Object
73
74
75
76
|
# File 'lib/denko/sensor/bmp180.rb', line 73
def write_settings
update_measurement_time
i2c_write [0xF4, @register]
end
|