Uncategorized

BMP280 Programming Notes v0.1

BMP280 Programming Notes v0.1

penzu link: https://penzu.com/p/05db0200





Contents

BMP280 Adapter

BMP280 I2C Device

BMP280 Driver


pyromori adapter tlfong01  2020may20hkt1501

pi@raspberrypi:/usr/local/lib/python3.7/dist-packages/i2cdevice $ ls
adapter.py  __init__.py  __pycache__
pi@raspberrypi:/usr/local/lib/python3.7/dist-packages/i2cdevice $ cat adapter.py
class Adapter:
“””
Must implement `_decode()` and `_encode()`.
“””
def _decode(self, value):
raise NotImplementedError

def _encode(self, value):
raise NotImplementedError
class LookupAdapter(Adapter):
“””Adaptor with a dictionary of values.

:param lookup_table: A dictionary of one or more key/value pairs where the key is the human-readable value and the value is the bitwise register value

“””
def __init__(self, lookup_table, snap=True):
self.lookup_table = lookup_table
self.snap = snap

def _decode(self, value):
for k, v in self.lookup_table.items():
if v == value:
return k
raise ValueError(“{} not in lookup table”.format(value))

def _encode(self, value):
if self.snap and type(value) in [int, float]:
value = min(list(self.lookup_table.keys()), key=lambda x: abs(x – value))
return self.lookup_table[value]

class U16ByteSwapAdapter(Adapter):
“””Adaptor to swap the bytes in a 16bit integer.”””
def _byteswap(self, value):
return (value >> 8) | ((value & 0xFF) << 8)

def _decode(self, value):
return self._byteswap(value)

def _encode(self, value):
return self._byteswap(value)
pi@raspberrypi:/usr/local/lib/python3.7/dist-packages/i2cdevice $


pyromori i2c_device tlfong01  2020may20hkt1501

pi@raspberrypi:/usr/local/lib/python3.7/dist-packages/i2cdevice $ ls
adapter.py  __init__.py  __pycache__
pi@raspberrypi:/usr/local/lib/python3.7/dist-packages/i2cdevice $ cat __init__.py

from collections import namedtuple

__version__ = ‘0.0.6’
def _mask_width(value, bit_width=8):
“””Get the width of a bitwise mask

ie: 0b000111 = 3
“””
value >>= _trailing_zeros(value, bit_width)
return value.bit_length()

def _leading_zeros(value, bit_width=8):
“””Count leading zeros on a binary number with a given bit_width

ie: 0b0011 = 2

Used for shifting around values after masking.
“””
count = 0
for _ in range(bit_width):
if value & (1 << (bit_width – 1)):
return count
count += 1
value <<= 1
return count
def _trailing_zeros(value, bit_width=8):
“””Count trailing zeros on a binary number with a given bit_width

ie: 0b11000 = 3

Used for shifting around values after masking.
“””
count = 0
for _ in range(bit_width):
if value & 1:
return count
count += 1
value >>= 1
return count
def _int_to_bytes(value, length, endianness=’big’):
try:
return value.to_bytes(length, endianness)
except AttributeError:
output = bytearray()
for x in range(length):
offset = x * 8
mask = 0xff << offset
output.append((value & mask) >> offset)
if endianness == ‘big’:
output.reverse()
return output

class MockSMBus:

def __init__(self, i2c_bus, default_registers=None):
self.regs = [0 for _ in range(255)]
if default_registers is not None:
for index in default_registers.keys():
self.regs[index] = default_registers.get(index)

def write_i2c_block_data(self, i2c_address, register, values):
self.regs[register:register + len(values)] = values

def read_i2c_block_data(self, i2c_address, register, length):
return self.regs[register:register + length]
class _RegisterProxy(object):
“””Register Proxy

This proxy catches lookups against non existent get_fieldname and set_fieldname methods
and converts them into calls against the device’s get_field and set_field methods with
the appropriate options.

This means device.register.set_field(value) and device.register.get_field(value) will work
and also transparently update the underlying device without the register or field objects
having to know anything about how data is written/read/stored.

“””
def __init__(self, device, register):
self.device = device
self.register = register

def __getattribute__(self, name):
if name.startswith(“get_”):
name = name.replace(“get_”, “”)
return lambda: self.device.get_field(self.register.name, name)
if name.startswith(“set_”):
name = name.replace(“set_”, “”)
return lambda value: self.device.set_field(self.register.name, name, value)
return object.__getattribute__(self, name)

