Volt Docs

Reference

SCD4x

True CO2 (photoacoustic NDIR) in ppm plus temperature and humidity: SCD40 / SCD41.

Connects over
I²C
Address
0x62
Made by
Sensirion
Datasheet
sensirion.com

Use it

main.volt
hardware {
    device scd4x: SCD4x
}

every 1s {
    let value: int = scd4x.co2()
    log("scd4x", "co2={value}")
}

On its own, the declaration puts the SCD4x on the first I²C bus (SDA 21, SCL 22 on the ESP32) at 0x62. To choose the pins or the address, declare the bus and attach the device: device scd4x: SCD4x on i2c0 at 0x62 with i2c i2c0(sda: 21, scl: 22).

Methods

  • scd4x.calibrate(target_ppm: int) -> int

    Forced recalibration to a known CO2 level in ppm (e.g. 420 outdoors) after 3 min of stable readings; returns the correction applied in ppm, or -32768 on failure.

  • scd4x.co2() -> int

    CO2 concentration in ppm.

  • scd4x.humidity() -> float

    Relative humidity %.

  • scd4x.ready() -> bool

    True once the first measurement has been read.

  • scd4x.set_auto_calibration(on: bool)

    Turn automatic self-calibration on or off (on by default).

  • scd4x.set_pressure(hpa: int)

    Ambient pressure in hPa for pressure compensation (e.g. from a BME280); can be called at any time.

  • scd4x.set_temperature_offset(offset: float)

    Self-heating offset in °C subtracted from the temperature reading (default 4).

  • scd4x.temperature() -> float

    Temperature in °C.

Wiring

PinConnect to
VDD3.3V or 5V; needs a solid supply for the 175 mA peaks
GNDGround
SDAI2C data, pull-up on most breakouts
SCLI2C clock

Specifications

Co2
SCD40: 400 - 2000 ppm ±(50 ppm + 5%); SCD41: 400 - 5000 ppm ±(40 ppm + 5%)
Current
~15 mA average in periodic mode (peaks 175 mA)
Humidity
0 - 100% RH ±6%
Sample rate
one measurement every 5 s
Temp
-10 to 60 °C ±0.8 °C
Voltage
2.4V - 5.5V

Tips

  • A new value arrives every 5 s; reading more often returns the last value. ready() is false until the first one (about 5 s after boot).
  • Automatic self-calibration assumes it sees fresh outdoor air (~420 ppm) at least once a week; turn it off with set_auto_calibration(false) in rooms that never get that, and use calibrate(420) outdoors instead.
  • calibrate(), set_temperature_offset() and set_auto_calibration() pause measurements for about 1 s and are not kept across power loss.
  • Self-heating makes it read 2-4 °C warm in an enclosure; correct it with set_temperature_offset().

Alternatives worth knowing:

  • SGP30: Cheaper, but eCO2 is estimated from VOCs, not measured.
  • ENS160: VOC-based AQI / eCO2.