Zum Hauptinhalt springen

Bewegungserkennung

Was dieses Beispiel zeigt​

Der BMA400 überwacht Bewegungen selbstständig. Der generische Interrupt 1 des Chips vergleicht die Beschleunigung mit einem Referenzwert und löst INT1 aus, sobald sich eine beliebige Achse um mehr als den Schwellenwert bewegt. Ihr Board reagiert nur auf den Interrupt.

Neben der I2C-Verdrahtung (im Beispiel GPIO 9 für SCL und GPIO 8 für SDA) verbinden Sie den Pin INT1 des Breakout mit GPIO 5, oder ändern Sie INT1_PIN auf den Pin, den Sie verwenden.

Der Beispielcode​

# FILE: bma400-motionDetection.py
# AUTHOR: Soldered Electronics
# BRIEF: Uses the BMA400's generic interrupt feature to detect motion via a
# hardware interrupt pin
# WORKS WITH: BMA400 Accelerometer breakout: www.solde.red/333419
# LAST UPDATED: 2026-09-17

from machine import I2C, Pin
from bma400 import (
BMA400,
BMA400_OK,
BMA400_AXIS_XYZ_EN,
BMA400_DATA_SRC_ACCEL_FILT_2,
BMA400_ACTIVITY_INT,
BMA400_ANY_AXES_INT,
BMA400_UPDATE_EVERY_TIME,
BMA400_HYST_96_MG,
BMA400_INT_CHANNEL_1,
BMA400_INT_PUSH_PULL_ACTIVE_1,
BMA400_GEN1_INT_EN,
BMA400_ASSERTED_GEN1_INT,
)

# Hardware setup: connect the breakout board's INT1 pin to INT1_PIN below
INT1_PIN = 5

mems_event = False


def int1_callback(pin):
global mems_event
mems_event = True


# Change these to match how your board wires I2C
i2c = I2C(0, scl=Pin(9), sda=Pin(8))
sensor = BMA400(i2c)

if sensor.status != BMA400_OK:
raise Exception("Failed to initialize BMA400: " + sensor.status_string())

# Configure the generic interrupt feature. It triggers an interrupt when the
# measured acceleration exceeds a reference acceleration
config = {
"gen_int_thres": 5, # 8mg resolution (e.g. 5 = 40mg)
"gen_int_dur": 5, # 10ms resolution (e.g. 5 = 50ms)
"axes_sel": BMA400_AXIS_XYZ_EN, # Evaluate all axes for interrupts
"data_src": BMA400_DATA_SRC_ACCEL_FILT_2, # Datasheet recommends filter 2 (100Hz)
"criterion_sel": BMA400_ACTIVITY_INT, # Trigger when active
"evaluate_axes": BMA400_ANY_AXES_INT, # Trigger if any axis exceeds threshold
"ref_update": BMA400_UPDATE_EVERY_TIME, # Automatically update reference values
"hysteresis": BMA400_HYST_96_MG, # Hysteresis for noise rejection
"int_thres_ref_x": 0,
"int_thres_ref_y": 0,
"int_thres_ref_z": 512, # 1g at 4g range
"int_chan": BMA400_INT_CHANNEL_1, # Route interrupt to INT1 pin
}
sensor.set_generic1_interrupt(config)

# Configure INT1 pin to push/pull mode, active high
sensor.set_interrupt_pin_mode(BMA400_INT_CHANNEL_1, BMA400_INT_PUSH_PULL_ACTIVE_1)

# Enable the generic 1 interrupt condition
sensor.enable_interrupt(BMA400_GEN1_INT_EN, True)

int1 = Pin(INT1_PIN, Pin.IN)
int1.irq(trigger=Pin.IRQ_RISING, handler=int1_callback)

print("Waiting for motion...")

while True:
if mems_event:
mems_event = False
status = sensor.get_interrupt_status()
if status is not None and (status & BMA400_ASSERTED_GEN1_INT):
print("Motion detected!")

🔗Vollständiges Beispiel öffnen

bma400-motionDetection.py bei Commit 484a5be

→

Dieses Beispiel verwendet außerdem machine.I2C (MicroPython-Referenz) und machine.Pin mit der Methode irq() (MicroPython-Referenz), die zur MicroPython-Firmware gehören und nicht Teil des Moduls bma400 sind.