def write(self):
return self.device.write_register(self.register.name)

def read(self):
return self.device.read_register(self.register.name)

def __enter__(self):
self.device.read_register(self.register.name)
self.device.lock_register(self.register.name)
return self

def __exit__(self, exception_type, exception_value, exception_traceback):
self.device.unlock_register(self.register.name)
class Register():
“””Store information about an i2c register”””
def __init__(self, name, address, fields=None, bit_width=8, read_only=False, volatile=True):
self.name = name
self.address = address
self.bit_width = bit_width
self.read_only = read_only
self.volatile = volatile
self.is_read = False
self.fields = {}

for field in fields:
self.fields[field.name] = field

self.namedtuple = namedtuple(self.name, sorted(self.fields))
class BitField():
“””Store information about a field or flag in an i2c register”””
def __init__(self, name, mask, adapter=None, bit_width=8, read_only=False):
self.name = name
self.mask = mask
self.adapter = adapter
self.bit_width = bit_width
self.read_only = read_only
class BitFlag(BitField):
def __init__(self, name, bit, read_only=False):
BitField.__init__(self, name, 1 << bit, adapter=None, bit_width=8, read_only=read_only)
class Device(object):
def __init__(self, i2c_address, i2c_dev=None, bit_width=8, registers=None):
self._bit_width = bit_width

self.locked = {}
self.registers = {}
self.values = {}

if type(i2c_address) is list:
self._i2c_addresses = i2c_address
self._i2c_address = i2c_address[0]
else:
self._i2c_addresses = [i2c_address]
self._i2c_address = i2c_address

self._i2c = i2c_dev

if self._i2c is None:
import smbus
self._i2c = smbus.SMBus(1)

for register in registers:
self.locked[register.name] = False
self.values[register.name] = 0
self.registers[register.name] = register
self.__dict__[register.name] = _RegisterProxy(self, register)

def lock_register(self, name):
self.locked[name] = True

def unlock_register(self, name):
self.locked[name] = False

def read_register(self, name):
register = self.registers[name]
if register.volatile or not register.is_read:
self.values[register.name] = self._i2c_read(register.address, register.bit_width)
register.is_read = True
return self.values[register.name]

def write_register(self, name):
register = self.registers[name]
return self._i2c_write(register.address, self.values[register.name], register.bit_width)

def get_addresses(self):
return self._i2c_addresses

def select_address(self, address):
if address in self._i2c_addresses:
self._i2c_address = address
return True
raise ValueError(“Address {:02x} invalid!”.format(address))

def next_address(self):
next_addr = self._i2c_addresses.index(self._i2c_address)
next_addr += 1
next_addr %= len(self._i2c_addresses)
self._i2c_address = self._i2c_addresses[next_addr]
return self._i2c_address

def set(self, register, **kwargs):
“””Write one or more fields on a device register.

Accepts multiple keyword arguments, one for each field to write.

:param register: Name of register to write.

“””
self.read_register(register)
self.lock_register(register)
for field in kwargs.keys():
value = kwargs.get(field)
self.set_field(register, field, value)
self.write_register(register)
self.unlock_register(register)

def get(self, register):
“””Get a namedtuple containing register fields.

:param register: Name of register to retrieve

“””
result = {}
self.read_register(register)
for field in self.registers[register].fields:
result[field] = self.get_field(register, field)
return self.registers[register].namedtuple(**result)

def get_field(self, register, field):
register = self.registers[register]
field = register.fields[field]

if not self.locked[register.name]:
self.read_register(register.name)

value = self.values[register.name]

value = (value & field.mask) >> _trailing_zeros(field.mask, register.bit_width)

if field.adapter is not None:
value = field.adapter._decode(value)

return value

def set_field(self, register, field, value):
register = self.registers[register]
field = register.fields[field]
shift = _trailing_zeros(field.mask, register.bit_width)

if field.adapter is not None:
value = field.adapter._encode(value)

if not self.locked[register.name]:
self.read_register(register.name)

reg_value = self.values[register.name]

reg_value &= ~field.mask
reg_value |= (value << shift) & field.mask

self.values[register.name] = reg_value

if not self.locked[register.name]:
self.write_register(register.name)

def get_register(self, register):
register = self.registers[register]
return self._i2c_read(register.address, register.bit_width)

