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 setzt INT1, sobald sich eine Achse stärker als der Schwellenwert bewegt. Ihr Controller reagiert nur noch auf den Interrupt.

Verbinden Sie zusätzlich zu Qwiic oder den I2C-Header-Pins den Pin INT1 des Breakout mit dem digitalen Pin 2 Ihres Controllers, oder ändern Sie interruptPin im Sketch auf den Pin, den Sie verwenden. Der Pin muss Interrupts unterstützen.

Der Beispielcode​

Select Board
motionDetection.ino
/**
**************************************************
*
* @file motionDetection.ino
*
* @brief Example showing how to use the BMA400's generic interrupt
* feature to detect motion via a hardware interrupt pin
*
* @link solde.red/333419 : Soldered BMA400 Accelerometer breakout
*
* @authors SparkFun Electronics, modified by Soldered Electronics
***************************************************/
#include <BMA400-SOLDERED.h>

// Create an instance of the BMA400 sensor
Soldered_BMA400 accelerometer;

// Pin connected to the sensor's INT1 pin, change to match your wiring
int interruptPin = 2;

// Flag to know when an interrupt occurs
volatile bool interruptOccurred = false;

void bma400InterruptHandler()
{
interruptOccurred = true;
}

void setup()
{
// Initialize serial for output
Serial.begin(115200);
Serial.println("BMA400 Example - Motion Detection");

// Initialize I2C bus
Wire.begin();

// Check if sensor is connected and initialize it.
// Address is optional, defaults to 0x14
while (accelerometer.begin() != BMA400_OK)
{
Serial.println("Error: BMA400 not connected, check wiring and I2C address!");
delay(1000);
}

Serial.println("BMA400 connected!");

// Configure the generic interrupt feature. It triggers an interrupt
// when the measured acceleration exceeds a reference acceleration
bma400_gen_int_conf 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, // Raw 12-bit reference value
.int_thres_ref_y = 0, // Raw 12-bit reference value
.int_thres_ref_z = 512, // Raw 12-bit reference value (1g at 4g range)
.int_chan = BMA400_INT_CHANNEL_1 // Route interrupt to INT1 pin
};
accelerometer.setGeneric1Interrupt(&config);

// Configure INT1 pin to push/pull mode, active high
accelerometer.setInterruptPinMode(BMA400_INT_CHANNEL_1, BMA400_INT_PUSH_PULL_ACTIVE_1);

// Enable the generic 1 interrupt condition
accelerometer.enableInterrupt(BMA400_GEN1_INT_EN, true);

// Attach the interrupt handler to the microcontroller pin wired to INT1
attachInterrupt(digitalPinToInterrupt(interruptPin), bma400InterruptHandler, RISING);
}

void loop()
{
if (interruptOccurred)
{
interruptOccurred = false;

// Check which interrupt condition triggered
uint16_t interruptStatus = 0;
accelerometer.getInterruptStatus(&interruptStatus);

if (interruptStatus & BMA400_ASSERTED_GEN1_INT)
{
Serial.println("Motion detected!");
}
}
}

Dieses Beispiel verwendet außerdem attachInterrupt() und digitalPinToInterrupt() (Arduino-Referenz), die zum Arduino-Core gehören und nicht Teil der Soldered-BMA400-Accelerometer-Bibliothek sind.

Erwartetes Ergebnis:

Serial MonitorAutoscrollShow timestampNewline115200 baud
Message (Enter to send message to the board)
BMA400 Example - Motion Detection
BMA400 connected!
Motion detected!

Die ersten beiden Zeilen erscheinen beim Start. Motion detected! erscheint jedes Mal, wenn der BMA400 eine Bewegung über INT1 meldet.

Verwendete Funktionen​

Soldered_BMA400()returns none

Konstruktor. Erzeugt das Sensorobjekt; es kommuniziert erst mit dem Sensor, wenn Sie begin() aufrufen.