Erwartetes Ergebnis:

ShellMicroPython
Waiting for motion...
Motion detected!

Waiting for motion... erscheint, sobald der Interrupt eingerichtet ist. Motion detected! erscheint jedes Mal, wenn der BMA400 eine Bewegung über INT1 meldet.

Verwendete Funktionen​

BMA400(i2c=None, address=BMA400_I2C_ADDRESS_SDO_LOW)returns BMA400

Konstruktor. Führt einen Soft-Reset des Sensors durch, prüft seine Chip-ID (0x90) und setzt ihn in den normalen Energiemodus. Löst eine Exception aus, wenn der Sensor nicht antwortet oder ein anderer Chip antwortet.

ReturnsDas Sensorobjekt.

Parameter

TypNameBeschreibung
I2Ci2cEin initialisiertes machine.I2C-Objekt. Nur bei Firmware optional, die sich als esp32, esp8266 oder als eine ältere Soldered-Board-Firmware meldet.
intaddressI2C-Adresse. BMA400_I2C_ADDRESS_SDO_LOW (0x14, der Standardwert) oder BMA400_I2C_ADDRESS_SDO_HIGH (0x15).
status_string()returns str

Beschreibt den aktuellen Statuscode sensor.status, zum Beispiel Communication failure oder Sensor not found.

ReturnsDie Beschreibung oder ein leerer String, wenn der Status BMA400_OK ist.

set_generic1_interrupt(config)returns None

Schreibt die Konfiguration des generischen Interrupts 1 des BMA400. Das Ergebnis wird in sensor.status gespeichert.

ReturnsNichts; prüfen Sie sensor.status.

Parameter

TypNameBeschreibung
dictconfigSchlüssel gen_int_thres (8-mg-Schritte), gen_int_dur (10-ms-Schritte), axes_sel, data_src, criterion_sel, evaluate_axes, ref_update, hysteresis, int_thres_ref_x, int_thres_ref_y, int_thres_ref_z und int_chan.
set_interrupt_pin_mode(channel, mode)returns None

Stellt einen Interrupt-Pin als Push-Pull oder Open-Drain, active high oder active low ein. Das Ergebnis wird in sensor.status gespeichert.

ReturnsNichts; prüfen Sie sensor.status.

Parameter

TypNameBeschreibung
intchannelBMA400_INT_CHANNEL_1 oder BMA400_INT_CHANNEL_2.
intmodeBMA400_INT_PUSH_PULL_ACTIVE_0, BMA400_INT_PUSH_PULL_ACTIVE_1 (Standard), BMA400_INT_OPEN_DRIVE_ACTIVE_0 oder BMA400_INT_OPEN_DRIVE_ACTIVE_1.
enable_interrupt(int_type, enable)returns None

Schaltet eine Interrupt-Bedingung ein oder aus. Das Ergebnis wird in sensor.status gespeichert.

ReturnsNichts; prüfen Sie sensor.status.

Parameter

TypNameBeschreibung
intint_typeEine der BMA400_*_INT_EN-Konstanten, hier BMA400_GEN1_INT_EN.
boolenableTrue zum Aktivieren, False zum Deaktivieren.
get_interrupt_status()returns int or None

Liest, welche Interrupt-Bedingungen ausgelöst sind. Prüfen Sie das Ergebnis gegen Flags wie BMA400_ASSERTED_GEN1_INT.

ReturnsEine Bitmaske aus BMA400_ASSERTED_*-Flags oder None bei einem Busfehler.

Zusammenfassung​

Wenn gen_int_thres und gen_int_dur beide auf 5 stehen, wird der Interrupt ausgelöst, wenn sich eine Achse für 50 ms um mehr als 40 mg von ihrer Referenz entfernt, entsprechend den Kommentaren im Beispiel. Mit ref_update auf BMA400_UPDATE_EVERY_TIME aktualisiert der Chip die Referenz selbstständig, und die Z-Referenz von 512 entspricht 1 g im ±4-g-Bereich. INT1 ist Push-Pull und active high, daher löst der Pin-Interrupt bei Pin.IRQ_RISING aus.

Der Callback setzt nur mems_event. Die Hauptschleife liest dann den Status über I2C aus und gibt Motion detected! aus, wenn das Flag des generischen Interrupts 1 gesetzt ist.