Source code for PyExpLabSys.drivers.bosch_bme280
import time
import smbus
# from ctypes import c_short
# from ctypes import c_byte
# from ctypes import c_ubyte
[docs]class BoschBME280(object):
"""
Class for reading pressure, humidity and temperature from BoschBME280.
Hint for implementation found at
http://forum.arduino.cc/index.php?topic=285116.0
"""
[docs] def __init__(self):
self.bus = smbus.SMBus(1)
self.device_address = 0x77
# oversample_hum = 0b00000001 # Oversampling x 1
# oversample_hum = 0b00000010 # Oversampling x 2
# oversample_hum = 0b00000011 # Oversampling x 4
# oversample_hum = 0b00000100 # Oversampling x 8
oversample_hum = 0b00000101 # Oversampling x 16
self.bus.write_byte_data(self.device_address, 0xF2, oversample_hum)
# Oversample setting - same as above
oversample_temp = 0b00000101
oversample_pres = 0b00000101
mode = 0b11 # Normal mode
control = oversample_temp << 5 | oversample_pres << 2 | mode
self.bus.write_byte_data(self.device_address, 0xF4, control)
# 0b111: 20ms, 0b010: 125ms, 0b011: 250ms, 0b101: 1000ms
standby = 0b111
filter_set = 0b0 # off - 0b001: 2, 0b100: 16
config = standby << 5 | filter_set << 2
self.bus.write_byte_data(self.device_address, 0xF5, config)
self._read_calibration()
def _read_calibration(self):
# Read blocks of calibration data from EEPROM
# See Page 22 data sheet
cal1 = self.bus.read_i2c_block_data(self.device_address, 0x88, 24)
self.T = {}
self.T['1'] = cal1[1] * 256 + cal1[0]
# Principally these are signed, consider check
self.T['2'] = cal1[3] * 256 + cal1[2]
self.T['3'] = cal1[5] * 256 + cal1[4]
self.P = {}
self.P[1] = cal1[7] * 256 + cal1[6]
self.P[2] = cal1[9] * 256 + cal1[8]
self.P[3] = cal1[11] * 256 + cal1[10]
self.P[4] = cal1[13] * 256 + cal1[12]
self.P[5] = cal1[15] * 256 + cal1[14]
self.P[6] = cal1[17] * 256 + cal1[16]
self.P[7] = cal1[19] * 256 + cal1[18]
self.P[8] = cal1[21] * 256 + cal1[20]
self.P[9] = cal1[23] * 256 + cal1[22]
for i in range(2, 10):
if self.P[i] > 2 ** 15:
self.P[i] = self.P[i] - 2 ** 16
self.H = {}
cal2 = self.bus.read_i2c_block_data(self.device_address, 0xA1, 1)
self.H[1] = cal2[0]
cal3 = self.bus.read_i2c_block_data(self.device_address, 0xE1, 7)
self.H[2] = cal3[1] * 256 + cal3[0]
self.H[3] = cal3[2]
self.H[4] = cal3[3] * 16 + cal3[4] % 16
self.H[5] = cal3[5] * 16 + (cal3[4] // 16)
self.H[6] = cal3[6]
def _calculate_temperature(self, temp_raw):
var1 = (temp_raw / 16384 - self.T['1'] / 1024) * self.T['2']
# Simplify!
var2 = (
((temp_raw / 16 - self.T['1']) * (temp_raw / 16 - self.T['1']))
/ 4096
* self.T['3']
/ 2 ** 14
)
t_fine = var1 + var2
# Which is correct?!?
temperature = t_fine / 5120
# temperature = (( t_fine * 5) + 128) / 256
# temperature = temperature / 100.0
return temperature, t_fine
def _calculate_pressure(self, pres_raw, t_fine):
v1 = t_fine / 2.0 - 64000.0
v2 = (((v1 / 4.0) * (v1 / 4.0)) / 2048) * self.P[6]
v2 += (v1 * self.P[5]) * 2.0
v2 = (v2 / 4.0) + (self.P[4] * 65536.0)
v1 = (
((self.P[3] * (((v1 / 4.0) * (v1 / 4.0)) / 8192)) / 8)
+ ((self.P[2] * v1) / 2.0)
) / 262144
v1 = ((32768 + v1) * self.P[1]) / 32768
if v1 == 0:
return 0
pressure = ((1048576 - pres_raw) - (v2 / 4096)) * 3125
if pressure < 0x80000000:
pressure = (pressure * 2.0) / v1
else:
pressure = (pressure / v1) * 2
v1 = (self.P[9] * (((pressure / 8.0) * (pressure / 8.0)) / 8192.0)) / 4096
v2 = ((pressure / 4.0) * self.P[8]) / 8192.0
pressure = pressure + ((v1 + v2 + self.P[7]) / 16.0)
return pressure / 100
def _calculate_humidity(self, hum_raw, t_fine):
humidity = t_fine - 76800.0
humidity = (hum_raw - (self.H[4] * 64.0 + self.H[5] / 2 ** 14 * humidity)) * (
self.H[2]
/ 2 ** 16
* (
1.0
+ self.H[6]
/ 2 ** 26
* humidity
* (1.0 + self.H[3] / 2 ** 26 * humidity)
)
)
humidity = humidity * (1.0 - self.H[1] * humidity / 2 ** 19)
if humidity > 100:
humidity = 100
elif humidity < 0:
humidity = 0
return humidity
def _read_ids(self):
(nr, version) = self.bus.read_i2c_block_data(self.device_address, 0xD0, 2)
# time.sleep(0.1)
return {'id_number:': nr, 'version': version}
def measuring(self):
data = self.bus.read_i2c_block_data(self.device_address, 0xF3, 1)
measure_bit = data[0] >> 3
return measure_bit
def read_all_values(self):
while not self.measuring():
time.sleep(0.01)
while self.measuring():
time.sleep(0.01)
data = self.bus.read_i2c_block_data(self.device_address, 0xF7, 8)
pres_raw = data[0] * 4096 + data[1] * 16 + data[2] // 16
temp_raw = data[3] * 4096 + data[4] * 16 + data[5] // 16
hum_raw = data[6] * 256 + data[7]
temperature, t_fine = self._calculate_temperature(temp_raw)
air_pressure = self._calculate_pressure(pres_raw, t_fine)
humidity = self._calculate_humidity(hum_raw, t_fine)
return_dict = {
'temperature': temperature,
'humidity': humidity,
'air_pressure': air_pressure,
}
return return_dict
if __name__ == '__main__':
BOSCH = BoschBME280()
t = time.time()
iterations = 20
for i in range(0, iterations):
values = BOSCH.read_all_values()
msg = 'Temperature: {:.2f}C, Pressure: {:.2f}Pa, Humidity: {:.2f}%'
print(
msg.format(
values['temperature'], values['air_pressure'], values['humidity']
)
)
print('Time pr iteration: {:.3f}s'.format((time.time() - t) / iterations))