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
/**
**************************************************
*
* @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:
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 noneKonstruktor. 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_tStartet 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
| Typ | Name | Beschreibung |
|---|---|---|
uint8_t | address | I2C-Adresse. BMA400_I2C_ADDRESS_DEFAULT (0x14, der Standardwert) oder BMA400_I2C_ADDRESS_SECONDARY (0x15). |
TwoWire & | wirePort | Zu verwendender I2C-Bus. Standardmäßig Wire. |
int8_t setGeneric1Interrupt(bma400_gen_int_conf* config)returns int8_tSchreibt 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
| Typ | Name | Beschreibung |
|---|---|---|
bma400_gen_int_conf* | config | Zeiger 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_tStellt einen Interrupt-Pin als Push-Pull oder Open-Drain, aktiv High oder aktiv Low ein.
Returns0 bei Erfolg, negativ bei Fehler.
Parameter
| Typ | Name | Beschreibung |
|---|---|---|
bma400_int_chan | channel | Der zu konfigurierende Pin, zum Beispiel BMA400_INT_CHANNEL_1 für INT1. |
uint8_t | 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. |
int8_t enableInterrupt(bma400_int_type intType, bool enable)returns int8_tSchaltet eine Interrupt-Bedingung ein oder aus.
Returns0 bei Erfolg, negativ bei Fehler.
Parameter
| Typ | Name | Beschreibung |
|---|---|---|
bma400_int_type | intType | Die Bedingung, zum Beispiel BMA400_GEN1_INT_EN für den generischen Interrupt 1. |
bool | enable | true zum Aktivieren, false zum Deaktivieren. |
int8_t getInterruptStatus(uint16_t* status)returns int8_tLiest 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
| Typ | Name | Beschreibung |
|---|---|---|
uint16_t* | status | Erhä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.