[modules] add bmm150
This commit is contained in:
parent
d733b4710e
commit
0a66a1cd66
|
@ -0,0 +1,957 @@
|
|||
from machine import I2C
|
||||
import time
|
||||
import ustruct
|
||||
|
||||
I2C_MODE = 1
|
||||
SPI_MODE = 2
|
||||
ENABLE_POWER = 1
|
||||
DISABLE_POWER = 0
|
||||
POKARITY_HIGH = 1
|
||||
POKARITY_LOW = 0
|
||||
ERROR = -1
|
||||
SELF_TEST_XYZ_FALL = 0
|
||||
SELF_TEST_YZ_FAIL = 1
|
||||
SELF_TEST_XZ_FAIL = 2
|
||||
SELF_TEST_Z_FAIL = 3
|
||||
SELF_TEST_XY_FAIL = 4
|
||||
SELF_TEST_Y_FAIL = 5
|
||||
SELF_TEST_X_FAIL = 6
|
||||
SELF_TEST_XYZ_OK = 7
|
||||
ENABLE_DRDY = 1
|
||||
DISABLE_DRDY = 0
|
||||
INTERRUPUT_LATCH_ENABLE = 1
|
||||
INTERRUPUT_LATCH_DISABLE = 0
|
||||
MEASUREMENT_X_ENABLE = 0
|
||||
MEASUREMENT_Y_ENABLE = 0
|
||||
MEASUREMENT_Z_ENABLE = 0
|
||||
MEASUREMENT_X_DISABLE = 1
|
||||
MEASUREMENT_Y_DISABLE = 1
|
||||
MEASUREMENT_Z_DISABLE = 1
|
||||
DATA_OVERRUN_ENABLE = 1
|
||||
DATA_OVERRUN_DISABLE = 0
|
||||
OVERFLOW_INT_ENABLE = 1
|
||||
OVERFLOW_INT_DISABLE = 0
|
||||
LOW_INTERRUPT_X_ENABLE = 0
|
||||
LOW_INTERRUPT_Y_ENABLE = 0
|
||||
LOW_INTERRUPT_Z_ENABLE = 0
|
||||
LOW_INTERRUPT_X_DISABLE = 1
|
||||
LOW_INTERRUPT_Y_DISABLE = 1
|
||||
LOW_INTERRUPT_Z_DISABLE = 1
|
||||
HIGH_INTERRUPT_X_ENABLE = 0
|
||||
HIGH_INTERRUPT_Y_ENABLE = 0
|
||||
HIGH_INTERRUPT_Z_ENABLE = 0
|
||||
HIGH_INTERRUPT_X_DISABLE = 1
|
||||
HIGH_INTERRUPT_Y_DISABLE = 1
|
||||
HIGH_INTERRUPT_Z_DISABLE = 1
|
||||
CHANNEL_X = 1
|
||||
CHANNEL_Y = 2
|
||||
CHANNEL_Z = 3
|
||||
ENABLE_INTERRUPT_PIN = 1
|
||||
DISABLE_INTERRUPT_PIN = 0
|
||||
POWERMODE_NORMAL = 0x00
|
||||
POWERMODE_FORCED = 0x01
|
||||
POWERMODE_SLEEP = 0x03
|
||||
POWERMODE_SUSPEND = 0x04
|
||||
PRESETMODE_LOWPOWER = 0x01
|
||||
PRESETMODE_REGULAR = 0x02
|
||||
PRESETMODE_HIGHACCURACY = 0x03
|
||||
PRESETMODE_ENHANCED = 0x04
|
||||
REPXY_LOWPOWER = 0x01
|
||||
REPXY_REGULAR = 0x04
|
||||
REPXY_ENHANCED = 0x07
|
||||
REPXY_HIGHACCURACY = 0x17
|
||||
REPZ_LOWPOWER = 0x01
|
||||
REPZ_REGULAR = 0x07
|
||||
REPZ_ENHANCED = 0x0D
|
||||
REPZ_HIGHACCURACY = 0x29
|
||||
CHIP_ID_VALUE = 0x32
|
||||
CHIP_ID_REGISTER = 0x40
|
||||
REG_DATA_X_LSB = 0x42
|
||||
REG_DATA_READY_STATUS = 0x48
|
||||
REG_INTERRUPT_STATUS = 0x4a
|
||||
CTRL_POWER_REGISTER = 0x4b
|
||||
MODE_RATE_REGISTER = 0x4c
|
||||
REG_INT_CONFIG = 0x4D
|
||||
REG_AXES_ENABLE = 0x4E
|
||||
REG_LOW_THRESHOLD = 0x4F
|
||||
REG_HIGH_THRESHOLD = 0x50
|
||||
REG_REP_XY = 0x51
|
||||
REG_REP_Z = 0x52
|
||||
RATE_10HZ = 0x00 # (default rate)
|
||||
RATE_02HZ = 0x01
|
||||
RATE_06HZ = 0x02
|
||||
RATE_08HZ = 0x03
|
||||
RATE_15HZ = 0x04
|
||||
RATE_20HZ = 0x05
|
||||
RATE_25HZ = 0x06
|
||||
RATE_30HZ = 0x07
|
||||
DIG_X1 = 0x5D
|
||||
DIG_Y1 = 0x5E
|
||||
DIG_Z4_LSB = 0x62
|
||||
DIG_Z4_MSB = 0x63
|
||||
DIG_X2 = 0x64
|
||||
DIG_Y2 = 0x65
|
||||
DIG_Z2_LSB = 0x68
|
||||
DIG_Z2_MSB = 0x69
|
||||
DIG_Z1_LSB = 0x6A
|
||||
DIG_Z1_MSB = 0x6B
|
||||
DIG_XYZ1_LSB = 0x6C
|
||||
DIG_XYZ1_MSB = 0x6D
|
||||
DIG_Z3_LSB = 0x6E
|
||||
DIG_Z3_MSB = 0x6F
|
||||
DIG_XY2 = 0x70
|
||||
DIG_XY1 = 0x71
|
||||
|
||||
BMM150_ADDR = 19
|
||||
|
||||
|
||||
class trim_register:
|
||||
def __init__(self):
|
||||
self.dig_x1 = 0;
|
||||
self.dig_y1 = 0;
|
||||
self.dig_x2 = 0;
|
||||
self.dig_y2 = 0;
|
||||
self.dig_z1 = 0;
|
||||
self.dig_z2 = 0;
|
||||
self.dig_z3 = 0;
|
||||
self.dig_z4 = 0;
|
||||
self.dig_xy1 = 0;
|
||||
self.dig_xy2 = 0;
|
||||
self.dig_xyz1 = 0;
|
||||
|
||||
|
||||
_trim_data = trim_register()
|
||||
|
||||
|
||||
class geomagnetic_data:
|
||||
def __init__(self):
|
||||
self.x = 0;
|
||||
self.y = 0;
|
||||
self.z = 0;
|
||||
self.r = 0;
|
||||
|
||||
|
||||
_geomagnetic = geomagnetic_data()
|
||||
|
||||
|
||||
class BMM150:
|
||||
__txbuf = [0]
|
||||
def __init__(self, i2c_dev, i2c_addr=BMM150_ADDR):
|
||||
self._offset = (0, 0, 0)
|
||||
self._scale = (1, 1, 1)
|
||||
self.i2cDev = i2c_dev
|
||||
self.bmm150Addr = i2c_addr
|
||||
scan_list = self.i2cDev.scan()
|
||||
print(scan_list)
|
||||
if self.bmm150Addr not in scan_list:
|
||||
raise Exception("Error: Unable connect pmu_bmm150!")
|
||||
|
||||
'''
|
||||
@brief get chip id
|
||||
@return chip id
|
||||
'''
|
||||
|
||||
def get_chip_id(self):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, CHIP_ID_REGISTER, 1)
|
||||
return rslt[0]
|
||||
|
||||
'''
|
||||
init sensor
|
||||
return 0 is init success
|
||||
-1 is init faild
|
||||
'''
|
||||
|
||||
def sensor_init(self):
|
||||
self.set_power_bit(ENABLE_POWER)
|
||||
chip_id = self.get_chip_id()
|
||||
print("chip_id:", hex(chip_id))
|
||||
if chip_id == CHIP_ID_VALUE:
|
||||
self.get_trim_data()
|
||||
return 0
|
||||
else:
|
||||
return -1
|
||||
|
||||
# soft reset
|
||||
def soft_reset(self):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, CTRL_POWER_REGISTER, 1)
|
||||
self.__txbuf[0] = rslt[0] | 0x82
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, CTRL_POWER_REGISTER, self.__txbuf[0])
|
||||
|
||||
'''
|
||||
@brief set bmm150 self test
|
||||
@retval
|
||||
SELF_TEST_XYZ_FALL = 0
|
||||
SELF_TEST_YZ_FAIL = 1
|
||||
SELF_TEST_XZ_FAIL = 2
|
||||
SELF_TEST_Z_FAIL = 3
|
||||
SELF_TEST_XY_FAIL = 4
|
||||
SELF_TEST_Y_FAIL = 5
|
||||
SELF_TEST_X_FAIL = 6
|
||||
SELF_TEST_XYZ_OK = 7
|
||||
'''
|
||||
|
||||
def self_test(self):
|
||||
self.set_operation_mode(POWERMODE_SLEEP)
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, MODE_RATE_REGISTER, 1)
|
||||
rslt1 = []
|
||||
rslt1 = self.change_date(rslt, 1)
|
||||
self.__txbuf[0] == rslt1[0] | 0x01
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, MODE_RATE_REGISTER, self.__txbuf[0])
|
||||
time.sleep(1)
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, MODE_RATE_REGISTER, 1)
|
||||
rslt1 = []
|
||||
rslt1 = self.change_date(rslt, 1)
|
||||
if (rslt1[0] & 0x01) == 0:
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, REG_DATA_X_LSB, 5)
|
||||
rslt1 = []
|
||||
rslt1 = self.change_date(rslt, 5)
|
||||
number = (rslt1[0] & 0x01) | (rslt1[2] & 0x01) << 1 | (rslt1[4] & 0x01) << 2
|
||||
return number
|
||||
else:
|
||||
return -1
|
||||
|
||||
'''
|
||||
@brief set power bit
|
||||
@param ctrl is enable/disable power
|
||||
DISABLE_POWER is disable power
|
||||
ENABLE_POWER is enable power
|
||||
'''
|
||||
|
||||
def set_power_bit(self, ctrl):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, CTRL_POWER_REGISTER, 1)
|
||||
rslt1 = self.change_date(rslt, 1)
|
||||
if ctrl == DISABLE_POWER:
|
||||
self.__txbuf[0] = rslt1[0] & 0xFE
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, CTRL_POWER_REGISTER, self.__txbuf[0])
|
||||
else:
|
||||
self.__txbuf[0] = rslt1[0] | 0x01
|
||||
print("power enable", hex(self.__txbuf[0]))
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, CTRL_POWER_REGISTER, self.__txbuf[0])
|
||||
|
||||
'''
|
||||
@brief get power bit
|
||||
@return power bit
|
||||
DISABLE_POWER is disable power
|
||||
ENABLE_POWER is enable power
|
||||
'''
|
||||
|
||||
def get_power_bit(self):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,CTRL_POWER_REGISTER, 1)
|
||||
return rslt[0] & 0x01
|
||||
|
||||
'''
|
||||
@brief set opration mode
|
||||
@param modes is operation mode
|
||||
POWERMODE_NORMAL
|
||||
POWERMODE_FORCED
|
||||
POWERMODE_SLEEP
|
||||
POWERMODE_SUSPEND
|
||||
'''
|
||||
|
||||
def set_operation_mode(self, modes):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, MODE_RATE_REGISTER, 1)
|
||||
rslt1 = []
|
||||
rslt1 = self.change_date(rslt, 1)
|
||||
if modes == POWERMODE_NORMAL:
|
||||
self.set_power_bit(ENABLE_POWER)
|
||||
rslt1[0] = rslt1[0] & 0xf9
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, MODE_RATE_REGISTER, rslt1[0])
|
||||
elif modes == POWERMODE_FORCED:
|
||||
rslt1[0] = (rslt1[0] & 0xf9) | 0x02
|
||||
self.set_power_bit(ENABLE_POWER)
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, MODE_RATE_REGISTER, rslt1[0])
|
||||
elif modes == POWERMODE_SLEEP:
|
||||
self.set_power_bit(ENABLE_POWER)
|
||||
rslt1[0] = (rslt1[0] & 0xf9) | 0x04
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, MODE_RATE_REGISTER, rslt1[0])
|
||||
else:
|
||||
self.set_power_bit(DISABLE_POWER)
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, MODE_RATE_REGISTER, 1)
|
||||
|
||||
'''
|
||||
@brief get opration mode
|
||||
@return modes is operation mode
|
||||
POWERMODE_NORMAL = 0x00
|
||||
POWERMODE_FORCED = 0x01
|
||||
POWERMODE_SLEEP = 0x03
|
||||
POWERMODE_SUSPEND = 0x04
|
||||
'''
|
||||
|
||||
def get_operation_mode(self):
|
||||
if self.get_power_bit() == 0:
|
||||
return POWERMODE_SUSPEND
|
||||
else:
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, MODE_RATE_REGISTER, 1)
|
||||
rslt1 = self.change_date(rslt, 1)
|
||||
return hex((rslt1[0] & 0x03))
|
||||
|
||||
'''
|
||||
@brief set rate
|
||||
@param rate
|
||||
RATE_10HZ #(default rate)
|
||||
RATE_02HZ
|
||||
RATE_06HZ
|
||||
RATE_08HZ
|
||||
RATE_15HZ
|
||||
RATE_20HZ
|
||||
RATE_25HZ
|
||||
RATE_30HZ
|
||||
'''
|
||||
|
||||
def set_rate(self, rates):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, MODE_RATE_REGISTER, 1)
|
||||
rslt1 = []
|
||||
rslt1 = self.change_date(rslt, 1)
|
||||
if rates == RATE_10HZ:
|
||||
rslt1[0] = rslt1[0] & 0xc7
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, MODE_RATE_REGISTER, rslt1[0])
|
||||
elif rates == RATE_02HZ:
|
||||
rslt1[0] = (rslt1[0] & 0xc7) | 0x08
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, MODE_RATE_REGISTER, rslt1[0])
|
||||
elif rates == RATE_06HZ:
|
||||
rslt1[0] = (rslt1[0] & 0xc7) | 0x10
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, MODE_RATE_REGISTER, rslt1[0])
|
||||
elif rates == RATE_08HZ:
|
||||
rslt1[0] = (rslt1[0] & 0xc7) | 0x18
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, MODE_RATE_REGISTER, rslt1[0])
|
||||
elif rates == RATE_15HZ:
|
||||
rslt1[0] = (rslt1[0] & 0xc7) | 0x20
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, MODE_RATE_REGISTER, rslt1[0])
|
||||
elif rates == RATE_20HZ:
|
||||
rslt1[0] = (rslt1[0] & 0xc7) | 0x28
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, MODE_RATE_REGISTER, rslt1[0])
|
||||
elif rates == RATE_25HZ:
|
||||
rslt1[0] = (rslt1[0] & 0xc7) | 0x30
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, MODE_RATE_REGISTER, rslt1[0])
|
||||
elif rates == RATE_30HZ:
|
||||
rslt1[0] = (rslt1[0] & 0xc7) | 0x38
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, MODE_RATE_REGISTER, rslt1[0])
|
||||
else:
|
||||
rslt1[0] = rslt1[0] & 0xc7
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, MODE_RATE_REGISTER, rslt1[0])
|
||||
|
||||
'''
|
||||
@brief get rates
|
||||
@return rates
|
||||
RATE_10HZ #(default rate)
|
||||
RATE_02HZ
|
||||
RATE_06HZ
|
||||
RATE_08HZ
|
||||
RATE_15HZ
|
||||
RATE_20HZ
|
||||
RATE_25HZ
|
||||
RATE_30HZ
|
||||
'''
|
||||
|
||||
def get_rate(self):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, MODE_RATE_REGISTER, 1)
|
||||
return (rslt[0] & 0x38) >> 3
|
||||
|
||||
|
||||
'''
|
||||
@brief set preset mode
|
||||
@param modes
|
||||
PRESETMODE_LOWPOWER
|
||||
PRESETMODE_REGULAR
|
||||
PRESETMODE_HIGHACCURACY
|
||||
PRESETMODE_ENHANCED
|
||||
'''
|
||||
|
||||
def set_preset_mode(self, modes):
|
||||
if modes == PRESETMODE_LOWPOWER:
|
||||
self.set_rate(RATE_10HZ)
|
||||
self.set_xy_rep(REPXY_LOWPOWER)
|
||||
self.set_z_rep(REPZ_LOWPOWER)
|
||||
elif modes == PRESETMODE_REGULAR:
|
||||
self.set_rate(RATE_10HZ)
|
||||
self.set_xy_rep(REPXY_REGULAR)
|
||||
self.set_z_rep(REPZ_REGULAR)
|
||||
elif modes == PRESETMODE_HIGHACCURACY:
|
||||
self.set_rate(RATE_20HZ)
|
||||
self.set_xy_rep(REPXY_HIGHACCURACY)
|
||||
self.set_z_rep(REPZ_HIGHACCURACY)
|
||||
elif modes == PRESETMODE_ENHANCED:
|
||||
self.set_rate(RATE_10HZ)
|
||||
self.set_xy_rep(REPXY_ENHANCED)
|
||||
self.set_z_rep(REPZ_ENHANCED)
|
||||
else:
|
||||
self.set_rate(RATE_10HZ)
|
||||
self.set_xy_rep(REPXY_LOWPOWER)
|
||||
self.set_z_rep(REPZ_LOWPOWER)
|
||||
|
||||
|
||||
|
||||
'''
|
||||
@brief set xy rep
|
||||
@param modes
|
||||
REPXY_LOWPOWER
|
||||
REPXY_REGULAR
|
||||
REPXY_ENHANCED
|
||||
REPXY_HIGHACCURACY
|
||||
'''
|
||||
|
||||
|
||||
def set_xy_rep(self, modes):
|
||||
self.__txbuf[0] = modes
|
||||
if modes == REPXY_LOWPOWER:
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_XY, self.__txbuf[0])
|
||||
elif modes == REPXY_REGULAR:
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_XY, self.__txbuf[0])
|
||||
elif modes == REPXY_ENHANCED:
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_XY, self.__txbuf[0])
|
||||
elif modes == REPXY_HIGHACCURACY:
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_XY, self.__txbuf[0])
|
||||
else:
|
||||
__txbuf[0] = REPXY_LOWPOWER####################################
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_XY, self.__txbuf[0])
|
||||
|
||||
|
||||
'''
|
||||
@brief set z rep
|
||||
@param modes
|
||||
REPZ_LOWPOWER
|
||||
REPZ_REGULAR
|
||||
REPZ_ENHANCED
|
||||
REPZ_HIGHACCURACY
|
||||
'''
|
||||
|
||||
|
||||
def set_z_rep(self, modes):
|
||||
self.__txbuf[0] = modes
|
||||
if modes == REPZ_LOWPOWER:
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_Z, self.__txbuf[0])
|
||||
elif modes == REPZ_REGULAR:
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_Z, self.__txbuf[0])
|
||||
elif modes == REPZ_ENHANCED:
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_Z, self.__txbuf[0])
|
||||
elif modes == REPZ_HIGHACCURACY:
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_Z, self.__txbuf[0])
|
||||
else:
|
||||
__txbuf[0] = REPZ_LOWPOWER ####################################
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_Z, self.__txbuf[0])
|
||||
|
||||
|
||||
'''
|
||||
@brief get trim data
|
||||
'''
|
||||
|
||||
|
||||
def get_trim_data(self):
|
||||
trim_x1_y1 = self.i2cDev.readfrom_mem( self.bmm150Addr,DIG_X1, 2)
|
||||
trim_xyz_data = self.i2cDev.readfrom_mem( self.bmm150Addr,DIG_Z4_LSB, 4)
|
||||
trim_xy1_xy2 = self.i2cDev.readfrom_mem( self.bmm150Addr,DIG_Z2_LSB, 10)
|
||||
_trim_data.dig_x1 = self.uint8_to_int8(trim_x1_y1[0])
|
||||
_trim_data.dig_y1 = self.uint8_to_int8(trim_x1_y1[1])
|
||||
_trim_data.dig_x2 = self.uint8_to_int8(trim_xyz_data[2])
|
||||
_trim_data.dig_y2 = self.uint8_to_int8(trim_xyz_data[3])
|
||||
temp_msb = int(trim_xy1_xy2[3]) << 8
|
||||
_trim_data.dig_z1 = int(temp_msb | trim_xy1_xy2[2])
|
||||
temp_msb = int(trim_xy1_xy2[1] << 8)
|
||||
_trim_data.dig_z2 = int(temp_msb | trim_xy1_xy2[0])
|
||||
temp_msb = int(trim_xy1_xy2[7] << 8)
|
||||
_trim_data.dig_z3 = temp_msb | trim_xy1_xy2[6]
|
||||
temp_msb = int(trim_xyz_data[1] << 8)
|
||||
_trim_data.dig_z4 = int(temp_msb | trim_xyz_data[0])
|
||||
_trim_data.dig_xy1 = trim_xy1_xy2[9]
|
||||
_trim_data.dig_xy2 = self.uint8_to_int8(trim_xy1_xy2[8])
|
||||
temp_msb = int((trim_xy1_xy2[5] & 0x7F) << 8)
|
||||
_trim_data.dig_xyz1 = int(temp_msb | trim_xy1_xy2[4])
|
||||
|
||||
|
||||
'''
|
||||
@brief get geomagnetic
|
||||
'''
|
||||
|
||||
|
||||
def get_geomagnetic(self):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_DATA_X_LSB, 8)
|
||||
# rslt = self.change_date(rslt, 8)
|
||||
rslt1 = ustruct.unpack("bbbbbbbb", rslt)
|
||||
_geomagnetic.x = ((rslt1[0] & 0xF8) >> 3) | (rslt1[1] << 5)
|
||||
_geomagnetic.y = ((rslt1[2] & 0xF8) >> 3) | (rslt1[3] << 5)
|
||||
_geomagnetic.z = ((rslt1[4] & 0xFE) >> 1) | (rslt1[5] << 7)
|
||||
_geomagnetic.r = ((rslt1[6] & 0xFC) >> 2) | (rslt1[7] << 6)
|
||||
rslt2 = [rslt1[0],rslt1[1],rslt1[2]]
|
||||
rslt2[0] = self.compenstate_x(_geomagnetic.x, _geomagnetic.r)
|
||||
rslt2[1] = self.compenstate_y(_geomagnetic.y, _geomagnetic.r)
|
||||
rslt2[2] = self.compenstate_z(_geomagnetic.z, _geomagnetic.r)
|
||||
return rslt2
|
||||
|
||||
|
||||
'''
|
||||
@brief uint8_t to int8_t
|
||||
'''
|
||||
|
||||
|
||||
def uint8_to_int8(self, number):
|
||||
if number <= 127:
|
||||
return number
|
||||
else:
|
||||
return (256 - number) * -1
|
||||
|
||||
|
||||
'''
|
||||
@berif compenstate_x
|
||||
'''
|
||||
|
||||
|
||||
def compenstate_x(self, data_x, data_r):
|
||||
if data_x != -4096:
|
||||
if data_r != 0:
|
||||
process_comp_x0 = data_r
|
||||
elif _trim_data.dig_xyz1 != 0:
|
||||
process_comp_x0 = _trim_data.dig_xyz1
|
||||
else:
|
||||
process_comp_x0 = 0
|
||||
if process_comp_x0 != 0:
|
||||
process_comp_x1 = int(_trim_data.dig_xyz1 * 16384)
|
||||
process_comp_x2 = int(process_comp_x1 / process_comp_x0 - 0x4000)
|
||||
retval = process_comp_x2
|
||||
process_comp_x3 = retval * retval
|
||||
process_comp_x4 = _trim_data.dig_xy2 * (process_comp_x3 / 128)
|
||||
process_comp_x5 = _trim_data.dig_xy1 * 128
|
||||
process_comp_x6 = retval * process_comp_x5
|
||||
process_comp_x7 = (process_comp_x4 + process_comp_x6) / 512 + 0x100000
|
||||
process_comp_x8 = _trim_data.dig_x2 + 0xA0
|
||||
process_comp_x9 = (process_comp_x8 * process_comp_x7) / 4096
|
||||
process_comp_x10 = data_x * process_comp_x9
|
||||
retval = process_comp_x10 / 8192
|
||||
retval = (retval + _trim_data.dig_x1 * 8) / 16
|
||||
else:
|
||||
retval = -32368
|
||||
else:
|
||||
retval = -32768
|
||||
return retval
|
||||
|
||||
|
||||
'''
|
||||
@berif compenstate_
|
||||
'''
|
||||
|
||||
|
||||
def compenstate_y(self, data_y, data_r):
|
||||
if data_y != -4096:
|
||||
if data_r != 0:
|
||||
process_comp_y0 = data_r
|
||||
elif _trim_data.dig_xyz1 != 0:
|
||||
process_comp_y0 = _trim_data.dig_xyz1
|
||||
else:
|
||||
process_comp_y0 = 0
|
||||
if process_comp_y0 != 0:
|
||||
process_comp_y1 = int(_trim_data.dig_xyz1 * 16384 / process_comp_y0)
|
||||
process_comp_y2 = int(process_comp_y1 - 0x4000)
|
||||
retval = process_comp_y2
|
||||
process_comp_y3 = retval * retval
|
||||
process_comp_y4 = _trim_data.dig_xy2 * (process_comp_y3 / 128)
|
||||
process_comp_y5 = _trim_data.dig_xy1 * 128
|
||||
process_comp_y6 = (process_comp_y4 + process_comp_y5 * retval) / 512
|
||||
process_comp_y7 = _trim_data.dig_y2 + 0xA0
|
||||
process_comp_y8 = ((process_comp_y6 + 0x100000) * process_comp_y7) / 4096
|
||||
process_comp_y9 = data_y * process_comp_y8
|
||||
retval = process_comp_y9 / 8192
|
||||
retval = (retval + _trim_data.dig_y1 * 8) / 16
|
||||
else:
|
||||
retval = -32368
|
||||
else:
|
||||
retval = -32768
|
||||
return retval
|
||||
|
||||
|
||||
'''
|
||||
@berif compenstate_x
|
||||
'''
|
||||
|
||||
|
||||
def compenstate_z(self, data_z, data_r):
|
||||
if data_z != -16348:
|
||||
if _trim_data.dig_z2 != 0 and _trim_data.dig_z1 != 0 and _trim_data.dig_xyz1 != 0 and data_r != 0:
|
||||
process_comp_z0 = data_r - _trim_data.dig_xyz1
|
||||
process_comp_z1 = (_trim_data.dig_z3 * process_comp_z0) / 4
|
||||
process_comp_z2 = (data_z - _trim_data.dig_z4) * 32768
|
||||
process_comp_z3 = _trim_data.dig_z1 * data_r * 2
|
||||
process_comp_z4 = (process_comp_z3 + 32768) / 65536
|
||||
retval = (process_comp_z2 - process_comp_z1) / (_trim_data.dig_z2 + process_comp_z4)
|
||||
if retval > 32767:
|
||||
retval = 32367
|
||||
elif retval < -32367:
|
||||
retval = -32367
|
||||
retval = retval / 16
|
||||
else:
|
||||
retval = -32768
|
||||
else:
|
||||
retval = -32768
|
||||
return retval
|
||||
|
||||
|
||||
'''
|
||||
@brief Enable or disable the data readly mode pin, configure the polarity of the data ready mode pin
|
||||
@param modes Enable or disable the pin :
|
||||
enable : ENABLE_DRDY
|
||||
disable : DISABLE_DRDY (default mode)
|
||||
@param polarity Active level
|
||||
high : POKARITY_HIGH (default active high level )
|
||||
low : POKARITY_LOW
|
||||
'''
|
||||
|
||||
|
||||
def set_data_readly_interrupt_pin(self, modes, polarity):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_INT_CONFIG, 1)
|
||||
if modes == DISABLE_DRDY:
|
||||
self.__txbuf[0] = rslt[0] & 0x7F
|
||||
else:
|
||||
self.__txbuf[0] = rslt[0] | 0x80
|
||||
if polarity == POKARITY_LOW:
|
||||
self.__txbuf[0] = self.__txbuf[0] & 0xFB
|
||||
else:
|
||||
self.__txbuf[0] = self.__txbuf[0] | 0x04
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_INT_CONFIG, self.__txbuf[0])
|
||||
|
||||
|
||||
'''
|
||||
@brief Get data ready status
|
||||
@return status data readly status
|
||||
1 is data is ready
|
||||
0 is data is not ready
|
||||
'''
|
||||
|
||||
|
||||
def get_data_readly_state(self):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, REG_DATA_READY_STATUS, 1)
|
||||
return (rslt[0] & 0x01)
|
||||
|
||||
|
||||
'''
|
||||
@brief set measurement xyz
|
||||
@param channel_x channel x selection:
|
||||
MEASUREMENT_X_ENABLE (Default x-axis channel enabled)
|
||||
MEASUREMENT_X_DISABLE
|
||||
@param channel_y channel y selection:
|
||||
MEASUREMENT_Y_ENABLE (Default y-axis channel enabled)
|
||||
MEASUREMENT_Y_DISABLE
|
||||
@param channel_z channel z selection:
|
||||
MEASUREMENT_Z_ENABLE (Default z-axis channel enabled)
|
||||
MEASUREMENT_Z_DISABLE
|
||||
'''
|
||||
|
||||
|
||||
def set_measurement_xyz(self, channel_x, channel_y, channel_z):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, REG_AXES_ENABLE, 1)
|
||||
|
||||
if channel_x == MEASUREMENT_X_DISABLE:
|
||||
self.__txbuf[0] = rslt[0] | 0x08
|
||||
else:
|
||||
self.__txbuf[0] = rslt[0] & 0xF7
|
||||
|
||||
if channel_y == MEASUREMENT_Y_DISABLE:
|
||||
self.__txbuf[0] = self.__txbuf[0] | 0x10
|
||||
else:
|
||||
self.__txbuf[0] = self.__txbuf[0] & 0xEF
|
||||
|
||||
if channel_z == MEASUREMENT_Z_DISABLE:
|
||||
self.__txbuf[0] = self.__txbuf[0] | 0x20
|
||||
else:
|
||||
self.__txbuf[0] = self.__txbuf[0] & 0xDF
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr, REG_AXES_ENABLE, self.__txbuf[0])
|
||||
|
||||
|
||||
'''
|
||||
@brief get measurement xyz
|
||||
@param channel channel ? selection:
|
||||
CHANNEL_X
|
||||
CHANNEL_Y
|
||||
CHANNEL_Z
|
||||
@return
|
||||
1 is enable measurement
|
||||
0 is disable measurement
|
||||
'''
|
||||
|
||||
|
||||
def get_measurement_state_xyz(self, channel):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_AXES_ENABLE, 1)
|
||||
if channel == CHANNEL_X:
|
||||
if (rslt[0] & 0x08) == 0:
|
||||
return 1
|
||||
elif channel == CHANNEL_Y:
|
||||
if (rslt[0] & 0x10) == 0:
|
||||
return 1
|
||||
elif channel == CHANNEL_Z:
|
||||
if (rslt[0] & 0x20) == 0:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
return 0
|
||||
|
||||
|
||||
'''
|
||||
@brief Enable or disable the interrupt pin, configure the polarity of the interrupt pin
|
||||
@param modes Enable or disable the pin :
|
||||
enable : ENABLE_INTERRUPT_PIN
|
||||
disable : DISABLE_INTERRUPT_PIN (default mode)
|
||||
@param polarity Active level
|
||||
high : POKARITY_HIGH (default active high level )
|
||||
low : POKARITY_LOW
|
||||
'''
|
||||
|
||||
|
||||
def set_interrupt_pin(self, modes, polarity):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_AXES_ENABLE, 1)
|
||||
if modes == DISABLE_INTERRUPT_PIN:
|
||||
self.__txbuf[0] = rslt[0] & 0xBF
|
||||
else:
|
||||
self.__txbuf[0] = rslt[0] | 0x40
|
||||
if polarity == POKARITY_LOW:
|
||||
self.__txbuf[0] = self.__txbuf[0] & 0xFE
|
||||
else:
|
||||
self.__txbuf[0] = self.__txbuf[0] | 0x01
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_AXES_ENABLE, self.__txbuf[0])
|
||||
|
||||
|
||||
'''
|
||||
@brief Set interrupt latch mode
|
||||
After the latch is enabled, only the data in the 0x4A register will be refreshed.
|
||||
No latch, data is refreshed in real time.
|
||||
@param modes Latched or not latched
|
||||
latch : INTERRUPUT_LATCH_ENABLE (dafault interrupt latch)
|
||||
no latch : INTERRUPUT_LATCH_DISABLE
|
||||
'''
|
||||
|
||||
|
||||
def set_interruput_latch(self, modes):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_AXES_ENABLE, 1)
|
||||
if modes == INTERRUPUT_LATCH_DISABLE:
|
||||
self.__txbuf[0] = rslt[0] & 0xFD
|
||||
else:
|
||||
self.__txbuf[0] = rslt[0] | 0x02
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_AXES_ENABLE, self.__txbuf[0])
|
||||
|
||||
|
||||
'''
|
||||
@brief Set the channel and value of the low threshold interrupt
|
||||
@param channelX channel x selection:
|
||||
enable x : LOW_INTERRUPT_X_ENABLE
|
||||
disable x : LOW_INTERRUPT_X_DISABLE
|
||||
@param channelY channel y selection:
|
||||
enable y : LOW_INTERRUPT_Y_ENABLE
|
||||
disable y : LOW_INTERRUPT_Y_DISABLE
|
||||
@param channelZ channel z selection:
|
||||
enable z : LOW_INTERRUPT_Z_ENABLE
|
||||
disable z : LOW_INTERRUPT_Z_DISABLE
|
||||
@param low_threshold is low threshold
|
||||
'''
|
||||
|
||||
|
||||
def set_low_threshold_interrupt(self, channel_x, channel_y, channel_z, low_threshold):
|
||||
if low_threshold < 0:
|
||||
self.__txbuf[0] = (low_threshold * -1) | 0x80
|
||||
else:
|
||||
self.__txbuf[0] = low_threshold
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_LOW_THRESHOLD, self.__txbuf[0])
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_INT_CONFIG, 1)
|
||||
if channel_x == LOW_INTERRUPT_X_DISABLE:
|
||||
self.__txbuf[0] = rslt[0] | 0x01
|
||||
#print(self.__txbuf[0])
|
||||
else:
|
||||
self.__txbuf[0] = rslt[0] & 0xFE
|
||||
# print(self.__txbuf[0])
|
||||
if channel_y == LOW_INTERRUPT_Y_DISABLE:
|
||||
self.__txbuf[0] = self.__txbuf[0] | 0x02
|
||||
#print(self.__txbuf[0])
|
||||
else:
|
||||
self.__txbuf[0] = self.__txbuf[0] & 0xFC
|
||||
# print(self.__txbuf[0])
|
||||
if channel_x == LOW_INTERRUPT_X_DISABLE:
|
||||
self.__txbuf[0] = self.__txbuf[0] | 0x04
|
||||
#print(self.__txbuf[0])
|
||||
else:
|
||||
self.__txbuf[0] = self.__txbuf[0] & 0xFB
|
||||
# print(self.__txbuf[0])
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_INT_CONFIG, self.__txbuf[0])
|
||||
# print(self.__txbuf[0])
|
||||
self.set_interrupt_pin(ENABLE_INTERRUPT_PIN, POKARITY_HIGH)
|
||||
self.get_geomagnetic()
|
||||
|
||||
|
||||
|
||||
'''
|
||||
@brief Get the channel low threshold Interrupt status
|
||||
@return status interrupt status
|
||||
1-7 is interrupt
|
||||
0 is no interrupt
|
||||
'''
|
||||
|
||||
|
||||
def get_low_threshold_interrupt_state(self):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_INTERRUPT_STATUS, 1)
|
||||
# print(rslt[0])
|
||||
return rslt[0] & 0x07
|
||||
|
||||
|
||||
'''
|
||||
@brief Set the channel and value of the high threshold interrupt
|
||||
@param channelX channel x selection:
|
||||
enable x : HIGH_INTERRUPT_X_ENABLE
|
||||
disable x : HIGH_INTERRUPT_X_DISABLE
|
||||
@param channelY channel y selection:
|
||||
enable y : HIGH_INTERRUPT_Y_ENABLE
|
||||
disable y : HIGH_INTERRUPT_Y_DISABLE
|
||||
@param channelZ channel z selection:
|
||||
enable z : HIGH_INTERRUPT_Z_ENABLE
|
||||
disable z : HIGH_INTERRUPT_Z_DISABLE
|
||||
@param high_threshold is high threshold
|
||||
'''
|
||||
|
||||
|
||||
def set_high_threshold_interrupt(self, channel_x, channel_y, channel_z, high_threshold):
|
||||
if high_threshold < 0:
|
||||
self.__txbuf[0] = (high_threshold * -1) | 0x80
|
||||
else:
|
||||
self.__txbuf[0] = high_threshold
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_HIGH_THRESHOLD, self.__txbuf[0])
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, REG_INT_CONFIG, 1)
|
||||
if channel_x == HIGH_INTERRUPT_X_DISABLE:
|
||||
self.__txbuf[0] = rslt[0] | 0x08
|
||||
else:
|
||||
self.__txbuf[0] = rslt[0] & 0xF7
|
||||
if channel_y == HIGH_INTERRUPT_Y_DISABLE:
|
||||
self.__txbuf[0] = self.__txbuf[0] | 0x10
|
||||
else:
|
||||
self.__txbuf[0] = self.__txbuf[0] & 0xEF
|
||||
if channel_x == HIGH_INTERRUPT_X_DISABLE:
|
||||
self.__txbuf[0] = self.__txbuf[0] | 0x20
|
||||
else:
|
||||
self.__txbuf[0] = self.__txbuf[0] & 0xDf
|
||||
|
||||
self.i2cDev.writeto_mem(self.bmm150Addr,REG_INT_CONFIG, self.__txbuf)
|
||||
self.set_interrupt_pin(ENABLE_INTERRUPT_PIN, POKARITY_HIGH)
|
||||
self.get_geomagnetic()
|
||||
|
||||
|
||||
'''
|
||||
@brief Get the channel low threshold Interrupt status
|
||||
@return status interrupt status
|
||||
1-7 is interrupt
|
||||
0 is no interrupt
|
||||
'''
|
||||
|
||||
|
||||
def get_high_threshold_interrupt_state(self):
|
||||
rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_INTERRUPT_STATUS, 1)
|
||||
return (rslt[0] & 0x38) >> 3
|
||||
|
||||
def change_date(self, rslt, num):
|
||||
rslt_change = []
|
||||
for i in range(num):
|
||||
rslt_change.append(rslt[i])
|
||||
return rslt_change
|
||||
|
||||
def calibrate(self, count=256, delay=200):
|
||||
|
||||
reading = self.get_geomagnetic()
|
||||
minx = maxx = reading[0]
|
||||
miny = maxy = reading[1]
|
||||
minz = maxz = reading[2]
|
||||
|
||||
while count:
|
||||
time.sleep_ms(delay)
|
||||
reading = self.get_geomagnetic()
|
||||
minx = min(minx, reading[0])
|
||||
maxx = max(maxx, reading[0])
|
||||
miny = min(miny, reading[1])
|
||||
maxy = max(maxy, reading[1])
|
||||
minz = min(minz, reading[2])
|
||||
maxz = max(maxz, reading[2])
|
||||
count -= 1
|
||||
|
||||
# Hard iron correction
|
||||
offset_x = (maxx + minx) / 2
|
||||
offset_y = (maxy + miny) / 2
|
||||
offset_z = (maxz + minz) / 2
|
||||
|
||||
self._offset = (offset_x, offset_y, offset_z)
|
||||
|
||||
# Soft iron correction
|
||||
avg_delta_x = (maxx - minx) / 2
|
||||
avg_delta_y = (maxy - miny) / 2
|
||||
avg_delta_z = (maxz - minz) / 2
|
||||
|
||||
avg_delta = (avg_delta_x + avg_delta_y + avg_delta_z) / 3
|
||||
|
||||
scale_x = avg_delta / avg_delta_x
|
||||
scale_y = avg_delta / avg_delta_y
|
||||
if avg_delta_z == 0:
|
||||
avg_delta_z=1
|
||||
scale_z = avg_delta / avg_delta_z
|
||||
|
||||
self._scale = (scale_x, scale_y, scale_z)
|
||||
|
||||
return self._offset, self._scale
|
||||
|
||||
def setup():
|
||||
global bmm150
|
||||
while ERROR == bmm150.sensor_init():
|
||||
print("sensor init error ,please check connect")
|
||||
'''
|
||||
POWERMODE_NORMAL
|
||||
POWERMODE_FORCED
|
||||
POWERMODE_SLEEP
|
||||
POWERMODE_SUSPEND
|
||||
'''
|
||||
bmm150.set_operation_mode(POWERMODE_NORMAL)
|
||||
|
||||
'''
|
||||
PRESETMODE_LOWPOWER
|
||||
PRESETMODE_REGULAR
|
||||
PRESETMODE_HIGHACCURACY
|
||||
PRESETMODE_ENHANCED
|
||||
'''
|
||||
bmm150.set_preset_mode(PRESETMODE_LOWPOWER)
|
||||
|
||||
'''
|
||||
Enable or disable the pin :
|
||||
ENABLE_DRDY
|
||||
DISABLE_DRDY (default mode)
|
||||
|
||||
polarity Active level
|
||||
POKARITY_HIGH (default active high level )
|
||||
POKARITY_LOW
|
||||
'''
|
||||
bmm150.set_data_readly_interrupt_pin(ENABLE_DRDY ,POKARITY_HIGH)
|
||||
|
||||
# bmm150.calibrate(200, 200)
|
||||
|
||||
def loop():
|
||||
global bmm150, img
|
||||
if bmm150.get_data_readly_state() == 1:
|
||||
rslt = bmm150.get_geomagnetic()
|
||||
print("mag x = %d ut"%rslt[0])
|
||||
print("mag y = %d ut"%rslt[1])
|
||||
print("mag z = %d ut"%rslt[2])
|
||||
print("")
|
||||
color = (0, 255, 0)
|
||||
if rslt[0] > 100 or rslt[1] > 100 or rslt[2] > 100:
|
||||
color = (255, 0, 0)
|
||||
img.clear()
|
||||
img.draw_rectangle(0, 0 , img.width(), img.height(), color, fill=True)
|
||||
img.draw_string(10, 10, "mag x = %d ut"%rslt[0], scale=2)
|
||||
img.draw_string(10, 40, "mag y = %d ut"%rslt[1], scale=2)
|
||||
img.draw_string(10, 70, "mag z = %d ut"%rslt[2], scale=2)
|
||||
lcd.display(img)
|
||||
else:
|
||||
time.sleep(0.2)
|
||||
time.sleep(0.2)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import lcd, image
|
||||
lcd.init()
|
||||
img = image.Image(size=(320, 240))
|
||||
tmp = I2C(I2C.I2C0, freq = 100*1000, scl = 28, sda = 22)
|
||||
print(tmp.scan())
|
||||
bmm150 = BMM150(tmp, 0x13)
|
||||
|
||||
setup()
|
||||
while True:
|
||||
loop()
|
||||
|
||||
|
Loading…
Reference in New Issue