AGS10 TVOC Gas Sensor
The AGS10 is a digital TVOC gas sensor for measuring the total amount of volatile organic compounds (TVOCs) in the air. It is suitable for applications such as indoor air quality monitoring, smart home systems, and IoT projects.
Overview
- Measured quantity: TVOC (Total Volatile Organic Compounds)
- Interface: I²C
- Supply voltage: 3.3 – 5.0 V
- Logic level (I²C): compatible with 3.3 V and 5 V
- I²C pull-ups: available on the breakout board
- Output: TVOC value in ppb
- Warm-up time: approx. 2–3 minutes
Typical Applications
- Indoor air quality measurement
- Smart home & building automation
- Air monitoring in offices & workshops
- Maker & IoT projects
Technical Data
| Parameter | Value |
|---|---|
| Measurement range | 0 – 1000 ppb TVOC |
| Resolution | 1 ppb |
| Interface | I²C |
| I²C address | 0x1A (default) |
| Supply voltage | 3.3 – 5.0 V |
| Logic level | 3.3 V / 5 V tolerant |
| Current consumption | typically approx. 30 mA |
| Operating temperature | -10 °C to +50 °C |
Pinout & Connections
| Pin | Name | Description |
|---|---|---|
| VCC | Supply | 3.3 – 5.0 V |
| GND | Ground | Ground |
| SDA | I²C Data | I²C data line |
| SCL | I²C Clock | I²C clock line |
Note:
The I²C pull-up resistors are already integrated on the breakout board used.
Therefore, the sensor can be connected directly to 3.3 V or 5 V I²C buses.
Electrical Characteristics
- Operation with 3.3 V or 5 V supply voltage
- I²C logic levels compatible with 3.3 V and 5 V
- Internal level adaptation via the breakout board
- Stable quiescent current after warm-up phase
Communication (I²C)
- Bus: I²C
- Address:
0x1A - Pull-ups: available on the board
- Data format: 16-bit TVOC value (ppb)
Reading a measurement (simplified)
- Start condition
- I²C address + read
- Receive 2 bytes
- Calculate TVOC value
Example Code
Arduino (I²C)
## Beispielcode (Arduino)
#include <Wire.h>
#define AGS10_ADDR 0x1A
#define REG_DATA_ACQ 0x00
#define REG_READ_VERSION 0x11
#define REG_READ_RESISTANCE 0x20
#define CMD_DELAY_MS 30
#define READ_DELAY_MS 1500
uint8_t calcCRC8(const uint8_t *data, uint8_t len) {
uint8_t crc = 0xFF;
for (uint8_t b = 0; b < len; b++) {
crc ^= data[b];
for (uint8_t i = 0; i < 8; i++)
crc = (crc & 0x80) ? (crc << 1) ^ 0x31 : (crc << 1);
}
return crc;
}
bool i2cRead5(uint8_t reg, uint8_t *out) {
Wire.beginTransmission(AGS10_ADDR);
Wire.write(reg);
if (Wire.endTransmission() != 0) return false;
delay(CMD_DELAY_MS);
if (Wire.requestFrom((int)AGS10_ADDR, 5) != 5) return false;
for (uint8_t i = 0; i < 5; i++) out[i] = Wire.read();
return (calcCRC8(out, 4) == out[4]);
}
bool readTVOC(uint32_t &tvoc, uint8_t &status) {
uint8_t buf[5];
if (!i2cRead5(REG_DATA_ACQ, buf)) return false;
status = buf[0];
tvoc = ((uint32_t)buf[1] << 16) | ((uint32_t)buf[2] << 8) | buf[3];
delay(READ_DELAY_MS);
return true;
}
bool readVersion(uint8_t &ver) {
uint8_t buf[5];
if (!i2cRead5(REG_READ_VERSION, buf)) return false;
ver = buf[3];
return true;
}
bool readResistance(uint32_t &res) {
uint8_t buf[5];
if (!i2cRead5(REG_READ_RESISTANCE, buf)) return false;
res = ((uint32_t)buf[1] << 16) | ((uint32_t)buf[2] << 8) | buf[3];
return true;
}
void setup() {
Serial.begin(115200);
Wire.begin();
Serial.println("Paradisetronic - AGS10 TVOC Sensor Test");
Serial.println("Bitte mindestens 2 Minuten Vorheizzeit beachten...");
delay(2000);
uint8_t fw;
if (readVersion(fw)) {
Serial.print("Firmware-Version: 0x");
Serial.println(fw, HEX);
}
uint32_t r;
if (readResistance(r)) {
Serial.print("Sensor-Widerstand: ");
Serial.print(r / 10.0, 1);
Serial.println(" kOhm");
}
Serial.println("Starte TVOC-Messung...");
}
void loop() {
uint32_t tvoc;
uint8_t status;
if (readTVOC(tvoc, status)) {
Serial.print("Status: 0x");
Serial.print(status, HEX);
Serial.print(" | TVOC: ");
Serial.print(tvoc);
Serial.println(" ppb");
} else {
Serial.println("Fehler beim Lesen der TVOC-Daten.");
}
delay(2000);
}
## Beispielcode (Arduino)
#include <Wire.h>
#define AGS10_ADDR 0x1A
#define REG_DATA_ACQ 0x00
#define REG_READ_VERSION 0x11
#define REG_READ_RESISTANCE 0x20
#define CMD_DELAY_MS 30
#define READ_DELAY_MS 1500
uint8_t calcCRC8(const uint8_t *data, uint8_t len) {
uint8_t crc = 0xFF;
for (uint8_t b = 0; b < len; b++) {
crc ^= data[b];
for (uint8_t i = 0; i < 8; i++)
crc = (crc & 0x80) ? (crc << 1) ^ 0x31 : (crc << 1);
}
return crc;
}
bool i2cRead5(uint8_t reg, uint8_t *out) {
Wire.beginTransmission(AGS10_ADDR);
Wire.write(reg);
if (Wire.endTransmission() != 0) return false;
delay(CMD_DELAY_MS);
if (Wire.requestFrom((int)AGS10_ADDR, 5) != 5) return false;
for (uint8_t i = 0; i < 5; i++) out[i] = Wire.read();
return (calcCRC8(out, 4) == out[4]);
}
bool readTVOC(uint32_t &tvoc, uint8_t &status) {
uint8_t buf[5];
if (!i2cRead5(REG_DATA_ACQ, buf)) return false;
status = buf[0];
tvoc = ((uint32_t)buf[1] << 16) | ((uint32_t)buf[2] << 8) | buf[3];
delay(READ_DELAY_MS);
return true;
}
bool readVersion(uint8_t &ver) {
uint8_t buf[5];
if (!i2cRead5(REG_READ_VERSION, buf)) return false;
ver = buf[3];
return true;
}
bool readResistance(uint32_t &res) {
uint8_t buf[5];
if (!i2cRead5(REG_READ_RESISTANCE, buf)) return false;
res = ((uint32_t)buf[1] << 16) | ((uint32_t)buf[2] << 8) | buf[3];
return true;
}
void setup() {
Serial.begin(115200);
Wire.begin();
Serial.println("Paradisetronic - AGS10 TVOC Sensor Test");
Serial.println("Bitte mindestens 2 Minuten Vorheizzeit beachten...");
delay(2000);
uint8_t fw;
if (readVersion(fw)) {
Serial.print("Firmware-Version: 0x");
Serial.println(fw, HEX);
}
uint32_t r;
if (readResistance(r)) {
Serial.print("Sensor-Widerstand: ");
Serial.print(r / 10.0, 1);
Serial.println(" kOhm");
}
Serial.println("Starte TVOC-Messung...");
}
void loop() {
uint32_t tvoc;
uint8_t status;
if (readTVOC(tvoc, status)) {
Serial.print("Status: 0x");
Serial.print(status, HEX);
Serial.print(" | TVOC: ");
Serial.print(tvoc);
Serial.println(" ppb");
} else {
Serial.println("Fehler beim Lesen der TVOC-Daten.");
}
delay(2000);
}
Calibration & Notes
- After power-up, a warm-up time of approximately 2–3 minutes is required before stable measurements are available.
- The TVOC measurement is relative and intended for trend and comparison analysis, not as a laboratory-grade reference.
- For meaningful results, the sensor should be initialized in clean reference air.
- Sudden changes in air composition (e.g. alcohol, cleaning agents, solvents) will cause significantly increased readings.
- The sensor is not suitable for safety-critical applications (e.g. gas alarm or warning systems).
Troubleshooting
No I²C communication
- Ensure SDA and SCL are connected correctly
- Check the supply voltage (3.3 V or 5 V)
- No external I²C pull-up resistors are required (already present on the board)
- Verify the I²C address (
0x1A) - Test the I²C bus using an I²C scanner if necessary
Downloads
- Datasheet (PDF)
Further Links
- Manufacturer documentation
- I²C specification
- Indoor air quality guidelines (TVOC)
Revision / Changelog
| Version | Date | Change |
|---|---|---|
| 1.0 | 2025-01-08 | Initial release |