#!/usr/bin/env python3 # vim: set ai et ts=4 sw=4: # (c) Aleksander Alekseev 2018 # https://eax.me/ import sys import time import subprocess from struct import pack, unpack # oversampling setting oss = 0 # 0..3 def read(addr): cmd = "i2cget -y 0 0x77 0x{:02X}".format(addr) res = subprocess.check_output(cmd, shell=True) res = res.decode('utf-8').strip() return int(res[2:4], base = 16) def write(addr, val): cmd = "i2cset -y 0 0x77 0x{:02X} 0x{:02X}".format(addr, val) code = subprocess.call(cmd, shell=True) if code != 0: print("Command '{}' returned {}".format(cmd, code)) sys.exit(1) def signed_short(b1, b2): return unpack('h', pack('BB', b1, b2))[0] def unsigned_short(b1, b2): return (b1 << 8) | b2 # return unpack('H', pack('BB', b1, b2))[0] # read calibration data ac1 = signed_short(read(0xAA), read(0xAB)) ac2 = signed_short(read(0xAC), read(0xAD)) ac3 = signed_short(read(0xAE), read(0xAF)) ac4 = unsigned_short(read(0xB0), read(0xB1)) ac5 = unsigned_short(read(0xB2), read(0xB3)) ac6 = unsigned_short(read(0xB4),read(0xB5)) b1 = signed_short(read(0xB6), read(0xB7)) b2 = signed_short(read(0xB8), read(0xB9)) mb = signed_short(read(0xBA), read(0xBB)) mc = signed_short(read(0xBC), read(0xBD)) md = signed_short(read(0xBE), read(0xBF)) while True: # read uncompensated temperature value write(0xF4, 0x2E) time.sleep(0.005) ut = (read(0xF6) << 8) | read(0xF7) # read uncompensated pressure value write(0xF4, 0x34 + (oss << 6)) time.sleep(0.005) up = ((((read(0xF6) << 8) | read(0xF7)) << 8) | read(0xF8)) >> (8 - oss) # calculate true temperature x1 = ((ut - ac6)*ac5) / (2**15) x2 = (mc * (2**11)) / (x1 + md) b5 = x1 + x2 t = (b5 + 8) / (2**4) # temperature in 0.1 C to temperature in C t = t / 10 # calculate true pressure b6 = b5 - 4000 x1 = (b2 * (b6 * b6 / (2**12))) / (2**11) x2 = (ac2 * b6) / (2**11) x3 = x1 + x2 b3 = ((int(ac1*4 + x3) << oss) + 2) / 4 x1 = ac3 * b6 / (2**13) x2 = (b1 * (b6 * b6 / (2**12))) / (2**16) x3 = ((x1 + x2) + 2) / (2**2) b4 = ac4 * (x3 + 32768) / (2**15) b7 = (up - b3) * (50000 >> oss) p = 0 if b7 < 0x80000000: p = (b7 * 2) / b4 else: p = (b7 / b4) * 2 x1 = (p / (2**8)) ** 2 x1 = (x1 * 3038) / (2**16) x2 = (-7357 * p) / (2**16) p = p + (x1 + x2 + 3791) / (2**4) # pascal to millimeter of mercury p = p*0.00750062 print("t = {:.1f} C, p = {:.1f} mmHg".format(t, p)) time.sleep(1)