def _i2c_write(self, register, value, bit_width):
values = _int_to_bytes(value, bit_width // self._bit_width, ‘big’)
values = list(values)
self._i2c.write_i2c_block_data(self._i2c_address, register, values)

def _i2c_read(self, register, bit_width):
value = 0
for x in self._i2c.read_i2c_block_data(self._i2c_address, register, bit_width // self._bit_width):
value <<= 8
value |= x
return value
pi@raspberrypi:/usr/local/lib/python3.7/dist-packages/i2cdevice $


pyromori bmp280 driver (formatted) tlfong  2020may20hkt1501

# pi@raspberrypi:/usr/local/lib/python3.7/dist-packages/bmp280 $ cat __init__.py
# “””BMP280 Driver.”””

from i2cdevice import Device, Register, BitField, _int_to_bytes
from i2cdevice.adapter import LookupAdapter, Adapter
import struct

__version__ = ‘0.0.3’

CHIP_ID = 0x58
I2C_ADDRESS_GND = 0x76
I2C_ADDRESS_VCC = 0x77

class S16Adapter(Adapter):
“””Convert unsigned 16bit integer to signed.”””

def _decode(self, value):
return struct.unpack(‘<h’, _int_to_bytes(value, 2))[0]

class U16Adapter(Adapter):
“””Convert from bytes to an unsigned 16bit integer.”””

def _decode(self, value):
return struct.unpack(‘<H’, _int_to_bytes(value, 2))[0]

class BMP280Calibration():
def __init__(self):
self.dig_t1 = 0
self.dig_t2 = 0
self.dig_t3 = 0

self.dig_p1 = 0
self.dig_p2 = 0
self.dig_p3 = 0
self.dig_p4 = 0
self.dig_p5 = 0
self.dig_p6 = 0
self.dig_p7 = 0
self.dig_p8 = 0
self.dig_p9 = 0

self.temperature_fine = 0

def set_from_namedtuple(self, value):
# Iterate through a tuple supplied by i2cdevice
# and copy its values into the class attributes
for key in self.__dict__.keys():
try:
setattr(self, key, getattr(value, key))
except AttributeError:
pass

def compensate_temperature(self, raw_temperature):
var1 = (raw_temperature / 16384.0 – self.dig_t1 / 1024.0) * self.dig_t2
var2 = raw_temperature / 131072.0 – self.dig_t1 / 8192.0
var2 = var2 * var2 * self.dig_t3
self.temperature_fine = (var1 + var2)
return self.temperature_fine / 5120.0

def compensate_pressure(self, raw_pressure):
var1 = self.temperature_fine / 2.0 – 64000.0
var2 = var1 * var1 * self.dig_p6 / 32768.0
var2 = var2 + var1 * self.dig_p5 * 2
var2 = var2 / 4.0 + self.dig_p4 * 65536.0
var1 = (self.dig_p3 * var1 * var1 / 524288.0 + self.dig_p2 * var1) / 524288.0
var1 = (1.0 + var1 / 32768.0) * self.dig_p1
pressure = 1048576.0 – raw_pressure
pressure = (pressure – var2 / 4096.0) * 6250.0 / var1
var1 = self.dig_p9 * pressure * pressure / 2147483648.0
var2 = pressure * self.dig_p8 / 32768.0
return pressure + (var1 + var2 + self.dig_p7) / 16.0

class BMP280:
def __init__(self, i2c_addr=I2C_ADDRESS_GND, i2c_dev=None):
self.calibration = BMP280Calibration()
self._is_setup = False
self._i2c_addr = i2c_addr
self._i2c_dev = i2c_dev
self._bmp280 = Device([I2C_ADDRESS_GND, I2C_ADDRESS_VCC], i2c_dev=self._i2c_dev, bit_width=8,             registers=(
Register(‘CHIP_ID’, 0xD0, fields=(
BitField(‘id’, 0xFF),
)),
Register(‘RESET’, 0xE0, fields=(
BitField(‘reset’, 0xFF),
)),
Register(‘STATUS’, 0xF3, fields=(
BitField(‘measuring’, 0b00001000),  # 1 when conversion is running
BitField(‘im_update’, 0b00000001),  # 1 when NVM data is being copied
)),
Register(‘CTRL_MEAS’, 0xF4, fields=(
BitField(‘osrs_t’, 0b11100000,   # Temperature oversampling
adapter=LookupAdapter({
1: 0b001,
2: 0b010,
4: 0b011,
8: 0b100,
16: 0b101
})),
BitField(‘osrs_p’, 0b00011100,   # Pressure oversampling
adapter=LookupAdapter({
1: 0b001,
2: 0b010,
4: 0b011,
8: 0b100,
16: 0b101})),
BitField(‘mode’, 0b00000011,     # Power mode
adapter=LookupAdapter({
‘sleep’: 0b00,
‘forced’: 0b10,
‘normal’: 0b11})),
)),
Register(‘CONFIG’, 0xF5, fields=(
BitField(‘t_sb’, 0b11100000,     # Temp standby duration in normal mode
adapter=LookupAdapter({
0.5: 0b000,
62.5: 0b001,
125: 0b010,
250: 0b011,
500: 0b100,
1000: 0b101,
2000: 0b110,
4000: 0b111})),
BitField(‘filter’, 0b00011100),                   # Controls the time constant of the IIR                     filter
BitField(‘spi3w_en’, 0b0000001, read_only=True),  # Enable 3-wire SPI interface when set                         to 1. IE: Don’t set this bit!
)),
Register(‘DATA’, 0xF7, fields=(
BitField(‘temperature’, 0x000000FFFFF0),
BitField(‘pressure’, 0xFFFFF0000000),
), bit_width=48),
Register(‘CALIBRATION’, 0x88, fields=(
BitField(‘dig_t1’, 0xFFFF << 16 * 11, adapter=U16Adapter()),   # 0x88 0x89
BitField(‘dig_t2’, 0xFFFF << 16 * 10, adapter=S16Adapter()),   # 0x8A 0x8B
BitField(‘dig_t3’, 0xFFFF << 16 * 9, adapter=S16Adapter()),    # 0x8C 0x8D
BitField(‘dig_p1’, 0xFFFF << 16 * 8, adapter=U16Adapter()),    # 0x8E 0x8F
BitField(‘dig_p2’, 0xFFFF << 16 * 7, adapter=S16Adapter()),    # 0x90 0x91
BitField(‘dig_p3’, 0xFFFF << 16 * 6, adapter=S16Adapter()),    # 0x92 0x93
BitField(‘dig_p4’, 0xFFFF << 16 * 5, adapter=S16Adapter()),    # 0x94 0x95
BitField(‘dig_p5’, 0xFFFF << 16 * 4, adapter=S16Adapter()),    # 0x96 0x97
BitField(‘dig_p6’, 0xFFFF << 16 * 3, adapter=S16Adapter()),    # 0x98 0x99
BitField(‘dig_p7’, 0xFFFF << 16 * 2, adapter=S16Adapter()),    # 0x9A 0x9B
BitField(‘dig_p8’, 0xFFFF << 16 * 1, adapter=S16Adapter()),    # 0x9C 0x9D
BitField(‘dig_p9’, 0xFFFF << 16 * 0, adapter=S16Adapter()),    # 0x9E 0x9F
), bit_width=192)
))

 

    def setup(self):
if self._is_setup:
return
self._is_setup = True

self._bmp280.select_address(self._i2c_addr)

try:
chip = self._bmp280.get(‘CHIP_ID’)
if chip.id != CHIP_ID:
raise RuntimeError(“Unable to find bmp280 on 0x{:02x}, CHIP_ID returned {:02x}”.format(self._i2c_addr, chip.id))
except IOError:
raise RuntimeError(“Unable to find bmp280 on 0x{:02x}, IOError”.format(self._i2c_addr))

self._bmp280.set(‘CTRL_MEAS’,
mode=’normal’,
osrs_t=16,
osrs_p=16)

self._bmp280.set(‘CONFIG’,
t_sb=500,
filter=2)

self.calibration.set_from_namedtuple(self._bmp280.get(‘CALIBRATION’))

def update_sensor(self):
self.setup()

raw = self._bmp280.get(‘DATA’)

self.temperature = self.calibration.compensate_temperature(raw.temperature)
self.pressure = self.calibration.compensate_pressure(raw.pressure) / 100.0

def get_temperature(self):
self.update_sensor()
return self.temperature

def get_pressure(self):
self.update_sensor()
return self.pressure

def get_altitude(self, qnh=1013.25):
self.update_sensor()
pressure = self.get_pressure()
altitude = 44330.0 * (1.0 – pow(pressure / qnh, (1.0 / 5.255)))
return altitude

# pi@raspberrypi:/usr/local/lib/python3.7/dist-packages/bmp280 $



pyromori bmp280 driver (raw)  tlfong  2020may20hkt1501

# pi@raspberrypi:/usr/local/lib/python3.7/dist-packages/bmp280 $ cat __init__.py
# “””BMP280 Driver.”””

from i2cdevice import Device, Register, BitField, _int_to_bytes
from i2cdevice.adapter import LookupAdapter, Adapter
import struct

__version__ = ‘0.0.3’

CHIP_ID = 0x58
I2C_ADDRESS_GND = 0x76
I2C_ADDRESS_VCC = 0x77

class S16Adapter(Adapter):
“””Convert unsigned 16bit integer to signed.”””

def _decode(self, value):
return struct.unpack(‘<h’, _int_to_bytes(value, 2))[0]

class U16Adapter(Adapter):
“””Convert from bytes to an unsigned 16bit integer.”””

def _decode(self, value):
return struct.unpack(‘<H’, _int_to_bytes(value, 2))[0]

class BMP280Calibration():
def __init__(self):
self.dig_t1 = 0
self.dig_t2 = 0
self.dig_t3 = 0

self.dig_p1 = 0
self.dig_p2 = 0
self.dig_p3 = 0
self.dig_p4 = 0
self.dig_p5 = 0
self.dig_p6 = 0
self.dig_p7 = 0
self.dig_p8 = 0
self.dig_p9 = 0

self.temperature_fine = 0

def set_from_namedtuple(self, value):
# Iterate through a tuple supplied by i2cdevice
# and copy its values into the class attributes
for key in self.__dict__.keys():
try:
setattr(self, key, getattr(value, key))
except AttributeError:
pass

def compensate_temperature(self, raw_temperature):
var1 = (raw_temperature / 16384.0 – self.dig_t1 / 1024.0) * self.dig_t2
var2 = raw_temperature / 131072.0 – self.dig_t1 / 8192.0
var2 = var2 * var2 * self.dig_t3
self.temperature_fine = (var1 + var2)
return self.temperature_fine / 5120.0

def compensate_pressure(self, raw_pressure):
var1 = self.temperature_fine / 2.0 – 64000.0
var2 = var1 * var1 * self.dig_p6 / 32768.0
var2 = var2 + var1 * self.dig_p5 * 2
var2 = var2 / 4.0 + self.dig_p4 * 65536.0
var1 = (self.dig_p3 * var1 * var1 / 524288.0 + self.dig_p2 * var1) / 524288.0
var1 = (1.0 + var1 / 32768.0) * self.dig_p1
pressure = 1048576.0 – raw_pressure
pressure = (pressure – var2 / 4096.0) * 6250.0 / var1
var1 = self.dig_p9 * pressure * pressure / 2147483648.0
var2 = pressure * self.dig_p8 / 32768.0
return pressure + (var1 + var2 + self.dig_p7) / 16.0

class BMP280:
def __init__(self, i2c_addr=I2C_ADDRESS_GND, i2c_dev=None):
self.calibration = BMP280Calibration()
self._is_setup = False
self._i2c_addr = i2c_addr
self._i2c_dev = i2c_dev
self._bmp280 = Device([I2C_ADDRESS_GND, I2C_ADDRESS_VCC], i2c_dev=self._i2c_dev, bit_width=8, registers=(
Register(‘CHIP_ID’, 0xD0, fields=(
BitField(‘id’, 0xFF),
)),
Register(‘RESET’, 0xE0, fields=(
BitField(‘reset’, 0xFF),
)),
Register(‘STATUS’, 0xF3, fields=(
BitField(‘measuring’, 0b00001000),  # 1 when conversion is running
BitField(‘im_update’, 0b00000001),  # 1 when NVM data is being copied
)),
Register(‘CTRL_MEAS’, 0xF4, fields=(
BitField(‘osrs_t’, 0b11100000,   # Temperature oversampling
adapter=LookupAdapter({
1: 0b001,
2: 0b010,
4: 0b011,
8: 0b100,
16: 0b101
})),
BitField(‘osrs_p’, 0b00011100,   # Pressure oversampling
adapter=LookupAdapter({
1: 0b001,
2: 0b010,
4: 0b011,
8: 0b100,
16: 0b101})),
BitField(‘mode’, 0b00000011,     # Power mode
adapter=LookupAdapter({
‘sleep’: 0b00,
‘forced’: 0b10,
‘normal’: 0b11})),
)),
Register(‘CONFIG’, 0xF5, fields=(
BitField(‘t_sb’, 0b11100000,     # Temp standby duration in normal mode
adapter=LookupAdapter({
0.5: 0b000,
62.5: 0b001,
125: 0b010,
250: 0b011,
500: 0b100,
1000: 0b101,
2000: 0b110,
4000: 0b111})),
BitField(‘filter’, 0b00011100),                   # Controls the time constant of the IIR filter
BitField(‘spi3w_en’, 0b0000001, read_only=True),  # Enable 3-wire SPI interface when set to 1. IE: Don’t set this bit!
)),
Register(‘DATA’, 0xF7, fields=(
BitField(‘temperature’, 0x000000FFFFF0),
BitField(‘pressure’, 0xFFFFF0000000),
), bit_width=48),
Register(‘CALIBRATION’, 0x88, fields=(
BitField(‘dig_t1’, 0xFFFF << 16 * 11, adapter=U16Adapter()),   # 0x88 0x89
BitField(‘dig_t2’, 0xFFFF << 16 * 10, adapter=S16Adapter()),   # 0x8A 0x8B
BitField(‘dig_t3’, 0xFFFF << 16 * 9, adapter=S16Adapter()),    # 0x8C 0x8D
BitField(‘dig_p1’, 0xFFFF << 16 * 8, adapter=U16Adapter()),    # 0x8E 0x8F
BitField(‘dig_p2’, 0xFFFF << 16 * 7, adapter=S16Adapter()),    # 0x90 0x91
BitField(‘dig_p3’, 0xFFFF << 16 * 6, adapter=S16Adapter()),    # 0x92 0x93
BitField(‘dig_p4’, 0xFFFF << 16 * 5, adapter=S16Adapter()),    # 0x94 0x95
BitField(‘dig_p5’, 0xFFFF << 16 * 4, adapter=S16Adapter()),    # 0x96 0x97
BitField(‘dig_p6’, 0xFFFF << 16 * 3, adapter=S16Adapter()),    # 0x98 0x99
BitField(‘dig_p7’, 0xFFFF << 16 * 2, adapter=S16Adapter()),    # 0x9A 0x9B
BitField(‘dig_p8’, 0xFFFF << 16 * 1, adapter=S16Adapter()),    # 0x9C 0x9D
BitField(‘dig_p9’, 0xFFFF << 16 * 0, adapter=S16Adapter()),    # 0x9E 0x9F
), bit_width=192)
))

def setup(self):
if self._is_setup:
return
self._is_setup = True

self._bmp280.select_address(self._i2c_addr)

try:
chip = self._bmp280.get(‘CHIP_ID’)
if chip.id != CHIP_ID:
raise RuntimeError(“Unable to find bmp280 on 0x{:02x}, CHIP_ID returned {:02x}”.format(self._i2c_addr, chip.id))
except IOError:
raise RuntimeError(“Unable to find bmp280 on 0x{:02x}, IOError”.format(self._i2c_addr))

self._bmp280.set(‘CTRL_MEAS’,
mode=’normal’,
osrs_t=16,
osrs_p=16)

self._bmp280.set(‘CONFIG’,
t_sb=500,
filter=2)

self.calibration.set_from_namedtuple(self._bmp280.get(‘CALIBRATION’))

def update_sensor(self):
self.setup()

raw = self._bmp280.get(‘DATA’)

self.temperature = self.calibration.compensate_temperature(raw.temperature)
self.pressure = self.calibration.compensate_pressure(raw.pressure) / 100.0

def get_temperature(self):
self.update_sensor()
return self.temperature

def get_pressure(self):
self.update_sensor()
return self.pressure

def get_altitude(self, qnh=1013.25):
self.update_sensor()
pressure = self.get_pressure()
altitude = 44330.0 * (1.0 – pow(pressure / qnh, (1.0 / 5.255)))
return altitude

# pi@raspberrypi:/usr/local/lib/python3.7/dist-packages/bmp280 $

.END

3:38pm Wed. 5/20/2020

.END

 

Categories: Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.