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:
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 BMA400Konstruktor. 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
| Typ | Name | Beschreibung |
|---|---|---|
I2C | i2c | Ein initialisiertes machine.I2C-Objekt. Nur bei Firmware optional, die sich als esp32, esp8266 oder als eine ältere Soldered-Board-Firmware meldet. |
int | address | I2C-Adresse. BMA400_I2C_ADDRESS_SDO_LOW (0x14, der Standardwert) oder BMA400_I2C_ADDRESS_SDO_HIGH (0x15). |
status_string()returns strBeschreibt 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 NoneSchreibt die Konfiguration des generischen Interrupts 1 des BMA400. Das Ergebnis wird in sensor.status gespeichert.
ReturnsNichts; prüfen Sie sensor.status.
Parameter
| Typ | Name | Beschreibung |
|---|---|---|
dict | config | Schlü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 NoneStellt 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
| Typ | Name | Beschreibung |
|---|---|---|
int | channel | BMA400_INT_CHANNEL_1 oder BMA400_INT_CHANNEL_2. |
int | mode | BMA400_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 NoneSchaltet eine Interrupt-Bedingung ein oder aus. Das Ergebnis wird in sensor.status gespeichert.
ReturnsNichts; prüfen Sie sensor.status.
Parameter
| Typ | Name | Beschreibung |
|---|---|---|
int | int_type | Eine der BMA400_*_INT_EN-Konstanten, hier BMA400_GEN1_INT_EN. |
bool | enable | True zum Aktivieren, False zum Deaktivieren. |
get_interrupt_status()returns int or NoneLiest, 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.