Read PM values
What this example shows
Reading PM10, PM2.5 and PM1 from the BMV080 in continuous measurement mode, and checking whether something is blocking the sensor. The sensor delivers a new reading about once a second; the sketch asks for one every 100 ms and prints a line only when a new one has arrived.
The example code
This is simpleReading.ino from the pinned library, without its header
comment. The sketch itself is exactly as shipped. It uses the board's default
address, 0x57.
#include "BMV080-SOLDERED.h"
BMV080 bmv080; // Create an instance of the BMV080 class
#define BMV080_ADDR 0x57 // BMV080 default address
void setup()
{
Serial.begin(115200);
while (!Serial)
delay(10); // Wait for Serial to become available.
Wire.begin();
if (bmv080.begin(BMV080_ADDR, Wire) == false)
{
Serial.println(
"BMV080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
while (1)
;
}
/* Initialize the Sensor (read driver, open, reset, id etc.)*/
bmv080.init();
/* Set the sensor mode to continuous mode */
if (bmv080.setMode(BMV080_MODE_CONTINUOUS) == true)
{
Serial.println("BMV080 set to continuous mode");
}
else
{
Serial.println("Error setting BMV080 mode");
}
}
void loop()
{
if (bmv080.readSensor())
{
float pm10 = bmv080.PM10();
float pm25 = bmv080.PM25();
float pm1 = bmv080.PM1();
Serial.print("PM10: ");
Serial.print(pm10);
Serial.print("\t");
Serial.print("PM2.5: ");
Serial.print(pm25);
Serial.print("\t");
Serial.print("PM1: ");
Serial.print(pm1);
if (bmv080.isObstructed() == true)
{
Serial.print("\tObstructed");
}
Serial.println();
}
delay(100);
}
Expected result, from a bench run on this board (the run did not record which controller it used):
BMV080 set to continuous mode
PM10: 9.84 PM2.5: 7.12 PM1: 5.06
PM10: 10.27 PM2.5: 7.39 PM1: 5.21
PM10: 10.03 PM2.5: 7.25 PM1: 5.14
PM10: 9.71 PM2.5: 7.01 PM1: 4.98
PM10: 9.92 PM2.5: 7.18 PM1: 5.09
A new line appears about once a second, with each value in µg/m³, and ends
with Obstructed when the sensor's view is blocked. Your numbers depend on the
air around the sensor. If the sensor does not answer, the sketch prints
BMV080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...
and stops.
Functions used
BMV080()returns NoneCreates the sensor object. It takes no arguments: the address and the Wire port are given to begin().
ReturnsConstructor; no return value.
begin(const uint8_t address = BMV080_DEFAULT_ADDRESS, TwoWire &wirePort = Wire)returns boolSets the I2C address and Wire port the library uses and checks that the sensor answers at that address. It does not start the I2C bus, so call Wire.begin() first, as the example does.
Returnstrue when the sensor answered at the address, false otherwise.
Parameters
| Name | Type | Description |
|---|---|---|
address | uint8_t | The sensor's I2C address. Defaults to BMV080_DEFAULT_ADDRESS, which is 0x57, the board's default. |
wirePort | TwoWire & | The I2C port to use. Defaults to Wire. |
init()returns boolPrepares the sensor through the Bosch driver: reads the driver version, opens the sensor, performs a soft reset and reads the sensor's ID. Call it after begin() and before anything else.
Returnstrue when every step succeeded, false when one failed.
setMode(uint8_t mode)returns boolStarts measuring in the mode you choose.
Returnstrue when the Bosch driver started the measurement, false otherwise.
Parameters
| Name | Type | Description |
|---|---|---|
mode | uint8_t | BMV080_MODE_CONTINUOUS for continuous measurement, or BMV080_MODE_DUTY_CYCLE for duty cycling. |
readSensor(bmv080_output_t *bmv080_output = nullptr)returns boolLets the Bosch driver fetch and process data from the sensor once. When a new reading arrives, the library keeps it for PM10(), PM25(), PM1() and isObstructed(). Call it regularly, as the example does in loop().
Returnstrue when a new reading arrived during this call, false otherwise.
Parameters
| Name | Type | Description |
|---|---|---|
bmv080_output | bmv080_output_t * | Optional. A Bosch output structure to copy the new reading into. The example leaves it out. |
PM10()returns floatReturns the PM10 value of the latest reading: particles 10 µm across or smaller.
ReturnsPM10 mass concentration in µg/m³.
PM25()returns floatReturns the PM2.5 value of the latest reading: particles 2.5 µm across or smaller.
ReturnsPM2.5 mass concentration in µg/m³.
PM1()returns floatReturns the PM1 value of the latest reading: particles 1 µm across or smaller.
ReturnsPM1 mass concentration in µg/m³.
isObstructed()returns boolReturns the obstruction flag of the latest reading. The sensor sets it when a fixed object sits in its optical path; brief obstructions, such as a hand waved past, are filtered out.
Returnstrue when the latest reading was obstructed, false otherwise.
Putting it together
The order matters: Wire.begin(), then begin() with the address, then
init(), then setMode(). After that, call readSensor() often and read the
values only when it returns true. If you change the address with jumpers JP2
and JP3, change BMV080_ADDR to match.