ReturnsKonstruktor; kein Rückgabewert.

int8_t begin(uint8_t address = BMA400_I2C_ADDRESS_DEFAULT, TwoWire &wirePort = Wire)returns int8_t

Startet den Sensor über I2C: setzt den BMA400 per Soft-Reset zurück, prüft seine Chip-ID und versetzt ihn in den normalen Energiemodus.

ReturnsBMA400_OK (0) bei Erfolg, sonst ein negativer Fehlercode. Eine andere Adresse als 0x14 oder 0x15 liefert BMA400_E_INVALID_CONFIG zurück.

Parameter

TypNameBeschreibung
uint8_taddressI2C-Adresse. BMA400_I2C_ADDRESS_DEFAULT (0x14, der Standardwert) oder BMA400_I2C_ADDRESS_SECONDARY (0x15).
TwoWire &wirePortZu verwendender I2C-Bus. Standardmäßig Wire.
int8_t setGeneric1Interrupt(bma400_gen_int_conf* config)returns int8_t

Schreibt die Konfiguration des generischen Interrupts 1 des BMA400: Schwellenwert, Dauer, Achsen, Datenquelle, Auslösekriterium, Referenzaktualisierung, Hysterese, Referenzwerte und den Interrupt-Pin, auf den er geleitet wird.

Returns0 bei Erfolg, negativ bei Fehler.

Parameter

TypNameBeschreibung
bma400_gen_int_conf*configZeiger auf die Konfiguration. Das Beispiel füllt gen_int_thres (Schritte von 8 mg), gen_int_dur (Schritte von 10 ms), axes_sel, data_src, criterion_sel, evaluate_axes, ref_update, hysteresis, int_thres_ref_x, int_thres_ref_y, int_thres_ref_z (rohe 12-Bit-Werte) und int_chan.
int8_t setInterruptPinMode(bma400_int_chan channel, uint8_t mode)returns int8_t

Stellt einen Interrupt-Pin als Push-Pull oder Open-Drain, aktiv High oder aktiv Low ein.

Returns0 bei Erfolg, negativ bei Fehler.

Parameter

TypNameBeschreibung
bma400_int_chanchannelDer zu konfigurierende Pin, zum Beispiel BMA400_INT_CHANNEL_1 für INT1.
uint8_tmodeBMA400_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.
int8_t enableInterrupt(bma400_int_type intType, bool enable)returns int8_t

Schaltet eine Interrupt-Bedingung ein oder aus.

Returns0 bei Erfolg, negativ bei Fehler.

Parameter

TypNameBeschreibung
bma400_int_typeintTypeDie Bedingung, zum Beispiel BMA400_GEN1_INT_EN für den generischen Interrupt 1.
boolenabletrue zum Aktivieren, false zum Deaktivieren.
int8_t getInterruptStatus(uint16_t* status)returns int8_t

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

Returns0 bei Erfolg, negativ bei Fehler.

Parameter

TypNameBeschreibung
uint16_t*statusErhält die Status-Flags, eine Kombination aus BMA400_ASSERTED_*-Werten.

Alles zusammen​

Mit gen_int_thres = 5 und gen_int_dur = 5 löst der Interrupt aus, wenn sich eine Achse für 50 ms um mehr als 40 mg von ihrer Referenz entfernt, entsprechend den Kommentaren im Beispiel. ref_update = BMA400_UPDATE_EVERY_TIME lässt den Chip die Referenz selbstständig aktualisieren, und die Z-Referenz von 512 entspricht 1 g im Bereich von ±4 g. INT1 ist auf Push-Pull, aktiv High, eingestellt, daher bindet der Sketch seinen Handler an eine RISING-Flanke.

Der Handler setzt nur ein volatile-Flag. loop() ruft dann getInterruptStatus() über I2C auf und gibt Motion detected! aus, wenn das Flag des generischen Interrupts 1 gesetzt ist.