Custom configuration
What this example shows
The module's electrochemical-customConfig.py example builds its own
SensorConfig: the cell's sensitivity, the zero offset, the ADC range and every
LMP91000 setting. begin() then sends that configuration to the board instead
of a built-in preset.
The values in the example are not this board's. To tune this board's cell,
start from the module's SENSOR_CL2 preset and change one value at a time.
Import the constants you use, as the example does: the gain from ads1115, the
rest from ElectrochemicalGasSensor.
| Argument | SENSOR_CL2 value |
|---|---|
nano_amperes_per_ppm | 600.0 |
internal_zero_calibration | 0 |
ads_gain | ADS_GAIN_4_096V |
tia_gain | TIA_GAIN_120_KOHM |
rload | RLOAD_33_OHM |
ref_source | REF_EXTERNAL |
internal_zero | INTERNAL_ZERO_20_PERCENT |
bias_sign | BIAS_SIGN_POSITIVE |
bias | BIAS_0_PERCENT |
fet_short | FET_SHORT_DISABLED |
op_mode | OP_MODE_3LEAD_AMP_CELL |
Keep ref_source at REF_EXTERNAL: the board has a 2.5 V reference for the
front end, and the module calculates ppm with 2.5 V.
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-customConfig.py
# AUTHOR: Fran Fodor @ Soldered
# BRIEF: Custom LMP91000 configuration example for any electrochemical sensor.
# LAST UPDATED: 2026-05-21
# Connecting diagram:
#
# Qwiic------------------------>Qwiic
# LMPEN------------------------>GPIO pin (see config_pin parameter below)
from machine import I2C, Pin
import time
from ElectrochemicalGasSensor import (
ElectrochemicalGasSensor, SensorConfig,
TIA_GAIN_35_KOHM, RLOAD_10_OHM, REF_EXTERNAL,
INTERNAL_ZERO_67_PERCENT, BIAS_SIGN_NEGATIVE, BIAS_0_PERCENT,
FET_SHORT_DISABLED, OP_MODE_3LEAD_AMP_CELL,
)
from ads1115 import ADS_GAIN_2_048V
# Custom sensor configuration — edit these values to match your sensor's datasheet.
#
# nanoAmperesPerPPM: Sensitivity from the sensor datasheet (nA/PPM)
# internalZeroCalibration: Voltage offset added to zero the reading in clean air
# adsGain: ADS1115 full-scale range (ADS_GAIN_6_144V .. ADS_GAIN_0_256V)
# tia_gain: TIA feedback resistor (TIA_GAIN_2_75_KOHM .. TIA_GAIN_350_KOHM)
# rload: Load resistor (RLOAD_10_OHM .. RLOAD_100_OHM)
# ref_source: Reference voltage source (REF_INTERNAL / REF_EXTERNAL)
# internal_zero: Internal zero percentage (INTERNAL_ZERO_20/50/67_PERCENT or _BYPASSED)
# bias_sign: Bias polarity (BIAS_SIGN_NEGATIVE / BIAS_SIGN_POSITIVE)
# bias: Bias percentage of Vref (BIAS_0_PERCENT .. BIAS_24_PERCENT)
# fet_short: FET short (FET_SHORT_DISABLED / FET_SHORT_ENABLED)
# op_mode: Operating mode (OP_MODE_3LEAD_AMP_CELL for normal operation)
SENSOR_CUSTOM = SensorConfig(
nano_amperes_per_ppm=-1000.0,
internal_zero_calibration=-0.0012,
ads_gain=ADS_GAIN_2_048V,
tia_gain=TIA_GAIN_35_KOHM,
rload=RLOAD_10_OHM,
ref_source=REF_EXTERNAL,
internal_zero=INTERNAL_ZERO_67_PERCENT,
bias_sign=BIAS_SIGN_NEGATIVE,
bias=BIAS_0_PERCENT,
fet_short=FET_SHORT_DISABLED,
op_mode=OP_MODE_3LEAD_AMP_CELL,
)
# Initialize I2C
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
sensor = ElectrochemicalGasSensor(SENSOR_CUSTOM, i2c)
# -------------------------------------------------------------------------
# Setup
# -------------------------------------------------------------------------
print("Electrochemical Gas Sensor - Custom Config 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:
reading = sensor.getPPB()
print("Sensor reading: {:.5f} PPB".format(reading))
time.sleep_ms(2500)
🔗Open the complete example
Examples/electrochemical-customConfig.py at commit 623e1e6
The connecting diagram in the example wires LMPEN to 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 - Custom Config Example
Sensor initialized successfully!
Then a line every 2.5 s: Sensor reading: , the concentration in ppb with five
decimals, and PPB. If begin() fails, the script prints
ERROR: Can't init the sensor! Check connections! and stops.
Functions used
SensorConfig(nano_amperes_per_ppm, internal_zero_calibration, ads_gain, tia_gain, rload, ref_source, internal_zero, bias_sign, bias, fet_short, op_mode)returns SensorConfigHolds one cell's configuration. The built-in presets, SENSOR_CL2 among them, are SensorConfig objects too.
ReturnsThe configuration object, passed to ElectrochemicalGasSensor().
Parameters
| Type | Name | Description |
|---|---|---|
float | nano_amperes_per_ppm | The cell's sensitivity in nA per ppm, used in the ppm calculation. |
float | internal_zero_calibration | Voltage offset added to every reading. |
int | ads_gain | ADS1115 full-scale range, ADS_GAIN_6_144V to ADS_GAIN_0_256V. |
int | tia_gain | LMP91000 amplifier gain, TIA_GAIN_EXTERNAL or TIA_GAIN_2_75_KOHM to TIA_GAIN_350_KOHM. |
int | rload | Load resistor, RLOAD_10_OHM, RLOAD_33_OHM, RLOAD_50_OHM or RLOAD_100_OHM. |
int | ref_source | REF_INTERNAL or REF_EXTERNAL. |
int | internal_zero | INTERNAL_ZERO_20_PERCENT, _50_PERCENT, _67_PERCENT or INTERNAL_ZERO_BYPASSED. |
int | bias_sign | BIAS_SIGN_NEGATIVE or BIAS_SIGN_POSITIVE. |
int | bias | Bias as a share of the reference, BIAS_0_PERCENT to BIAS_24_PERCENT. |
int | fet_short | FET_SHORT_DISABLED or FET_SHORT_ENABLED. |
int | op_mode | Operating mode, OP_MODE_3LEAD_AMP_CELL for normal measurement. |
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 configuration, here the example's SENSOR_CUSTOM. |
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 configuration's ADC gain and data rate, and writes its amplifier gain and load, reference, internal zero, bias and operating mode to the LMP91000. Call it once before reading.
ReturnsTrue when the board answered and both configuration steps succeeded, False otherwise.
sensor.getPPB()returns floatTakes one reading and converts it to ppb with the configuration's values: getPPM() times 1000. A result below zero is returned as 0.0.
ReturnsThe gas concentration in ppb.
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
begin() writes the LMP91000 and ADC settings to the board, and getPPB() uses
nano_amperes_per_ppm, internal_zero_calibration, the amplifier gain and the
internal zero in its calculation. Run the script again after each change.