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
- SEN0662 Gravity: BMV080 PM2.5 Sensor × 1
- DFR0654 FireBeetle 2 ESP32-E Development Board × 1
- Several Dupont Wires
Software Preparation
- Download and install Arduino IDE: Download Link
- Download DFRobot_BMV080_Gravity library: DFRobot_BMV080_Gravity Library
- Download and install the DFRobot_RTU library: DFRobot_RTU Library
- Library Installation Guide: View Installation Tutorial
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

Was this article helpful?
