One thing that throws me of a little is that it uses single bits of some registers to control some stuff.
i.e.
register ACCEL_CONFIG:
*Bit7 - x-axis self test
*Bit6 - y
*Bit5 - z
*Bit4:3 - range selection
*Bit3:0 - empty
Now with I2C.mem_write() I can write bytes to the addresses, but not bits within the byte. I guess the answer is in bitwise operations and stuff.
Here's what I got so far. Will continue tommorow.
Code: Select all
import pyb
import os
from struct import unpack as unp
class MPU9150():
'''
Module for the MPU9150 9DOF IMU.
'''
_mpu_addr = (104, 105) # addresses of MPU9150
# there can be two devices
# connected, first on 104,
# second on 105
# init
def __init__(self, side_str=None):
# choose wich i2c port to use
if side_str == 'X':
side = 1
elif side_str == 'Y':
side = 2
else:
print('pass either X or Y, defaulting to Y')
side = 2
# create i2c object
self.mpu_addr = self._mpu_addr[0]
self._mpu_i2c = pyb.I2C(side, pyb.I2C.MASTER)
self.chip_id = unp('>h', self._mpu_i2c.mem_read(1, self.mpu_addr, 0x75))[0] # who_am_i register
# wake, sleep and pwr_mgmt maybe should be
# mode() - returns mode
# mode('sleep') - sleep
# mode('wake') - wake
# but pwr_mgmt also controls other stuff
# don't know how to change single bits in byte on given address
# wake
def wake(self):
'''Wakes the device from sleep'''
self._mpu_i2c.mem_write(0x01, self.mpu_addr, 0x6B)
# sleep
def sleep(self):
'''Puts the device to sleep'''
self._mpu_i2c.mem_write(0x40, self.mpu_addr, 0x6B)
# pwr_mgmt
def get_pwr_mgmt(self):
'''Returns PWR_MGMT_1'''
return self._mpu_i2c.mem_read(2, self.mpu_addr, 0x6B)
# sample rate
def sample_rate(self, rate=None):
'''Returns the sample rate or sets it to the passed arg'''
if rate is None:
return unp('>h', self._mpu_i2c.mem_read(1, selfmpu_addr, 0x19))[0]
else:
pass
# this register also controls self test
# instead of list lookup bitshift operation possible
# accelerometer range
def accel_range(self, accel_range=None):
if accel_range is None:
return self._mpu_i2c.mem_read(1, self.mpu_addr, 0x1C)
else:
ar = (0x00, 0x08, 0x10, 0x18)
try:
print(ar[accel_range])
self._mpu_i2c.mem_write(ar[accel_range], self.mpu_addr, 0x1C)
except IndexError:
print('accel_range can only be 0, 1, 2 or 3')
# while use of dict is kinda cool, this needs
# a dict and a list to do something really easy
# however this makes it possible to do
# self.get_acceleration['x'] or 'xyz' or 'yz'
# or whatever
# but getting a single axis should not return a list
# get acceleration
def get_accel(self, xyz=None):
'''Returns the accelerations on axis passed in arg'''
if xyz is None:
xyz = 'xyz'
scale = 1
axyz = {'x': unp('>h', self._mpu_i2c.mem_read(2, self.mpu_addr, 0x3B))[0]*scale,
'y': unp('>h', self._mpu_i2c.mem_read(2, self.mpu_addr, 0x3D))[0]*scale,
'z': unp('>h', self._mpu_i2c.mem_read(2, self.mpu_addr, 0x3F))[0]*scale}
aout = []
for char in xyz:
aout.append(axyz[char])
return aout