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

2024-09-29 23:18:16 发布

您现在位置:Python中文网/ 问答频道 /正文

大家早上好, 我正试图用我的树莓皮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 它做得很好,它使用了一种不同的设备,但原理很明显是相同的。。但我不明白如何容易地实现运动检测,我只是按照指令操作,但它不起作用,该死的。在

我不认为这是寄存器配置问题。。 有人能告诉我托尼·迪科拉密码里有什么重要的遗漏吗? 我是python和i2c的新手,可能这并不难。在

正如行星所暗示的:

在我的主要例行程序中:

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类中添加的内容:

^{pr2}$

我用打印来查看寄存器,看起来我的操作永远不足以将if条件变成def动作。 是读/写问题吗?待机/激活问题?在

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

这里有寄存器:

    # 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


Tags: theselfreaddataaddressdevicedefwith

热门问题