使用MMA8451加速度计和Rpi进行运动检测,我是否正确读写寄存器?

时间:2018-11-27 11:27:09

标签: python raspberry-pi i2c

大家早安, 我正在尝试使用树莓派2b +和加速度计MMA8451进行项目。 我想将Rpi放在购物车上并测量振动,即使它沿X方向移动。 实际上,我只是尝试添加运动检测来修改Tony Dicola代码,这里是他的代码: https://github.com/adafruit/Adafruit_CircuitPython_MMA8451

我看过加速度计数据表https://www.nxp.com/docs/en/data-sheet/MMA8451Q.pdf 以及特定的“运动检测”一章也http://cache.freescale.com/files/sensor ... AN4070.pdf (以及许多其他数据表。) 在第12页的最后一个示例中,有一个示例,它与我的目标有些不同,但是我一直遵循它以了解其工作原理。 它是用C ++编写的,我必须在python中进行转换。 但是我在这里找到了一个完美的解释: https://www.digikey.com/en/maker/projects/b447ac46dced47d6a94c811725f28b1b 它确实做得很好,它使用不同的设备,但原理与我所想的完全相同。.但是我无法理解如何轻松实现运动检测,我只是按照说明进行操作,但是没有用,该死的。

我认为这不是寄存器配置问题。 任何人都可以告诉我,在Tony DiCola代码中是否缺少重要的东西? 我是python和i2c的新手,也许这并不难。

正如#planet建议的那样:

在我的主要例程中,我有:

import time
import board
import busio
import adafruit_mma8451V4
import csv
import datetime

# Initialize I2C bus.
i2c = busio.I2C(board.SCL, board.SDA)

# Initialize MMA8451 module.
sensor = adafruit_mma8451V4.MMA8451(i2c)
while True:
   while sensor.Motion():
       with open('Accelerometer.csv', 'a+') as csvfile:
           sensorwriter = csv.writer(csvfile) #, delimiter=' ',
                                   #quotechar='|', quoting=csv.QUOTE_MINIMAL)
           sensorwriter.writerow(['Datetime', 'X_Accel (m/s^2)', 'Y_Accel (m/s^2)', 'Z_Accel (m/s^2)'])

            x, y, z = sensor.acceleration
            time_now = datetime.datetime.now()
            sensor.MotionRegister()    

            print('Time={0}   X={1:0.3f} m/s^2  Y:{2:0.3f} m/s^2  Z:{3:0.3f} m/s^2'.format(time_now, X, Y, Z))
            sensorwriter.writerow([time_now, X, Y, Z])
            time.sleep(2)
    IntSourceMFF = sensor.MotionRegister() 

我知道的差不多。

这是我在I2C类中添加的内容:

def Motion (self): #, IntSourceSystem,IntSourceMFF):
    print(_MMA8451_INT_SOURCE)
    print(_MMA8451_REG_CTRL_REG1)
    self._write_u8(_MMA8451_REG_CTRL_REG1, 0x18) # Standby Mode
    #self._write_u8(_MMA8451_REG_CTRL_REG1, 0x00)        # deactivate
    print(_MMA8451_REG_CTRL_REG1)
    self._write_u8(REG_FF_MT_CONFIG, 0xD8) #Moto detection X axe 
    self._write_u8(REG_FF_MT_THS, 0x30)    #threshold 1g: es 3g/0.063g = 48 counts = 30 (hexadecimal)
    self._write_u8(REG_FF_MT_COUNT, 0x0A) #Debounce counter, set at 100ms timer and 800Hz
    self._write_u8(_MMA8451_REG_CTRL_REG4, 0x04)
    self._write_u8(_MMA8451_REG_CTRL_REG5, 0x04)
    print(_MMA8451_INT_SOURCE)
    CTRLreg1 = self._read_u8(_MMA8451_REG_CTRL_REG1)
##  CTRLreg1 |= 0x01
##  self._write_u8(_MMA8451_REG_CTRL_REG1, CTRLreg1)
    self._write_u8(_MMA8451_REG_CTRL_REG1, CTRLreg1 | 0x01) #activated
    print(_MMA8451_REG_CTRL_REG1)
    #self._write_u8(CTRLreg1)
    #IntSourceSystem = self._read_u8(_MMA8451_INT_SOURCE)
    #self._read_into(_MMA8451_INT_SOURCE, self._BUFFER, count=6)
    #IntSourceSystem = struct.unpack('>hhh', self._BUFFER)        
    #IntSourceSystem = self._read_u8(0x0C)
    #print(IntSourceSystem)
    #print(IntSourceSystem & 0b100)
    #Int_SourceSystem = (IntSourceSystem & 0x04)
    #print(Int_SourceSystem)       
    #if ((IntSourceSystem & 0x04) == 0x04):
    #if ((IntSourceSystem & 0x04) >0):
    #if ((_MMA8451_INT_SOURCE & 0x04) == 0x04):
    #if ((self._read_u8(_MMA8451_INT_SOURCE) & 0x04) == 0x04):
    print(self._read_u8(_MMA8451_INT_SOURCE & 0x04))
    if self._read_u8(_MMA8451_INT_SOURCE & 0x04) > 0:
    #if ((self._read_u8(_MMA8451_INT_SOURCE) & 0b100) == 0b100):       
        print("You are into if")
        return True
    else:
        print("You are into else")
        return False

