Sensor parameters
What this example shows
Reading, and optionally changing, the settings the Bosch driver uses to turn the sensor's raw data into PM values: volumetric mass density, integration time, distribution ID, obstruction detection, vibration filtering and the measurement algorithm. The example prints the current value of each one, then starts continuous measurement and prints PM10, PM2.5 and PM1 like the Read PM values example.
The lines that change the settings are inside a comment block in
read_configure_parameters(). Remove the /* and */ around them and edit the
values to apply your own. They run before setMode(), which is where they have
to be: the sensor takes its settings when the measurement starts.
The example code
This is Parameters.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 "Wire.h"
#include "BMV080-SOLDERED.h"
BMV080 bmv080; // Create and instance of the BMV080 class
#define BMV080_ADDR 0x57 // BMV080 default I2C address
void setup()
{
Serial.begin(115200);
// Wait for serial to become available
while (!Serial) delay(10);
Wire.begin();
// Attempt to initialize the sensor via I2C
if (bmv080.begin(BMV080_ADDR, Wire) == false)
{
Serial.println("BMV080 not detected");
while (1)
;
}
Serial.println("BMV080 found!");
// Initialize the sensor
if (bmv080.init())
{
Serial.println("BMV sensor initialized");
}
else
{
Serial.println("BMV initialization failed");
while (1)
;
}
// Read (and optionaly configure) sensor parameters
read_configure_parameters();
// 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()
{
// Attempt to read new measurement data from the sensor
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);
}
// Function which reads current configuration state of BMV080 sensor
// and shows you how to set those parameters to custom values
void read_configure_parameters(void)
{
// Variables to store the parameters, will be used for storing
// current values, and (optionaly) setting custom values for each parameter
float volumetric_mass_density = 0.0f;
float integration_time = 0.0f;
uint32_t distribution_id = 0;
bool do_obstruction_detection = false;
bool do_vibration_filtering = false;
uint8_t measurementAlgorithm = E_BMV080_MEASUREMENT_ALGORITHM_BALANCED;
// ===========================================================
// Reading current configuration parameters
// ===========================================================
// Get default parameter "volumetric_mass_density"
volumetric_mass_density = bmv080.volumetricMassDensity();
Serial.print("BMV080 'volumetric_mass_density' current value: ");
Serial.println(volumetric_mass_density);
// Get default parameter "integration_time"
integration_time = bmv080.integrationTime();
Serial.print("BMV080 'integration_time' current value: ");
Serial.println(integration_time);
// Get default parameter "distribution_id"
distribution_id = bmv080.distributionId();
Serial.print("BMV080 'distribution_id' current value: ");
Serial.println(distribution_id);
// Get default parameter "do_obstruction_detection"
do_obstruction_detection = bmv080.doObstructionDetection();
Serial.print("BMV080 'do_obstruction_detection' current value: ");
if(do_obstruction_detection == true)
{
Serial.println("true");
}
else
{
Serial.println("false");
}
// Get default parameter "do_vibration_filtering"
do_vibration_filtering = bmv080.doVibrationFiltering();
Serial.print("BMV080 'do_vibration_filtering' current value: ");
if(do_vibration_filtering == true)
{
Serial.println("true");
}
else
{
Serial.println("false");
}
// Get default parameter "measurement_algorithm"
measurementAlgorithm = bmv080.measurementAlgorithm();
Serial.print("BMV080 'measurement_algorithm' current value: ");
switch (measurementAlgorithm)
{
case E_BMV080_MEASUREMENT_ALGORITHM_FAST_RESPONSE:
Serial.println("Fast Response");
break;
case E_BMV080_MEASUREMENT_ALGORITHM_BALANCED:
Serial.println("Balanced");
break;
case E_BMV080_MEASUREMENT_ALGORITHM_HIGH_PRECISION:
Serial.println("High Precision");
break;
default:
Serial.println("Unknown");
break;
}
// ===========================================================
// Setting new configuration parameters
// ===========================================================
// Uncomment the following lines below to set the parameters to custom values
/*
volumetric_mass_density = 1.6f;
integration_time = 10.0f;
distribution_id = 3;
do_obstruction_detection = true;
do_vibration_filtering = false;
measurementAlgorithm = E_BMV080_MEASUREMENT_ALGORITHM_BALANCED;
Serial.println("----- Setting new parameters -----");
// Set custom parameter "volumetric_mass_density"
if(bmv080.setVolumetricMassDensity(volumetric_mass_density) == true)
{
Serial.print("BMV080 volumetric_mass_density SET TO: ");
Serial.println(volumetric_mass_density);
}
else
{
Serial.println("Error setting BMV080 parameter 'volumetric_mass_density'");
}
// Set custom parameter "integration_time"
if(bmv080.setIntegrationTime(integration_time) == true)
{
Serial.print("BMV080 integration_time SET TO: ");
Serial.println(integration_time);
}
else
{
Serial.println("Error setting BMV080 parameter 'integration_time'");
}
// Set custom parameter "distribution_id"
if(bmv080.setDistributionId(distribution_id) == true)
{
Serial.print("BMV080 distribution_id SET TO: ");
Serial.println(distribution_id);
}
else
{
Serial.println("Error setting BMV080 parameter 'distribution_id'");
}
// Set custom parameter "do_obstruction_detection"
if(bmv080.setDoObstructionDetection(do_obstruction_detection) == true)
{
Serial.print("BMV080 do_obstruction_detection SET TO: ");
if(do_obstruction_detection == true)
{
Serial.println("true");
}
else
{
Serial.println("false");
}
}
else
{
Serial.println("Error setting BMV080 parameter 'do_obstruction_detection'");
}
// Set custom parameter "do_vibration_filtering"
if(bmv080.setDoVibrationFiltering(do_vibration_filtering) == true)
{
Serial.print("BMV080 do_vibration_filtering SET TO: ");
if(do_vibration_filtering == true)
{
Serial.println("true");
}
else
{
Serial.println("false");
}
}
else
{
Serial.println("Error setting BMV080 parameter 'do_vibration_filtering'");
}
// Set custom parameter "measurement_algorithm"
if (bmv080.setMeasurementAlgorithm(measurementAlgorithm) == true)
{
Serial.print("BMV080 measurement_algorithm SET TO: ");
switch (measurementAlgorithm)
{
case E_BMV080_MEASUREMENT_ALGORITHM_FAST_RESPONSE:
Serial.println("Fast Response");
break;
case E_BMV080_MEASUREMENT_ALGORITHM_BALANCED:
Serial.println("Balanced");
break;
case E_BMV080_MEASUREMENT_ALGORITHM_HIGH_PRECISION:
Serial.println("High Precision");
break;
default:
Serial.println("Unknown");
break;
}
}
else
{
Serial.println("Error setting BMV080 parameter 'measurement_algorithm'");
}
Serial.println();
*/
}
Expected result, from a bench run on this board (the run did not record which controller it used):
BMV080 found!
BMV sensor initialized
BMV080 'volumetric_mass_density' current value: 1.60
BMV080 'integration_time' current value: 10.00
BMV080 'distribution_id' current value: 3
BMV080 'do_obstruction_detection' current value: true
BMV080 'do_vibration_filtering' current value: false
BMV080 'measurement_algorithm' current value: High Precision
BMV080 set to continuous mode
PM10: 9.88 PM2.5: 7.15 PM1: 5.07
PM10: 10.12 PM2.5: 7.33 PM1: 5.18
PM10: 9.95 PM2.5: 7.21 PM1: 5.11
The six current value lines show the sensor's settings as the unchanged
sketch reads them. After BMV080 set to continuous mode, a line
appears about once a second with the PM values in µg/m³. Your PM numbers depend
on the air around the sensor.
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.
volumetricMassDensity()returns floatReads the particle density the driver uses to convert particle measurements into mass concentration.
ReturnsThe density in g/cm³, or 0.0 when it could not be read.
setVolumetricMassDensity(float volumetric_mass_density)returns boolSets the particle density used for the mass concentration. The example's suggested value is 1.6.
Returnstrue when the value was set, false otherwise.
Parameters
| Name | Type | Description |
|---|---|---|
volumetric_mass_density | float | The particle density in g/cm³. |
integrationTime()returns floatReads the integration time: the measurement window over which the sensor computes one PM value. In duty cycling mode it also covers the time the sensor is on.
ReturnsThe integration time in seconds (10 by default), or 0.0 when it could not be read.
setIntegrationTime(float integration_time)returns boolSets the integration time. The example's suggested value is 10.0, the Bosch default.
Returnstrue when the value was set, false otherwise.
Parameters
| Name | Type | Description |
|---|---|---|
integration_time | float | The measurement window in seconds. |
distributionId()returns uint32_tReads the distribution ID: the particle size distribution model the driver uses to classify particles.
ReturnsThe distribution ID, or 0 when it could not be read.
setDistributionId(uint32_t distribution_id)returns boolSelects the particle size distribution model. The example's suggested value is 3.
Returnstrue when the value was set, false otherwise.
Parameters
| Name | Type | Description |
|---|---|---|
distribution_id | uint32_t | The distribution ID to use. |
doObstructionDetection()returns boolReads whether obstruction detection is on. When it is, isObstructed() reports a blocked optical path.
Returnstrue when obstruction detection is on, false when it is off or could not be read.
setDoObstructionDetection(bool do_obstruction_detection)returns boolTurns obstruction detection on or off.
Returnstrue when the setting was changed, false otherwise.
Parameters
| Name | Type | Description |
|---|---|---|
do_obstruction_detection | bool | true to turn obstruction detection on, false to turn it off. |
doVibrationFiltering()returns boolReads whether vibration filtering is on.
Returnstrue when vibration filtering is on, false when it is off or could not be read.
setDoVibrationFiltering(bool do_vibration_filtering)returns boolTurns vibration filtering on or off.
Returnstrue when the setting was changed, false otherwise.
Parameters
| Name | Type | Description |
|---|---|---|
do_vibration_filtering | bool | true to turn vibration filtering on, false to turn it off. |
measurementAlgorithm()returns uint8_tReads which measurement algorithm the driver uses.
ReturnsE_BMV080_MEASUREMENT_ALGORITHM_FAST_RESPONSE (1), E_BMV080_MEASUREMENT_ALGORITHM_BALANCED (2) or E_BMV080_MEASUREMENT_ALGORITHM_HIGH_PRECISION (3), or 0 when it could not be read.
setMeasurementAlgorithm(uint8_t measurement_algorithm)returns boolSelects the measurement algorithm. Fast response gives the quickest response, high precision the best precision, and balanced sits between the two. High precision is the Bosch default. Duty cycling always uses fast response.
Returnstrue when the algorithm was set, false otherwise.
Parameters
| Name | Type | Description |
|---|---|---|
measurement_algorithm | uint8_t | One of E_BMV080_MEASUREMENT_ALGORITHM_FAST_RESPONSE, E_BMV080_MEASUREMENT_ALGORITHM_BALANCED or E_BMV080_MEASUREMENT_ALGORITHM_HIGH_PRECISION. |
setMode(uint8_t mode)returns boolStarts measuring in the mode you choose, with the settings made before it.
Returnstrue when the Bosch driver started the measurement, false otherwise.
Parameters
| Name | Type | Description |
|---|---|---|
mode | uint8_t | BMV080_MODE_CONTINUOUS for continuous measurement, as here, 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().
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.
Returnstrue when the latest reading was obstructed, false otherwise.
Putting it together
Read or change the settings after init() and before setMode(). Each getter
returns 0, 0.0 or false when the driver could not read the setting, and each
setter returns true only when the driver accepted the new value, so check the
result before relying on it.