Calibrate the zero point
What this example shows
The electrochemical-calibrateSensor.py example applies a zero-point offset
and prints the gas concentration in PPB every 2.5 seconds.
The example creates the sensor with adc_addr=0x49 and config_pin=32.
CUSTOM_CALIBRATION is a voltage the module adds to the ADC voltage before it
converts it. The example's comment gives the method: in air with none of the
target gas, adjust the value until the reading is just barely 0 PPB.
Before you run it:
- The example is written with
SENSOR_O3, the module's ozone preset, so its values are not H2S values. Do not switch it toSENSOR_H2Sunchanged: that preset is written for the SGX-4H2S-100 cell (1200 nA per ppm). The datasheet of this board's SGX-4H2S-300 cell gives an output signal of 460 ± 140 nA per ppm, so with that preset the reading comes out about 2.6 times too low. Pass a customSensorConfigwith theSENSOR_H2Ssettings and 460 nA per ppm instead, as Quick Start shows. - Change
Pin(22)andPin(21)to your controller's SCL and SDA pins if they differ.
The example code
# FILE: electrochemical-calibrateSensor.py
from machine import I2C, Pin
import time
from ElectrochemicalGasSensor import ElectrochemicalGasSensor, SENSOR_O3
# This value is added to the voltage read from the ADC.
# In an environment with 0 of the target gas, the reading after calibration
# should be just barely 0 PPB — adjust this value until that is the case.
CUSTOM_CALIBRATION = 0
# Initialize I2C
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
# Custom ADC address (0x49 default) and GPIO pin for LMPEN
sensor = ElectrochemicalGasSensor(SENSOR_O3, i2c, adc_addr=0x49, config_pin=32)
# -------------------------------------------------------------------------
# Setup
# -------------------------------------------------------------------------
print("Electrochemical Gas Sensor - Calibration Example")
if not sensor.begin():
print("ERROR: Can't init the sensor! Check connections!")
while True:
time.sleep_ms(100)
# Apply the zero-point calibration offset
sensor.setCustomZeroCalibration(CUSTOM_CALIBRATION)
print("Sensor initialized successfully!")
# -------------------------------------------------------------------------
# Main loop
# -------------------------------------------------------------------------
while True:
reading = sensor.getPPB()
# O3 is typically measured in PPB
# Switch to getPPM() if PPM is more relevant for your use case
print("Sensor reading: {:.5f} PPB".format(reading))
time.sleep_ms(2500)
Expected result:
Electrochemical Gas Sensor - Calibration Example
Sensor initialized successfully!
Then a line starting with Sensor reading: follows every 2.5 seconds, with the
concentration in PPB to five decimals. The module never reports a value below
zero: it returns 0 instead, so 0.00000 is a normal reading. If the board
does not answer, the script prints
ERROR: Can't init the sensor! Check connections! and waits.
Functions used
ElectrochemicalGasSensor(sensor_type, i2c=None, adc_addr=0x49, config_pin=None)returns ElectrochemicalGasSensorCreates the sensor object. The sensor type holds the front-end and conversion settings for one gas cell. 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. A config_pin, when given, is set as an output and driven high.
ReturnsThe sensor object.
Parameters
| Name | Type | Description |
|---|---|---|
sensor_type | SensorConfig | Preset from the module (SENSOR_CO, SENSOR_NO2, SENSOR_SO2, SENSOR_O3, SENSOR_NO, SENSOR_H2S, SENSOR_NH3, SENSOR_CL2) or a custom SensorConfig. For this board's cell, pass a custom one with 460 nA per ppm. |
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 passes 0x49. |
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 passes 32. |
begin()returns boolWith an address from 0x30 to 0x37, checks that the board's ATtiny404 answers, sends it the ADC gain from the sensor type and the slowest data rate, then has it configure 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 configures the LMP91000 directly, pulling config_pin low during the writes. Call it once before reading.
ReturnsTrue when every step succeeded, False otherwise.
setCustomZeroCalibration(calibration)returns NoneSets the zero-point offset: a voltage that getPPM() adds to the ADC voltage before converting it. It writes the value into the sensor type object, so it replaces that object's internal zero calibration.
ReturnsNothing.
Parameters
| Name | Type | Description |
|---|---|---|
calibration | float | Offset in volts. The example passes CUSTOM_CALIBRATION. |
getPPB()returns floatTakes a reading with getPPM() and multiplies it by 1000.
ReturnsGas concentration in PPB.
getPPM()returns floatThe alternative the example's comment names. Takes an ADC reading, subtracts the front end's internal zero (2.5 V times its percentage), adds the zero calibration, then divides by the amplifier gain and by the cell sensitivity in nA per ppm from the sensor type. A result below 0 is returned as 0.0.
ReturnsGas concentration in PPM.
This example also uses I2C and Pin from MicroPython's
machine module,
which is not part of the Soldered ElectrochemicalGasSensor module.
Putting it together
Create the sensor, call begin(), then call
setCustomZeroCalibration() with your offset before you take readings. Run the
script in clean air, change CUSTOM_CALIBRATION, and run it again until the
reading is just barely 0 PPB.