大家早安, 我正在尝试使用树莓派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位功能不同,这是问题吗?
我该如何处理?
抱歉,该帖子过长,希望它对您有用。
如果还不够,图像中有我正在关注的数据表中的实例: