Averaged measurement
What this example shows
The module's electrochemical-averagedMeasurement.py example takes five
readings three seconds apart, averages them with one function call, and prints
the result in ppb.
The example creates the sensor with SENSOR_O3, the preset for the ozone cell.
The module calculates each reading from the preset's sensitivity and gain
settings; the preset for this board's chlorine cell is SENSOR_CL2.
The example opens I2C bus 0 with SCL on pin 22 and SDA on pin 21. Change
them to match your board.
The example code
# FILE: electrochemical-averagedMeasurement.py
# AUTHOR: Fran Fodor @ Soldered
# BRIEF: Averaged PPM reading example using the built-in averaging function.
# LAST UPDATED: 2026-05-21
# Connecting diagram:
#
# Qwiic------------------------>Qwiic
# LMPEN------------------------>GND or GPIO pin (see config_pin parameter below)
from machine import I2C, Pin
import time
from ElectrochemicalGasSensor import ElectrochemicalGasSensor, SENSOR_O3
# How many readings to average and how many seconds to wait between them
NUM_READINGS = 5
SECS_BETWEEN_READINGS = 3
# Initialize I2C
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
# Create sensor object - change SENSOR_O3 to match your sensor type
# Available types: SENSOR_CO, SENSOR_NO2, SENSOR_SO2, SENSOR_O3,
# SENSOR_NO, SENSOR_H2S, SENSOR_NH3, SENSOR_CL2
sensor = ElectrochemicalGasSensor(SENSOR_O3, i2c)
# -------------------------------------------------------------------------
# Setup
# -------------------------------------------------------------------------
print("Electrochemical Gas Sensor - Averaged Measurement Example")
if not sensor.begin():
print("ERROR: Can't init the sensor! Check connections!")
while True:
time.sleep_ms(100)
print("Sensor initialized successfully!")
# -------------------------------------------------------------------------
# Main loop
# -------------------------------------------------------------------------
while True:
# getAveragedPPM is a blocking call — it waits between each reading
reading = sensor.getAveragedPPB(NUM_READINGS, SECS_BETWEEN_READINGS)
# If PPM is more relevant for your sensor, use:
# reading = sensor.getAveragedPPM(NUM_READINGS, SECS_BETWEEN_READINGS)
print("Sensor reading: {:.5f} PPB".format(reading))
time.sleep_ms(2500)
🔗Open the complete example
Examples/electrochemical-averagedMeasurement.py at commit 623e1e6
The connecting diagram in the example wires LMPEN to GND or a GPIO. On this
board a 10 kΩ resistor holds LMPEN low and it is wired to the ATtiny404, so
you leave it unconnected (see the pin table on
Hardware details).
Expected result:
Electrochemical Gas Sensor - Averaged Measurement Example
Sensor initialized successfully!
Each average takes five readings with a 3 s wait after each, so the first
Sensor reading: line (the average in ppb with five decimals, then PPB)
comes about 15 s later, and the next ones about every 17.5 s, counting the
2.5 s pause at the end of the loop. If begin() fails, the script prints
ERROR: Can't init the sensor! Check connections! and stops.
Functions used
ElectrochemicalGasSensor(sensor_type, i2c=None, adc_addr=0x49, config_pin=None)returns ElectrochemicalGasSensorCreates the sensor object. Nothing is sent to the board until begin().
ReturnsThe sensor object.
Parameters
| Type | Name | Description |
|---|---|---|
SensorConfig | sensor_type | The cell preset. The example passes SENSOR_O3; this board's SGX-4CL2 cell has the preset SENSOR_CL2. |
I2C | i2c | A ready machine.I2C object; the example passes one. When left out, the module creates I2C(0, scl=Pin(22), sda=Pin(21)) on the esp32 port and on the one other board it recognises by its name (pins 22 and 21 there too); on esp8266, I2C(scl=Pin(5), sda=Pin(4)); on any other board it raises Board not recognized, please pass an I2C object manually. |
int | adc_addr | The I2C address, 0x49 when left out, as in the example. For an address from 0x30 to 0x37, the range of this board's ADDRESS switch, begin() talks to the board's ATtiny404; for any other address it looks for an ADS1115 at that address and the LMP91000 at 0x48 on the bus you pass. |
int | config_pin | A GPIO for the LMP91000's MENB input: the module drives it low while it configures the LMP91000 directly, and high otherwise. None when left out, as in the example. Unused for addresses 0x30 to 0x37. |
sensor.begin()returns boolChecks that the board answers, sets the preset's ADC gain and data rate, and configures the LMP91000 with the preset's settings. Call it once before reading.
ReturnsTrue when the board answered and both configuration steps succeeded, False otherwise.
sensor.getAveragedPPB(num_measurements=5, seconds_delay=2)returns floatgetAveragedPPM() times 1000. It blocks until all readings are done.
ReturnsThe averaged gas concentration in ppb.
Parameters
| Type | Name | Description |
|---|---|---|
int | num_measurements | How many readings to average. 5 by default; the example passes NUM_READINGS (5). |
int | seconds_delay | Seconds to wait after each reading. 2 by default; the example passes SECS_BETWEEN_READINGS (3). |
sensor.getAveragedPPM(num_measurements=5, seconds_delay=2)returns floatTakes num_measurements readings with getPPM(), sleeping seconds_delay seconds after each one, and returns their mean. The example shows it in a comment as the alternative.
ReturnsThe averaged gas concentration in ppm.
Parameters
| Type | Name | Description |
|---|---|---|
int | num_measurements | How many readings to average. 5 by default. |
int | seconds_delay | Seconds to wait after each reading. 2 by default. |
This example also uses
I2C and
Pin from
MicroPython's machine module and
time.sleep_ms(),
which are not part of this library and come with MicroPython itself.
Putting it together
Change NUM_READINGS and SECS_BETWEEN_READINGS to trade response time for a
steadier value. While the average runs, the rest of the loop waits.