def MotionRegister (self):
    return self._read_u8(REG_MT_SRC)

我正在使用打印来查看寄存器,并且看起来我的动作还不足以使IF Motion的if条件变为True。 它是读/写问题吗?待机/激活问题?

在注释中,有一些我刚刚尝试过的代码行(可能删除它们是个好主意。)

这里有寄存器:

    # Internal constants:
_MMA8451_DEFAULT_ADDRESS   = const(0x1D)
_MMA8451_REG_OUT_X_MSB     = const(0x01)
_MMA8451_REG_SYSMOD        = const(0x0B)
_MMA8451_REG_WHOAMI        = const(0x0D)
_MMA8451_REG_XYZ_DATA_CFG  = const(0x0E)
_MMA8451_REG_PL_STATUS     = const(0x10)
_MMA8451_REG_PL_CFG        = const(0x11)
_MMA8451_REG_CTRL_REG1     = const(0x2A)
_MMA8451_REG_CTRL_REG2     = const(0x2B)
_MMA8451_REG_CTRL_REG4     = const(0x2D)
_MMA8451_REG_CTRL_REG5     = const(0x2E)
_MMA8451_DATARATE_MASK     = const(0b111)

_MMA8451_INT_SOURCE        = const(0x0C)

#Register Setting for the Motion/Freefall Function
REG_FF_MT_CONFIG    = const(0x15)  # Motion/Freefall Configuration
REG_FF_MT_THS       = const(0x17)  # Setting the Treshold
REG_FF_MT_COUNT     = const(0x18)  # Setting the Debounce Counter
REG_MT_SRC          = const(0x16)  # Motion/Freefall Source Detection

我的输出(它们只是印刷品)是:

12
42
42
12
42
0
You are into else

我想这可能是寄存器的读写问题,在我的代码中,我有:

def _read_into(self, address, buf, count=None):
    # Read bytes from the specified address into the provided buffer.
    # If count is not specified (the default) the entire buffer is filled,
    # otherwise only count bytes are copied in.
    # It's silly that pylint complains about an explicit check that buf
    # has at least 1 value.  I don't trust the implicit true/false
    # recommendation as it was not designed for bytearrays which may not
    # follow that semantic.  Ignore pylint's superfulous complaint.
    assert len(buf) > 0  #pylint: disable=len-as-condition
    if count is None:
        count = len(buf)
    with self._device as i2c:
        i2c.write_then_readinto(bytes([address & 0xFF]), buf,
                                in_end=count, stop=False)

def _read_u8(self, address):
    # Read an 8-bit unsigned value from the specified 8-bit address.
    self._read_into(address, self._BUFFER, count=1)
    return self._BUFFER[0]

def _write_u8(self, address, val):
    # Write an 8-bit unsigned value to the specified 8-bit address.
    with self._device as i2c:
        self._BUFFER[0] = address & 0xFF
        self._BUFFER[1] = val & 0xFF
        i2c.write(self._BUFFER, end=2)

但是在我提到的说明网站上,它使用:

def _write_8(self, address, data):
    # Write 1 byte of data from the specified 16-bit register address.
    with self._device:
        self._device.write(bytes((address >> 8) & 0xFF,
                                   address & 0xFF,
                                   data))

def _write_16(self, address, data):
    # Write a 16-bit big endian value to the specified 16-bit register
    # address.
    with self._device:
        self._device.write(bytes((address >> 8) & 0xFF,
                                   address & 0xFF,
                                  (data >> 8) & 0xFF,
                                   data & 0xFF))

def _read_8(self, address):
    # Read and return a byte from the specified 16-bit register address.
    with self._device:
        self._device.write(bytes((address >> 8) & 0xFF,
                                   address & 0xFF),
                           stop=False)
        result = bytearray(1)
        self._device.read_into(result)
        return result0

def _read_16(self, address):
    # Read and return a 16-bit unsigned big endian value read from the
    # specified 16-bit register address.
    with self._device:
        self._device.write(bytes((address >> 8) & 0xFF,
                                   address & 0xFF),
                           stop=False)
        result = bytearray(2)
        self._device.read_into(result)
        return (result0 << 8) | result1

我不认为16位读写对我有用,但是8位功能不同,这是问题吗?
我该如何处理? 抱歉,该帖子过长,希望它对您有用。

如果还不够,图像中有我正在关注的数据表中的实例:

Motion Detection Datasheet Example

0 个答案:

没有答案