Example Code for Arduino- Duty-Cycle Low-Power Mode External Interrupt Reading

The article guides users to communicate with the BMV080 via the I2C interface of ESP32-E, configure the duty-cycle period and integration time, enable the fast response algorithm, blockage detection and vibration filtering, trigger data reading through GPIO14 external interrupt, obtain PM1.0/PM2.5/PM10 concentrations as well as blockage and out-of-range statuses, and print the outputs.

Hardware Preparation

Software Preparation

Wiring Diagram

SEN0662 I2C INT Wiring Diagram

Connection Description:

Sensor Pin: VCC Connect to Main Controller Pin: 3.3V
Sensor Pin: GND Connect to Main Controller Pin: GND
Sensor Pin: C Connect to Main Controller Pin: 22/SCL
Sensor Pin: D Connect to Main Controller Pin: 21/SDA
Sensor Pin: INT Connect to Main Controller Pin: 14/D6
  • DIP switch configuration for the sensor: Set communication mode to I2C, and set the I2C address to 0x57 (A0=1, A1=1, factory default address).

Sample Code

#include "DFRobot_BMV080_Gravity.h"

/**
 * Duty‑cycle timing parameters
 * @param DUTY_CYCLE_PERIOD    Total duration of one full cycle, unit: second
 * @param INTEGRATION_TIME     Sensor active measurement time per cycle, unit: second
 */
#define DUTY_CYCLE_PERIOD 30
#define INTEGRATION_TIME  10.0f

// I2C address, configured by hardware pin A0/A1 on module
const uint8_t I2C_ADDR = 0x57;
DFRobot_BMV080_Gravity_I2C sensor(&Wire, I2C_ADDR);

// Interrupt flag, volatile for shared access between ISR and main loop
volatile uint8_t dataFlag = 0;

void IRAM_ATTR onInterrupt(void)
{
  if (dataFlag == 0) {
    dataFlag = 1;
  }
}

// ESP32‑E interrupt pin: Module INT pin connected to GPIO14
const uint8_t INT_PIN = 14;

void setup()
{
  delay(2000);
  Serial.begin(115200);
  while (!Serial) {
    delay(100);
  }

  // I2C sensor initialization
  while (!sensor.begin()) {
    Serial.println("Sensor init failed");
    delay(1000);
  }
  Serial.println("BMV080 Gravity init succeeded");

  /**
   * Configure duty‑cycle timing parameters
   * Total duty‑cycle period must be greater than or equal to integration time + 2 seconds
   * Pay attention to configuration order when modifying parameters:
   * - Increase integration time: enlarge total period first
   * - Shorten total period: reduce integration time first
   */
  if (sensor.setDutyCyclingPeriod(DUTY_CYCLE_PERIOD) != 0) {
    Serial.println("Set duty‑cycle period failed");
  }
  Serial.print("Duty‑cycle Period: ");
  Serial.println(sensor.getDutyCyclingPeriod());

  if (sensor.setIntegrationTime(INTEGRATION_TIME) != 0) {
    Serial.println("Set integration time failed");
  }
  Serial.print("Integration Time: ");
  Serial.println(sensor.getIntegrationTime());

  /**
   * Configure measurement algorithm and filtering options
   * @note eFastResponse is recommended for duty‑cycle mode
   */
  sensor.setMeasurementAlgorithm(DFRobot_BMV080_Gravity::eFastResponse);
  Serial.print("Measurement Algorithm: ");
  Serial.println(sensor.getMeasurementAlgorithm());

  sensor.setObstructionDetection(true);
  Serial.print("Obstruction Detection: ");
  Serial.println(sensor.getObstructionDetection() ? "Enabled" : "Disabled");

  sensor.setVibrationFiltering(true);
  Serial.print("Vibration Filtering: ");
  Serial.println(sensor.getVibrationFiltering() ? "Enabled" : "Disabled");

  // Start duty‑cycle measurement mode, firmware applies cached parameters before measurement starts
  if (sensor.setMeasureMode(DFRobot_BMV080_Gravity::eDutyCycleMode) == 0) {
    Serial.println("Duty‑cycle measurement mode started");
  } else {
    Serial.println("Start measurement failed");
  }

  // Configure hardware external interrupt. INT pulse will be generated when each measurement cycle completes; callback only sets flag
  pinMode(INT_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(INT_PIN), onInterrupt, FALLING);
  Serial.print("External interrupt configured, INT pin is GPIO");
  Serial.println(INT_PIN);
}

void loop()
{
  DFRobot_BMV080_Gravity::sData_t data;
  if (dataFlag == 1) {
    /**
     * getData reads PM concentration, runtime, status, obstruction/out‑of‑range warning, sample sequence number and other information
     */
    if (sensor.getData(&data)) {
      dataFlag = 0;

      Serial.print("PM1.0: ");
      Serial.print(data.PM1);
      Serial.print(" ug/m3  PM2.5: ");
      Serial.print(data.PM2_5);
      Serial.print(" ug/m3  PM10: ");
      Serial.print(data.PM10);
      Serial.print(" ug/m3");

      if (data.isObstructed) {
        Serial.print("  [Obstruction Detected]");
      }
      if (data.isOutsideMeasurementRange) {
        Serial.print("  [Measurement out of range]");
      }
      Serial.println();
    }
  }
}

Result

SEN0662-I2C INT Result

Was this article helpful?

TOP