Skip to main content

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.

Select Board
Parameters.ino
#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):

Serial MonitorAutoscrollShow timestampNewline115200 baud
Message (Enter to send message to the board)
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 None

Creates 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 bool

Sets 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

NameTypeDescription
addressuint8_tThe sensor's I2C address. Defaults to BMV080_DEFAULT_ADDRESS, which is 0x57, the board's default.
wirePortTwoWire &The I2C port to use. Defaults to Wire.
init()returns bool

Prepares 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 float

Reads 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 bool

Sets 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

NameTypeDescription
volumetric_mass_densityfloatThe particle density in g/cm³.
integrationTime()returns float

Reads 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 bool

Sets the integration time. The example's suggested value is 10.0, the Bosch default.

Returnstrue when the value was set, false otherwise.

Parameters

NameTypeDescription
integration_timefloatThe measurement window in seconds.
distributionId()returns uint32_t

Reads 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 bool

Selects the particle size distribution model. The example's suggested value is 3.

Returnstrue when the value was set, false otherwise.

Parameters

NameTypeDescription
distribution_iduint32_tThe distribution ID to use.
doObstructionDetection()returns bool

Reads 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 bool

Turns obstruction detection on or off.

Returnstrue when the setting was changed, false otherwise.

Parameters

NameTypeDescription
do_obstruction_detectionbooltrue to turn obstruction detection on, false to turn it off.
doVibrationFiltering()returns bool

Reads 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 bool

Turns vibration filtering on or off.

Returnstrue when the setting was changed, false otherwise.

Parameters

NameTypeDescription
do_vibration_filteringbooltrue to turn vibration filtering on, false to turn it off.
measurementAlgorithm()returns uint8_t

Reads 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 bool

Selects 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

NameTypeDescription
measurement_algorithmuint8_tOne of E_BMV080_MEASUREMENT_ALGORITHM_FAST_RESPONSE, E_BMV080_MEASUREMENT_ALGORITHM_BALANCED or E_BMV080_MEASUREMENT_ALGORITHM_HIGH_PRECISION.
setMode(uint8_t mode)returns bool

Starts measuring in the mode you choose, with the settings made before it.

Returnstrue when the Bosch driver started the measurement, false otherwise.

Parameters

NameTypeDescription
modeuint8_tBMV080_MODE_CONTINUOUS for continuous measurement, as here, or BMV080_MODE_DUTY_CYCLE for duty cycling.
readSensor(bmv080_output_t *bmv080_output = nullptr)returns bool

Lets 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

NameTypeDescription
bmv080_outputbmv080_output_t *Optional. A Bosch output structure to copy the new reading into. The example leaves it out.
PM10()returns float

Returns the PM10 value of the latest reading: particles 10 µm across or smaller.

ReturnsPM10 mass concentration in µg/m³.

PM25()returns float

Returns the PM2.5 value of the latest reading: particles 2.5 µm across or smaller.

ReturnsPM2.5 mass concentration in µg/m³.

PM1()returns float

Returns the PM1 value of the latest reading: particles 1 µm across or smaller.

ReturnsPM1 mass concentration in µg/m³.

isObstructed()returns bool

Returns 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.