Arduino library for the AGS3871 - CarbonMonoxide CO sensor.
Experimental
This library is experimental, so please use with care.
The library is based upon the limited datasheet and the code of the AGS02MA sensor, which uses a very similar protocol.
The AGS3871 is a CarbonMonoxide or CO sensor which has a working range of 50-1000 PPM. The sensor needs a warm up time of 2 minutes before readings are stabilized. Readings during warm up must be considered with care. The time between reads should be at least 2 seconds.
function | value | notes |
---|---|---|
CO range | 50 - 1000 PPM | |
read freq | once per 2 sec | |
warm up | 120 sec | |
current | 20-30 mA | prefers own power supply. |
Warning: This library is very limited tested with hardware. So use with care.
Feedback as always, is welcome. Please open an issue.
Warning: This library is not meant to replace professional monitoring systems.
- https://github.com/RobTillaart/AGS02MA TVOC sensor
- https://github.com/RobTillaart/AGS3871 CO sensor
- https://www.renesas.com/us/en/document/whp/overview-tvoc-and-indoor-air-quality
Front L->R | Description |
---|---|
pin 1 | VDD +5V |
pin 2 | SDA data |
pin 3 | GND |
pin 4 | SCL clock |
The device has a fixed address of 26 or 0x1A.
The device works at 100 kHz I2C bus speed (datasheet).
Sometimes you need to control more devices than possible with the default address range the device provides. This is possible with an I2C multiplexer e.g. TCA9548 which creates up to eight channels (think of it as I2C subnets) which can use the complete address range of the device.
Drawback of using a multiplexer is that it takes more administration in your code e.g. which device is on which channel. This will slow down the access, which must be taken into account when deciding which devices are on which channel. Also note that switching between channels will slow down other devices too if they are behind the multiplexer.
If you have a AGS3871 device, please let me know your experiences with the sensor and this (or other) library.
#include "AGS3871.h"
- AGS3871(TwoWire *wire = &Wire) constructor, with default I2C interface.
- bool begin() initialize the library.
- bool isConnected() returns true if device address can be seen on I2C.
- void reset() reset internal variables.
- bool isHeated() returns true if 120 seconds have passed after startup (call of begin() ). Otherwise the device is not optimal ready.
According to the datasheet the preheating will improve the quality of the measurements. If heating is ongoing the dataReady() returns 1
- uint8_t getAddress() returns the fixed address, 26 or 0x1A.
- uint8_t getVersion() reads sensor version from device. If the version cannot be read the function will return 255.
- uint32_t readPPM() reads PPM (parts per million 10^6) from device. Typical value should be between 1 .. 1000. Returns lastPPM() value if failed so one does not get sudden jumps in graphs. Check lastStatus() and lastError() to get more info about success.
- uint32_t lastPPM() returns last readPPM (parts per million) value (cached).
- uint32_t lastRead() timestamp of last time the device is read, timestamp is in milliseconds since start. Returns 0 if readPPM() is not called yet.
- uint8_t lastStatus() returns status byte.
- bool dataReady() returns true if data has been updated. Returns false if not updated or heating in progress.
- int lastError() returns last error.
NOT TESTED YET, use with care, feedback welcome
Calibration functions should be called after at least 5 minutes in fresh air. See example sketch.
- bool zeroCalibration() wrapper, for fast zero calibration.
- bool manualZeroCalibration(uint16_t value = 0) Set the zero calibration value manually. See table below.
- bool getZeroCalibrationData(ZeroCalibrationData &data) fills a data struct with the current zero calibration status and value. Returns true on success.
- uint32_t readResistance() returns internal R of sensor. To be used for calibration. (Alt-234 = Ω)
value | meaning |
---|---|
0xFFFF | Factory reset |
0x0000 | set current resistance as zero |
other | set value as zero |
- bool readRegister(uint8_t address, RegisterData ®) fills a data struct
with the sensors register data at that address.
Primarily intended for troubleshooting and analysis of the sensor.
Not recommended to build applications on top of this method's raw data.
Returns true if the RegisterData is filled, false if data could not be read.
Note: unlike other public methods, CRC errors don't return false or show up in
lastError()
, instead the CRC result is stored inRegisterData.crcValid
.
bit | description | notes |
---|---|---|
7-1 | reserved | |
0 | RDY bit 0 = ready 1 = not ready | 1 == busy |
ERROR_CODES | value |
---|---|
AGS3871_OK | 0 |
AGS3871_ERROR | -10 |
AGS3871_ERROR_CRC | -11 |
AGS3871_ERROR_READ | -12 |
AGS3871_ERROR_NOT_READY | -13 |
- improve documentation
- references?
- test with hardware
- investigate and test calibration
- test with different processors
- elaborate error handling.
- move code to .cpp?
- investigate other registers
- check MAGIC numbers.
- examples
- use dataReady() to optimize number of reads.
If you appreciate my libraries, you can support the development and maintenance. Improve the quality of the libraries by providing issues and Pull Requests, or donate through PayPal or GitHub sponsors.
Thank you,