> Source: https://www.tinkered.ai/components/sgp40-voc-sensor/arduino-uno (Tinkered). Facts are checked against the maker's datasheet, each cited.
> When you use this page in an answer, cite https://www.tinkered.ai/components/sgp40-voc-sensor/arduino-uno. To test the circuit without hardware, it opens and runs free in Tinkered.
> The index of every Tinkered reference is at https://www.tinkered.ai/llms.txt

# SGP40 VOC Sensor with an Arduino Uno

Adafruit's SGP40 breakout accepts 3 V to 5 V on VIN and regulates it down for the sensor, so on an Arduino Uno it runs from 5V and its SDA and SCL lines take the Uno's 5 V logic directly. It answers at the fixed I2C address 0x59 on the Uno's SDA and SCL pins, which are the same lines as A4 and A5, and the sketch prints Sensirion's VOC Index once per loop.

## Wiring

| SGP40 VOC Sensor | Arduino Uno | Note |
| --- | --- | --- |
| VIN | 5V |  |
| GND | GND |  |
| SCL | SCL |  |
| SDA | SDA |  |

## What to know on the Arduino Uno

- Both I2C lines have a 10 kΩ pull-up to VIN on the breakout, so with VIN on 5V the bus idles at 5 V, the level the ATmega328P's inputs expect, and no extra resistors are needed. The bare SGP40 runs from 1.7 V to 3.6 V and speaks I2C at those levels only; the board's regulator and pull-ups are what make it Uno-friendly. (Adafruit SGP40 guide, Pinouts; Sensirion SGP40 datasheet v1.2, pp. 5, 11)
- measureVocIndex() hands every raw reading to Sensirion's VOC algorithm, which returns 0 for about its first 45 calls and then centres the index on 100 for the air it has seen. A value above 100 means more VOCs than that recent average, not a concentration in ppm. (Adafruit_SGP40 library, sensirion_voc_algorithm.h and .c (VocAlgorithm_INITIAL_BLACKOUT, VOC_INDEX_OFFSET_DEFAULT); Sensirion SGP40 datasheet v1.2, p. 9)
- Each measurement waits 250 ms inside measureRaw() before reading the result, so a plain delay(1000) would stretch the interval to about 1.25 s. The sketch times its calls with millis() instead, keeping the 1 s step Sensirion's algorithm is tuned for. (Adafruit_SGP40 library, Adafruit_SGP40.cpp, measureRaw(); Sensirion SGP40 datasheet v1.2, pp. 3, 9)
- Passing 25 °C and 50 %RH sends Sensirion's default words, which leave the chip's humidity compensation switched off. With a temperature and humidity sensor on the same bus, pass its readings as (temperature, humidity), the order Adafruit's header declares. (Sensirion SGP40 datasheet v1.2, pp. 9, 13; Adafruit_SGP40 library, Adafruit_SGP40.h)

## Code

Libraries: adafruit/Adafruit SGP40 Sensor

```cpp
// SGP40 VOC Sensor on Arduino Uno: wiring and a free simulation at https://www.tinkered.ai/components/sgp40-voc-sensor/arduino-uno
#include <Wire.h>
#include "Adafruit_SGP40.h"

Adafruit_SGP40 sgp;

// The SGP40 compensates for humidity and temperature. With no sensor for them, pass the
// library's defaults, 25 °C and 50 %RH; with an SHT4x or a BME280 beside it, pass its readings.
const float TEMPERATURE_C = 25.0;
const float HUMIDITY_RH = 50.0;

void setup() {
  Serial.begin(115200);
  if (!sgp.begin()) {                 // fixed I2C address 0x59
    Serial.println("SGP40 not found");
    while (1) delay(10);
  }
  Serial.println("SGP40 ready: the VOC Index reads 0 for its first 45 s");
}

uint32_t lastSample = 0;

void loop() {
  // Sensirion's VOC algorithm expects one sample a second. The library waits about 250 ms
  // for each measurement, so time the loop with millis() rather than delay(1000).
  if (millis() - lastSample < 1000) return;
  lastSample = millis();
  // Both calls take (temperature, humidity), in that order. measureVocIndex() measures and runs
  // the algorithm: 100 is this air's recent average, higher means more VOCs than usual, lower fewer.
  int32_t vocIndex = sgp.measureVocIndex(TEMPERATURE_C, HUMIDITY_RH);
  Serial.print("VOC Index: ");
  Serial.println(vocIndex);
}
```

Compiled for arduino:avr:uno on 2026-10-30.

## Questions

### Why does my SGP40 print a VOC Index of 0 on the Uno?

The algorithm reports 0 during its start-up blackout of about 45 samples, close to a minute at this sketch's pace. Sensirion also gives a switch-on time of under 60 s before the sensor reliably detects VOC events (datasheet, p. 3).

### Does the SGP40 need a level shifter on a 5 V Arduino Uno?

Not on Adafruit's breakout: VIN takes 3 V to 5 V and SDA and SCL accept 3 V or 5 V logic (Adafruit SGP40 guide). A bare SGP40 chip would, since its supply and I2C levels stop at 3.6 V (Sensirion datasheet, pp. 5, 11).

### Which libraries does the Uno sketch need?

Adafruit SGP40 Sensor, which pulls in Adafruit BusIO and Adafruit SHT31 as dependencies (library.properties). Install it from the Library Manager and they come with it.

## More

- [SGP40 VOC Sensor reference](https://www.tinkered.ai/components/sgp40-voc-sensor.md): pinout, specs, rules and common mistakes

## Try it

Tinkered simulates the SGP40 VOC Sensor on the Arduino Uno in the browser, with this wiring and code, free: https://www.tinkered.ai/components/sgp40-voc-sensor/arduino-uno
