大気圧センサー(BMP180)
工具箱をあさったら、I2C接続で使用できる大気圧センサーを見つけたので使用してみようかと思います
まずはモノ。単品でも、キットに付属でも入手できそうです
データシートです
これをある程度読み取れれば、使用可能です
https://www.sparkfun.com/datasheets/Components/General/BST-BMP085-DS000-05.pdf
サンプルプログラムです。
公式(?)のものも見つかりますが、動かなかったので手を入れています
このセンサーは温度センサーもついており、大気圧の算出に、その温度センサーの値も使用します
1秒ごとにセンサーから読み取り、温度と気圧をprintしてみているだけです
なお、1クラス1ファイルにする慣習があるようですが、このサンプルは2クラスと実行ルーチンを1ファイルにしてしまっています(適宜分けてもOK)
from time import sleep
import smbus
''' i2cクラス '''
class i2c:
# i2c オブジェクト
i2c = None
# i2c アドレス
ADR = None
''' コンストラクタ '''
def __init__(self, adr, bus = 1) -> None:
self.ADR = adr
self.i2c = smbus.SMBus(bus)
''' 符号あり8ビット読込 '''
def readS8(self, register):
result = self.i2c.read_byte_data(self.ADR, register)
if result > 127:
# 符号算出
result -= 256
return result
''' 符号あり16ビット読込(アドレス値は指定8ビット と 指定8ビット + 1) '''
def readS16(self, register):
hi = self.readS8(register)
lo = self.readU8(register+1)
return (hi << 8) + lo
''' 符号なし8ビット読込 '''
def readU8(self, register):
result = self.i2c.read_byte_data(self.ADR, register)
return result
''' 符号なし16ビット読込(アドレス値は指定8ビット と 指定8ビット + 1) '''
def readU16(self, register):
hi = self.readU8(register)
lo = self.readU8(register+1)
return (hi << 8) + lo
''' 指定ブロック読込 '''
def readBlockData(self, register, blocks):
block = self.i2c.read_i2c_block_data(self.ADR, register, blocks)
return block
''' 8ビット書込 '''
def write8(self, register, value):
self.i2c.write_byte_data(self.ADR, register, value)
''' 8ビット書込 '''
def writeByte(self, value):
self.i2c.write_byte(self.ADR, value)
class BMP085:
BMP085_CAL_AC1 = 0xAA
BMP085_CAL_AC2 = 0xAC
BMP085_CAL_AC3 = 0xAE
BMP085_CAL_AC4 = 0xB0
BMP085_CAL_AC5 = 0xB2
BMP085_CAL_AC6 = 0xB4
BMP085_CAL_B1 = 0xB6
BMP085_CAL_B2 = 0xB8
BMP085_CAL_MB = 0xBA
BMP085_CAL_MC = 0xBC
BMP085_CAL_MD = 0xBE
BMP085_CONTROL = 0xF4
BMP085_TEMPDATA = 0xF6
BMP085_PRESSUREDATA = 0xF6
BMP085_READTEMPCMD = 0x2E
BMP085_READPRESSURECMD = 0x34
MODE = 3
WAIT_TIME = [0.005, 0.014, 0.008, 0.026]
I2C_ADR = 0x77
i2c = None
''' コンストラクタ '''
def __init__(self) -> None:
# i2cオブジェクト
self.i2c = i2c(self.I2C_ADR)
''' キャリブレーション '''
def calibration(self):
# キャリブレーションデータ読込
self.cal_AC1 = self.i2c.readS16(self.BMP085_CAL_AC1)
self.cal_AC2 = self.i2c.readS16(self.BMP085_CAL_AC2)
self.cal_AC3 = self.i2c.readS16(self.BMP085_CAL_AC3)
self.cal_AC4 = self.i2c.readU16(self.BMP085_CAL_AC4)
self.cal_AC5 = self.i2c.readU16(self.BMP085_CAL_AC5)
self.cal_AC6 = self.i2c.readU16(self.BMP085_CAL_AC6)
self.cal_B1 = self.i2c.readS16(self.BMP085_CAL_B1)
self.cal_B2 = self.i2c.readS16(self.BMP085_CAL_B2)
self.cal_MB = self.i2c.readS16(self.BMP085_CAL_MB)
self.cal_MC = self.i2c.readS16(self.BMP085_CAL_MC)
self.cal_MD = self.i2c.readS16(self.BMP085_CAL_MD)
''' センサーから温度を取得 '''
def readUncpmpensatedTemp(self):
self.i2c.write8(self.BMP085_CONTROL, self.BMP085_READTEMPCMD)
sleep(0.026)
raw = self.i2c.readU16(self.BMP085_TEMPDATA)
return raw
''' センサーから気圧を取得 '''
def readUncpmpensatedPressure(self):
self.i2c.write8(self.BMP085_CONTROL, self.BMP085_READPRESSURECMD + (self.MODE << 6))
sleep(self.WAIT_TIME[self.MODE])
msb = self.i2c.readU8(self.BMP085_PRESSUREDATA)
lsb = self.i2c.readU8(self.BMP085_PRESSUREDATA+1)
xlsb = self.i2c.readU8(self.BMP085_PRESSUREDATA+2)
raw = ((msb << 16) + (lsb << 8) + xlsb) >> (8 - self.MODE)
return raw
''' 温度と気圧を算出 '''
def calcTemperaturePressure(self):
UT = self.readUncpmpensatedTemp()
UP = self.readUncpmpensatedPressure()
X1 = ((UT - self.cal_AC6) * self.cal_AC5) / 32768
X2 = (self.cal_MC * 2048) / (X1 + self.cal_MD)
B5 = X1 + X2
B6 = B5 - 4000
X1 = (self.cal_B2 * (B6 * B6) / 4096) / 2048
X2 = (self.cal_AC2 * B6) / 2048
X3 = X1 + X2
# 温度を算出しておく
temp = (B5 + 8) / 16 / 10
B3 = (((self.cal_AC1 * 4 + X3) * ( 2 ** self.MODE)) + 2) / 4
X1 = (self.cal_AC3 * B6) / 8192
X2 = (self.cal_B1 * ((B6 * B6) / 4096)) / 65536
X3 = ((X1 + X2) + 2) / 4
B4 = (self.cal_AC4 * (X3 + 32768)) / 32768
B7 = (UP - B3) * (50000 >> self.MODE)
if (B7 < 0x80000000):
press = int((B7 * 2) / B4)
else:
press = int((B7 / B4) * 2)
X1 = (press / 256 ) * (press / 256)
X1 = (X1 * 3038) / 65536
X2 = (-7357 * press) / 65536
press = press + ((X1 + X2 + 3791) / 16)
return temp, press
# インスタンス生成
bmp = BMP085()
# 初期化
bmp.calibration()
while True:
# 気温と気圧を取得
tempPress = bmp.calcTemperaturePressure()
# 表示
print(f'temp: {str(tempPress[0])[:5]} C')
print(f'prss: {str(tempPress[1] / 100.0 )[:6]} hPa')
sleep(1)