Use a custom sensor configuration
What this example shows
The electrochemical-customConfig.py example builds its own SensorConfig,
SENSOR_CUSTOM, instead of using one of the module's presets, and prints the
gas concentration in PPB every 2.5 seconds.
The example creates the sensor at the module's default address, 0x49.
This is how you give the module this board's cell. As written, SENSOR_CUSTOM
holds example values, such as a sensitivity of -1000 nA per ppm, so its readings
are not H2S values. For this board's SGX-4H2S-300 cell, set the values to those of the
module's SENSOR_H2S preset, with the output signal the cell's
datasheet
gives, 460 nA per ppm (460 ± 140), in place of the preset's 1200. The preset is
written for the SGX-4H2S-100 cell, and with this board's cell it reads about
2.6 times too low:
| Argument | Value for this board |
|---|---|
nano_amperes_per_ppm | 460.0 |
internal_zero_calibration | 0 |
ads_gain | ADS_GAIN_4_096V |
tia_gain | TIA_GAIN_7_KOHM |
rload | RLOAD_10_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 |
Import each constant you use: ADS_GAIN_4_096V from ads1115, the others from
ElectrochemicalGasSensor, as
Quick Start
shows. Change Pin(22) and Pin(21) to your controller's SCL and SDA pins if
they differ.
The example code
# FILE: electrochemical-customConfig.py
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)
Expected result:
Electrochemical Gas Sensor - Custom Config Example
Sensor initialized successfully!
Then a line starting with Sensor reading: follows every 2.5 seconds, with the
concentration in PPB to five decimals. If the board does not answer, the script
prints ERROR: Can't init the sensor! Check connections! and waits.
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 the settings for one gas cell: the values getPPM() converts with and the values begin() writes to the LMP91000 front end. The module's presets, such as SENSOR_H2S, are SensorConfig objects too.
ReturnsThe configuration object to pass to ElectrochemicalGasSensor.
Parameters
| Name | Type | Description |
|---|---|---|
nano_amperes_per_ppm | float | The cell's sensitivity in nA per ppm, from its datasheet. getPPM() divides by it. |
internal_zero_calibration | float | Voltage added to the reading to zero it in clean air. |
ads_gain | int | ADS1115 full-scale range, ADS_GAIN_6_144V to ADS_GAIN_0_256V (from ads1115). |
tia_gain | int | Front-end amplifier gain, TIA_GAIN_2_75_KOHM to TIA_GAIN_350_KOHM, or TIA_GAIN_EXTERNAL. |
rload | int | Load resistor, RLOAD_10_OHM to RLOAD_100_OHM. |
ref_source | int | Reference source, REF_INTERNAL or REF_EXTERNAL. |
internal_zero | int | Internal zero, INTERNAL_ZERO_20_PERCENT, INTERNAL_ZERO_50_PERCENT, INTERNAL_ZERO_67_PERCENT or INTERNAL_ZERO_BYPASSED. |
bias_sign | int | Bias polarity, BIAS_SIGN_NEGATIVE or BIAS_SIGN_POSITIVE. |
bias | int | Bias as a percentage of the reference, BIAS_0_PERCENT to BIAS_24_PERCENT. |
fet_short | int | FET_SHORT_DISABLED or FET_SHORT_ENABLED. |
op_mode | int | Operating mode; OP_MODE_3LEAD_AMP_CELL for normal operation. |
ElectrochemicalGasSensor(sensor_type, i2c=None, adc_addr=0x49, config_pin=None)returns ElectrochemicalGasSensorCreates the sensor object. The address decides how begin() talks to the board: an address from 0x30 to 0x37 goes through the board's ATtiny404; any other address, such as the default 0x49, goes to an ADS1115 at that address and to the LMP91000 directly.
ReturnsThe sensor object.
Parameters
| Name | Type | Description |
|---|---|---|
sensor_type | SensorConfig | The configuration to use. This example passes SENSOR_CUSTOM. |
i2c | machine.I2C | The I2C bus the board is on. Without it, the module opens one itself only on the boards it recognises: ESP32 builds of MicroPython and one Soldered board's own build (I2C bus 0, SCL 22, SDA 21), and ESP8266 builds (SCL 5, SDA 4). On any other board it raises Board not recognized, please pass an I2C object manually. |
adc_addr | int | The address begin() talks to. This example leaves it out, so the default, 0x49, is used. |
config_pin | int | A GPIO the module holds high and pulls low while it configures the LMP91000 directly. Unused at addresses from 0x30 to 0x37. This example leaves it out. |
begin()returns boolWith an address from 0x30 to 0x37, checks that the board's ATtiny404 answers, sends it the ADC gain from the configuration and the slowest data rate, then has it write the configuration to the LMP91000 front end; each command is retried for up to 500 ms. With any other address, checks that an ADS1115 answers at that address, sets its gain and the slowest data rate, then writes the configuration to the LMP91000 directly. Call it once before reading.
ReturnsTrue when every step succeeded, False otherwise.
getPPB()returns floatTakes a reading with getPPM(), which converts with the configuration's sensitivity, and multiplies it by 1000.
ReturnsGas concentration in PPB.
This example also uses I2C and Pin from MicroPython's
machine module,
which is not part of the Soldered ElectrochemicalGasSensor module.
Putting it together
Build a SensorConfig from your cell's datasheet, pass it to
ElectrochemicalGasSensor, call begin() once, then read with getPPB() or
getPPM(). For this board, the table above gives the values.