Use a custom sensor configuration
What this example shows
The customConfig example builds its own sensorType, SENSOR_CUSTOM,
instead of using one of the library's presets, creates the sensor with it at the
library's default address, 0x49, and prints the gas concentration in PPM
every 2.5 seconds.
This is how you give the library this board's cell. As written,
SENSOR_CUSTOM holds an example sensitivity of 100 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 library's SENSOR_H2S preset, with the output signal the SGX-4H2S-300'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:
| Field | Value for this board |
|---|---|
nanoAmperesPerPPM | 460.0F |
internalZeroCalibration | 0 |
adsGain | ADS_GAIN_4_096V |
TIA_GAIN_IN_KOHMS | 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 |
The example code
// Include the required library
#include "Electrochemical-Gas-Sensor-SOLDERED.h"
/**
* Here are parameters to configure for the custom sensor:
*
* nanoAmperesPerPPM: From the datasheet of the particular electrochemical
* sensor, used in the calculation of PPM/PPB
*
* internalZeroCalibration: A fixed value which is summed to the voltage
* measured by the ADS. The value here should make the reading be
* just barely 0 PPM when the sensor is in a place with none of the target gas
*
* adsGain: The gain of the ADS
* The voltage here represents the max range which it can measure
* ADS_GAIN_6_144V 6.144 V
* ADS_GAIN_4_096V 4.096 V
* ADS_GAIN_2_048V 2.048 V
* ADS_GAIN_1_024V 1.024 V
* ADS_GAIN_0_512V 0.512 V
* ADS_GAIN_0_256V 0.256 V
*
* TIA_GAIN_IN_KOHMS: The gain of the amplifier
* This increases the sensitivity of the measurement
* TIA_GAIN_EXTERNAL External resistance
* TIA_GAIN_2_75_KOHM 2.75 kOhm
* TIA_GAIN_3_5_KOHM 3.5 kOhm
* TIA_GAIN_7_KOHM 7 kOhm
* TIA_GAIN_14_KOHM 14 kOhm
* TIA_GAIN_35_KOHM 35 kOhm
* TIA_GAIN_120_KOHM 120 kOhm
* TIA_GAIN_350_KOHM 350 kOhm
*
* RLOAD: The load resistor in the LMP91000
* Specified in the electrochemical sensor's datasheet
* RLOAD_10_OHM 10 Ohm
* RLOAD_33_OHM 33 Ohm
* RLOAD_50_OHM 50 Ohm
* RLOAD_100_OHM 100 Ohm
*
* REF_SOURCE: Source of the control voltage reference
* For our breakout, use external, there's a 2.5V external
* reference voltage
* REF_INTERNAL Internal
* REF_EXTERNAL External
*
* INTERNAL_ZERO: Internal zero selection
* If the electrochemical sensor has a positive polarity, you
* would usually want to use 20% for the most headroom in the signal
* INTERNAL_ZERO_20_PERCENT 20%
* INTERNAL_ZERO_50_PERCENT 50%
* INTERNAL_ZERO_67_PERCENT 67%
* INTERNAL_ZERO_BYPASSED Internal zero bypassed
*
* BIAS_SIGN: The polarity of the bias voltage
* BIAS_SIGN_NEGATIVE Negative
* BIAS_SIGN_POSITIVE Positive
*
* BIAS: Added bias, percentage of the reference voltage
* Most sensors don't require this, check each sensor's datasheet
* BIAS_0_PERCENT 0%
* BIAS_1_PERCENT 1%
* BIAS_2_PERCENT 2%
* BIAS_4_PERCENT 4%
* BIAS_6_PERCENT 6%
* ...
* BIAS_22_PERCENT 22%
* BIAS_24_PERCENT 24%
*
* FET_SHORT: Short the FET
* Used to perserve the electrochemical sensor
* Has to be disabled for the sensor to be operable
* FET_SHORT_DISABLED Disabled
* FET_SHORT_ENABLED Enabled
*
* OP_MODE: Mode of operation
* OP_MODE_DEEP_SLEEP Deep Sleep (default)
* OP_MODE_2LEAD_GROUND_CELL 2-lead ground referred galvanic cell
* OP_MODE_STANDBY Standby
* OP_MODE_3LEAD_AMP_CELL 3-lead amperometric cell
* OP_MODE_TEMPERATURE_TIA_OFF Temperature measurement (TIA Off)
* OP_MODE_TEMPERATURE_TIA_ON Temperature measurement (TIA On)
*
* For more details, check thge LMP91000 datasheet, chapter 7.6
*/
// Here is an example of a custom configuration:
const sensorType SENSOR_CUSTOM = {
100.0F, // nanoAmperesPerPPM
0, // internalZeroCalibration
ADS_GAIN_4_096V, // adsGain
TIA_GAIN_120_KOHM, // TIA_GAIN_IN_KOHMS
RLOAD_10_OHM, // RLOAD
REF_EXTERNAL, // REF_SOURCE
INTERNAL_ZERO_20_PERCENT, // INTERNAL_ZERO
BIAS_SIGN_NEGATIVE, // BIAS_SIGN
BIAS_0_PERCENT, // BIAS
FET_SHORT_DISABLED, // FET_SHORT
OP_MODE_3LEAD_AMP_CELL, // OP_MODE
};
// Create the sensor object with the custom type
ElectrochemicalGasSensor sensor(SENSOR_CUSTOM);
void setup()
{
Serial.begin(115200); // For debugging
// Init the breakout
if (!sensor.begin())
{
// Can't init? Notify the user and go to infinite loop
Serial.println("ERROR: Can't init the sensor! Check connections!");
while (true)
delay(100);
}
Serial.println("Sensor initialized successfully!");
}
void loop()
{
// Make the reading
double reading = sensor.getPPM();
// Print the reading with 5 digits of precision
Serial.println("Sensor reading: ");
Serial.print(reading, 5);
Serial.println(" PPM");
// Wait a bit before reading again
delay(2500);
}
Expected result:
Sensor initialized successfully!
Then, every 2.5 seconds, the sketch prints Sensor reading: on one line and
the concentration in PPM to five decimals, followed by PPM, on the next. If
the sensor does not answer, the sketch prints
ERROR: Can't init the sensor! Check connections! and stops.
Functions used
sensorType is the structure that holds one cell's settings, in this order:
| Field | Type | Meaning |
|---|---|---|
nanoAmperesPerPPM | double | The cell's sensitivity in nA per ppm. getPPM() divides by it. |
internalZeroCalibration | double | Voltage added to the reading before conversion, to zero it with none of the target gas. |
adsGain | uint8_t | ADC full-scale range, ADS_GAIN_6_144V to ADS_GAIN_0_256V. |
TIA_GAIN_IN_KOHMS | uint8_t | Front-end amplifier gain, TIA_GAIN_2_75_KOHM to TIA_GAIN_350_KOHM, or TIA_GAIN_EXTERNAL. |
RLOAD | uint8_t | Load resistor, RLOAD_10_OHM to RLOAD_100_OHM. |
REF_SOURCE | uint8_t | Reference source, REF_INTERNAL or REF_EXTERNAL. |
INTERNAL_ZERO | uint8_t | Internal zero, INTERNAL_ZERO_20_PERCENT, INTERNAL_ZERO_50_PERCENT, INTERNAL_ZERO_67_PERCENT or INTERNAL_ZERO_BYPASSED. |
BIAS_SIGN | uint8_t | Bias polarity, BIAS_SIGN_NEGATIVE or BIAS_SIGN_POSITIVE. |
BIAS | uint8_t | Bias as a percentage of the reference, BIAS_0_PERCENT to BIAS_24_PERCENT. |
FET_SHORT | uint8_t | FET_SHORT_DISABLED or FET_SHORT_ENABLED. |
OP_MODE | uint8_t | Operating mode; the presets use OP_MODE_3LEAD_AMP_CELL. |
ElectrochemicalGasSensor(sensorType _t, uint8_t _adcAddr = DEFAULT_ADC_ADDR, int _configPin = -1)returns noneCreates 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.
ReturnsConstructor.
Parameters
| Name | Type | Description |
|---|---|---|
_t | sensorType | The configuration to use. This example passes SENSOR_CUSTOM. |
_adcAddr | uint8_t | The address begin() talks to. This example leaves it out, so the default, 0x49 (DEFAULT_ADC_ADDR), is used. |
_configPin | int | A GPIO the library holds high and pulls low while it configures the LMP91000 directly. Ignored at addresses from 0x30 to 0x37. This example leaves it out (-1, none). |
bool begin()returns boolStarts I2C and picks how to talk to the board from the address. With an address from 0x30 to 0x37 it checks that the board's ATtiny404 answers and sends it the ADC gain from the configuration with the slowest data rate; each command waits up to 500 ms for an answer. With any other address it starts an ADS1115 at that address with the same gain and data rate. Either way it then writes the configuration to the LMP91000 front end. Call it once before reading.
Returnstrue when every step succeeded, false otherwise.
double getPPM()returns doubleReads the ADC, 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 configuration's sensitivity in nA per ppm. A result below 0 is returned as 0.
ReturnsGas concentration in PPM.
Putting it together
Fill in a const sensorType with your cell's values, pass it to
ElectrochemicalGasSensor, call begin() once, then read with getPPM(). For
this board, the first table gives the values.