SparkFun Triple Axis Accelerometer Breakout - BMA400 (Qwiic) Hookup Guide

Pages
Contributors: El Duderino
Favorited Favorite 0

Arduino Examples

The BMA400 Arduino Library includes twelve examples covering all major features of the accelerometer. In this section we'll take a closer look at three of them.

Example 1 - Basic Readings I2C

Example 1 demonstrates how to set the BMA400 up to communicate basic motion data over I2C. Open the example by navigating to File > Examples > SparkFun BMA400 Arduino Library > Example01_BasicReadingsI2C. Select your Board and Port and click Upload. Open the serial monitor after the upload completes with the baud set to 115200 to watch motion data print out.

If you have adjusted the ADR jumper to change to the alternate I2C address for the BMA400 comment/uncomment the line with the correct value:

language:c
uint8_t i2cAddress = BMA400_I2C_ADDRESS_DEFAULT; // 0x14
//uint8_t i2cAddress = BMA400_I2C_ADDRESS_SECONDARY; // 0x15

The example attempts to initialize the sensor with default settings in I2C at the specified address. If it cannot initialize properly, the code prints out an error in over serial:

language:c
while(accelerometer.beginI2C(i2cAddress) != BMA400_OK)
    {
        // Not connected, inform user
        Serial.println("Error: BMA400 not connected, check wiring and I2C address!");

        // Wait a bit to see if connection is established
        delay(1000);
    }

If you see this error, double check the sensor is connected properly and set to the correct I2C address and reset the development board or re-upload the code.

The loop polls the BMA400 for acceleration data every 20ms using the 'getSensorData();' function and prints out acceleration for all three axes in g's:

language:c
void loop()
{
    // Get measurements from the sensor. This must be called before accessing
    // the acceleration data, otherwise it will never update
    accelerometer.getSensorData();

    // Print acceleration data
    Serial.print("Acceleration in g's");
    Serial.print("\t");
    Serial.print("X: ");
    Serial.print(accelerometer.data.accelX, 3);
    Serial.print("\t");
    Serial.print("Y: ");
    Serial.print(accelerometer.data.accelY, 3);
    Serial.print("\t");
    Serial.print("Z: ");
    Serial.println(accelerometer.data.accelZ, 3);

    // Print 50x per second
    delay(20);
}

Move the sensor around in different directions and watch the acceleration data change with the motion.

Example 6 - Motion Detection

Example 6 - Motion Detection demonstrates how to configure one of the BMA400's interrupt pins (INT1) to trigger when the sensor detects motion over 1g on the Z axis.

The code defaults to use 'D2' as the interrupt pin on a connected development board. If your development board does not support external interrupts on 'D2' change the value here:

language:c
int interruptPin = 2;

If you're not sure which pins on your board support external interrupts, this reference page has lists available interrupt pins for most common Arduino development boards.

After initializing the BMA400 over I2C, the code configures the interrupt feature:

language:c
bma400_gen_int_conf config =
    {
        .gen_int_thres = 5, // 8mg resolution (eg. gen_int_thres=5 results in 40mg)
        .gen_int_dur = 5, // 10ms resolution (eg. gen_int_dur=5 results in 50ms)
        .axes_sel = BMA400_AXIS_XYZ_EN, // Which axes to evaluate for interrupts (X/Y/Z in any combination)
        .data_src = BMA400_DATA_SRC_ACCEL_FILT_2, // Which filter to use (must be 100Hz, datasheet recommends filter 2)
        .criterion_sel = BMA400_ACTIVITY_INT, // Trigger interrupts when active or inactive
        .evaluate_axes = BMA400_ANY_AXES_INT, // Logical combining of axes for interrupt condition (OR/AND)
        .ref_update = BMA400_UPDATE_EVERY_TIME, // Whether to automatically update reference values
        .hysteresis = BMA400_HYST_96_MG, // Hysteresis acceleration for noise rejection
        .int_thres_ref_x = 0, // Raw 12-bit acceleration value
        .int_thres_ref_y = 0, // Raw 12-bit acceleration value
        .int_thres_ref_z = 512, // Raw 12-bit acceleration value (at 4g range (default), 512 = 1g)
        .int_chan = BMA400_INT_CHANNEL_1 // Which pin to use for interrupts
    };
    accelerometer.setGeneric1Interrupt(&config);

    // Here we configure the INT1 pin to push/pull mode, active high
    accelerometer.setInterruptPinMode(BMA400_INT_CHANNEL_1, BMA400_INT_PUSH_PULL_ACTIVE_1);

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

    // Setup interrupt handler
    attachInterrupt(digitalPinToInterrupt(interruptPin), bma400InterruptHandler, RISING);

This configures INT1 to operate in push/pull mode and active HIGH whenever the BMA400 reports motion the Z axis over 1g among other settings. It also enables the interrupt condition and sets up the interrupt handler.

The main loop waits for an interrupt event to happen and prints out whenever an interrupt occurs and motion is detected.

Example 10 - Step Counter

Example 10 - Step Counter shows how to use the BMA400's Step Counter feature commonly found in smart watches and other activity monitors. The sensor handles step detection and counting so we'll leave those settings as default. They can technically be altered but we do not recommend it as it's not well documented and can cause unpredictable behavior.

After initializing the sensor, we select and configure INT1 for interrupts and enable step counting:

language:c
bma400_step_int_conf config =
    {
        .int_chan = BMA400_INT_CHANNEL_1 // Which pin to use for interrupts
    };
    accelerometer.setStepCounterInterrupt(&config);

    // Here we configure the INT1 pin to push/pull mode, active high
    accelerometer.setInterruptPinMode(BMA400_INT_CHANNEL_1, BMA400_INT_PUSH_PULL_ACTIVE_1);

    // Enable step counter interrupt condition. This must be set to enable step
    // counting at all, even if you don't want interrupts to be generated.
    // In that case,  set the interrupt channel above to BMA400_UNMAP_INT_PIN
    accelerometer.enableInterrupt(BMA400_STEP_COUNTER_INT_EN, true);

    // Setup interrupt handler
    attachInterrupt(digitalPinToInterrupt(interruptPin), bma400InterruptHandler, RISING);

The main loop checks for a step detection interrupt event and prints the step count and activity type over serial. Try moving the sensor around or attach it to your wrist to simulate a smart watch and walk/run around. You should see the data update with new step values and activity states.