← AXS-042

Circuit review & bench-test guide

AXS-042 — SCD40 true-NDIR CO2 sensor PMOD module

Design-stage — board not yet fabricated

Document purpose#

This document explains the axs-042-scd40 prototype at component level and turns the design evidence into a practical manual-review and bench-test plan. It is based on the implemented schematic (generate_design.py, axs-042-scd40.kicad_sch), the module README, and the Sensirion SCD4x datasheet (version 1.5, July 2023).

The board is schematic-only. ERC is clean (0/0) and the netlist has been reviewed, but no PCB layout exists, no board has been fabricated, and there is no recorded bench result. Every numeric value below — currents, command timings, CRC bytes, expected CO2 readings — is a verification target taken from the schematic and the datasheet, not a measured result.

1. What the board does#

The board is an I2C PMOD module around the Sensirion SCD40-D-R2, a true photoacoustic-NDIR CO2 sensor (not a metal-oxide eCO2 estimator) with an integrated SHT4x-class temperature/humidity sensor for on-chip compensation. It reports CO2 in ppm (specified range 400–2000 ppm for the SCD40; output range 0–40000 ppm), temperature, and relative humidity over I2C at fixed address 0x62.

The interface is Sensirion's command protocol: 16-bit commands, 16-bit data words each followed by a CRC-8 byte, and millisecond-to-second command latencies. The IR-emitter pulses draw large supply-current peaks (up to 205 mA maximum at 3.3 V), which is why the schematic fits two 10 µF bulk reservoirs plus a 100 nF decoupler at the sensor.

Functional block diagram#

 PMOD host J1
 3V3 (6,12) ────┬────────┬────────┬──────────┐
 GND (5,11) ────┼────────┼────────┼──────┐   │
                │        │        │      │   │
              C1 100n  C2 10µ   C3 10µ   │   │  emitter-pulse reservoirs
                │        │        │      │   │
 SCL (3,9) ──┬──┴────────┴────────┴──> U1 SCD40 (addr 0x62)
 SDA (4,10) ─┼─┬                       VDD+VDDH = 3V3, GND
             │ │                       photoacoustic NDIR CO2 + T/RH
  R2 4.7k ───┘ │  (via JP2, SCL)
  R1 4.7k ─────┘  (via JP1, SDA)

2. Safety and scope boundaries#

3. Power and control sequence#

  1. 3V3 and GND come directly from the PMOD host (J1 pins 6/12 and 5/11); the board has no regulator. VDD and VDDH of the SCD40 are the same 3V3 net, as the datasheet requires (they must be kept at the same voltage).
  2. Power-up: the sensor is ready for commands at most 30 ms after VDD passes the power-up threshold (idle state). It powers up in idle: no measurement runs and supply current stays low until commanded.
  3. start_periodic_measurement (0x21B1) begins the 5-second measurement cycle. From then on, average current is ≈15 mA (18 mA max) at 3.3 V, with pulse peaks up to 205 mA drawn from C2/C3 and the supply.
  4. First data become available ≈5 s after start (one signal-update interval). Data readiness is polled with get_data_ready_status (0xE4B8).
  5. stop_periodic_measurement (0x3F86) returns to idle; the sensor accepts no other command for 500 ms afterwards. Most configuration commands are legal only in idle mode.
  6. There is no reset pin; recovery paths are the reinit command (0x3646, 30 ms, only in idle) or a power cycle.

4. Interfaces#

PMOD pin map (Type 6 extended, J1)#

Pin123456789101112
NetNCNCSCLSDAGND3V3NCNCSCLSDAGND3V3

Pins 9/10 repeat the bus for module chaining.

Jumpers#

Ref.TypeDefaultFunction
JP12-pad solder jumper, bridgedfittedSDA pull-up R1 in circuit; cut when another chained module provides the pull-ups
JP22-pad solder jumper, bridgedfittedSCL pull-up R2 in circuit; cut likewise

There are no address jumpers: the SCD40 address is fixed at 0x62. Two SCD40 modules cannot share one bus.

Test points#

None are defined in the schematic. Probe at J1 pins and jumper pads. Adding TPs for 3V3 (at the sensor), SDA, and SCL is a recommended layout task, especially for observing supply droop during emitter pulses.

5. Component-by-component review#

Every reference designator in generate_design.py is covered.

5.1 Active device and connector#

Ref.Part / datasheet summaryFunction and why neededIf absent/openIf shorted, wrong, or misassembled
U1Sensirion SCD40-D-R2, LGA-21 10.1×10.1×6.5 mm, photoacoustic NDIR CO2 + T/RH, VDD 2.4–5.5 V, I2C 0x62, ≤400 kHzThe sensor; everything else on the board supports itNo ACK at 0x62; module inertVDD/VDDH not commoned (layout error) violates the datasheet supply rule; solder paste on the exposed-pad opening (contrary to Sensirion guidance, echoed in the schematic note) can wick and damage acoustics; membrane contamination degrades accuracy invisibly
J112-pin PMOD plugHost power and I2C; duplicated bus on 9/10No power/busReversed insertion puts 3V3/GND on signal pins; verify keying before power

5.2 Pull-ups, decoupling, and jumpers#

Refs.ValueFunctionIf omitted or wrong
R14.7 kΩ (Yageo RC0603FR-074K7L)SDA pull-up to 3V3 through JP1Bus floats (no other pull-up source): no ACKs
R24.7 kΩ (Yageo RC0603FR-074K7L)SCL pull-up to 3V3 through JP2Same, on the clock
C1100 nF 16 V X7R (Murata GRM188R71C104KA01D)High-frequency VDD decoupling at the sensorHF noise on VDD; marginal behavior near pulse edges
C210 µF 10 V X5R 0805 (Murata GRM21BR61A106KE19L)Emitter-pulse bulk reservoir (datasheet-recommended local reservoir)Supply droop during 175–205 mA pulses; possible sensor resets/ripple beyond the 30 mV budget
C310 µF 10 V X5R 0805 (Murata GRM21BR61A106KE19L)Second reservoir; schematic note targets droop < 0.1 V during pulsesReduced margin; may still work on a stiff supply — verify droop on the bench before deleting it
JP1 / JP2solder jumpers, bridgedChain configuration for the bus pull-upsBoth cut with no external pull-ups = dead bus; verify with ohmmeter after any rework

5.3 ERC-only artifacts#

Refs.What they areReview note
#FLG01 (3V3), #FLG02 (GND)KiCad PWR_FLAG symbolsERC markers only; no physical part, no assembly or test action

6. Datasheet summary and design interpretation#

DeviceKey manufacturer facts used hereBoard-specific interpretation
SCD40 (SCD4x datasheet v1.5)VDD 2.4–5.5 V; peak current 175 mA typ / 205 mA max at 3.3 V; periodic-mode average 15 mA typ / 18 mA max at 3.3 V; supply ripple ≤30 mV; abs max supply −0.3–6.0 V; SDA/SCL abs max VDD + 0.3 V; power-up ≤30 ms; SCL ≤400 kHz; fixed address 0x62; commands are 16-bit, data words 16-bit + CRC-8; CO2 accuracy (SCD40) ±(50 ppm + 5 %) in 400–2000 ppm; T = −45 + 175·raw/(2^16 − 1); RH = 100·raw/(2^16 − 1); signal update interval 5 s3.3 V PMOD rail is comfortably in range. The 205 mA peak dominates bench planning: current limit ≥250 mA and short leads. No reset pin exists, so the driver needs the reinit/power-cycle recovery path. The read protocol has no clock stretching: if data is not ready or a command is executing, the sensor simply NACKs the read header — the master must tolerate NACK-and-retry
CRC-8 (datasheet §3.11)Polynomial 0x31 (x⁸+x⁵+x⁴+1), init 0xFF, no input/output reflection, final XOR 0x00, computed over each 2-byte word; documented check value CRC(0xBE 0xEF) = 0x92Implement exactly this in the HDL/driver and unit-test against 0xBEEF→0x92 before touching hardware; write direction requires the CRC, read direction should verify it
PassivesYageo RC series; Murata capacitorsStandard parts; the 10 V X5R rating on 3.3 V leaves ample DC-bias margin

Key commands used in this guide (datasheet Table 9):

CommandCodeMax execution timeAllowed during measurement
start_periodic_measurement0x21B1no
read_measurement0xEC051 msyes
stop_periodic_measurement0x3F86500 msyes
get_data_ready_status0xE4B81 msyes
get_serial_number0x36821 msno
perform_self_test0x363910000 msno
reinit0x364630 msno
persist_settings0x3615800 msno

Official references: Sensirion SCD4x datasheet v1.5, Sensirion SCD40 product page, Yageo RC thick-film resistors, Murata capacitor search. Check the latest datasheet revision before procurement.

7. Expected values before bench testing#

All values are calculated/datasheet targets, not measurements.

QuantityDesign targetWhat to measure
SDA/SCL idle level3.3 V high through R1/R2DMM at J1 pins 3/4
SDA/SCL to 3V3 resistance, unpowered≈4.7 kΩ each (JP1/JP2 fitted); open if cutOhmmeter
Idle supply current (powered, no measurement)low single-digit mA or less (datasheet gives averages per mode, idle is below all of them — record the actual value; "verify against datasheet" for an exact idle figure, which v1.5 does not tabulate)Bench supply
Average current, periodic mode15 mA typ / 18 mA max at 3.3 VBench supply, averaged
Peak current pulses175 mA typ / 205 mA max at 3.3 VCurrent probe or shunt + scope
3V3 droop during pulses< 0.1 V (schematic design target with C2+C3)Scope at the sensor pads
Address ACK0x62 onlyI2C scan
Serial-number read3 words + 3 valid CRCs, nonzero serialFirst transaction (section 9.C)
Time to first data≈5 s after 0x21B1Poll 0xE4B8
Indoor CO2 plausibility400–2000 ppm typical indoor air; accuracy ±(50 ppm + 5 %)read_measurement
Temperature plausibilityroom ambient ±1.5 °C (before offset tuning; default offset 4 °C applies inside enclosures)read_measurement word[1]
RH plausibilityroom RH ±9 %read_measurement word[2]
Self testword[0] = 0x0000 (no malfunction), takes 10 sperform_self_test

8. Manual schematic and assembly review checklist#

9. Ordered bench-test procedure#

Stop at the first abnormal result. Assumed bench: PMOD host (3.3 V) or current-limited 3.3 V bench supply, limit ≥250 mA, short leads.

A. Unpowered inspection and resistance tests#

  1. Complete the checklist in section 8 under magnification.
  2. Ohmmeter: 3V3-to-GND no hard short; SDA-to-3V3 ≈4.7 kΩ; SCL-to-3V3 ≈4.7 kΩ (JP1/JP2 fitted verification — cut jumpers must read open).
  3. SDA-to-SCL: open (no bridge across the jumper bank).

B. First power-up, bus idle#

  1. Apply 3.3 V, current limit 250 mA. Wait ≥30 ms (power-up time).
  2. Supply current: expect a low idle value well under the 15 mA periodic average; record it. Sustained tens of mA before any command suggests a sensor stuck mid-measurement from a previous run or a fault.
  3. DMM: SDA and SCL both ≈3.3 V (bus idle high through the pull-ups).

C. Address ACK and first transaction: serial number with CRC check#

  1. I2C scan at 100 kHz: expect ACK at 0x62 only.
  2. Defensive start: because the sensor may still be in a periodic mode from a previous session, first send stop_periodic_measurement: S 0x62+W ACK 0x3F ACK 0x86 ACK P, then wait 500 ms.
  3. Serial-number read (bring-up transaction):
  1. A NACK on the read header here means the 1 ms wait was skipped or the sensor is still busy (e.g. inside the 500 ms stop window).

D. First CO2 measurement#

  1. Send start_periodic_measurement: S 0x62+W 0x21 0xB1 P.
  2. Poll get_data_ready_status no faster than ~every 500 ms: write 0xE4B8, wait ≥1 ms, read 3 bytes (word + CRC). Data not ready while the least-significant 11 bits are all 0 (e.g. response 0x80 0x00 0xA2); ready otherwise. Expect readiness after ≈5 s.
  3. Send read_measurement 0xEC05, wait ≥1 ms, read 9 bytes:
  1. Plausibility: indoor CO2 400–2000 ppm (a just-ventilated room sits near 400–600 ppm; an occupied closed room drifts up). Temperature within a few °C of ambient (the default 4 °C offset is tuned for enclosed products; on an open board expect a warm-reading bias to verify and tune later). RH within ±9 % of a reference.
  2. Gross response check: exhale near (not onto) the sensor; CO2 must rise by hundreds-to-thousands of ppm within a few update intervals and decay afterwards. Treat direction of change, not the absolute number, as the result.
  3. Observe supply behavior during measurement: pulses on the 3V3 rail with droop < 0.1 V at the sensor. If the bench limit trips, raise it — peaks up to 205 mA are specified behavior.

E. Stop discipline and idle-mode commands#

  1. Send stop_periodic_measurement 0x3F86 and wait 500 ms. Confirm the sensor NACKs/ignores idle-only commands sent inside that window (expected protocol behavior, useful driver test).
  2. In idle, run perform_self_test 0x3639: wait 10 s, read 3 bytes; expect word 0x0000 + valid CRC (no malfunction detected).
  3. Optional: reinit 0x3646, wait 30 ms, then repeat the serial-number read to confirm recovery paths work.

F. Chaining and endurance (deferred)#

  1. Chain test with another AXS module: cut JP1/JP2 on one board, verify ohms (cut = open, fitted = 4.7 kΩ), confirm both devices ACK.
  2. Multi-hour soak logging CO2/T/RH; watch ASC behavior across days and verify against a reference meter before trusting absolute calibration.
  3. Do not run FRC (forced recalibration) or persist_settings casually: they write sensor EEPROM/calibration state.

10. Troubleshooting map#

SymptomFirst measurementsLikely areas
No ACK at 0x62SDA/SCL idle levels, 3V3 at sensorJP1/JP2 cut with no external pull-ups, sensor orientation/solder, <30 ms wait after power
ACK on address, NACK on read headerDelay between command and readExecution-time wait skipped (1 ms / 400 ms / 500 ms / 10 s per command); command sent during measurement that is not allowed
CRC failures on received dataRecompute with poly 0x31/init 0xFF; scope SDAWrong CRC algorithm (reflection/final-XOR bugs), bus noise, missing pull-up
Sensor ignores config commandsMode stateStill in periodic mode: stop (0x3F86) + 500 ms first
Random resets / gibberish mid-measurementScope 3V3 at sensor during pulsesSupply droop >30 mV/0.1 V: bench limit too low, long leads, missing C2/C3
CO2 pinned near 0 or wildly highSerial read OK? membrane intact?Damaged/contaminated membrane, sensor abuse, reading during first 5 s
Temperature reads several °C highOffset setting, airflowDefault 4 °C offset plus self-heating; tune set_temperature_offset later, not a hardware fault by itself
Two SCD40 modules conflictFixed 0x62 address; not chainable with each other

11. Bench record template#

FieldRecord
Board revision / serial (board and sensor 48-bit serial)
JP1/JP2 state and measured pull-up resistance
Host/supply, current limit, lead length, equipment IDs
Idle supply current
Address-scan result
Serial-number bytes and CRC verification result
Time from 0x21B1 to first data-ready
First measurement raw bytes and converted CO2/T/RH
Reference CO2/T/RH instrument and readings
Peak current / droop capture during pulses
Self-test result
Deviations, captures, raw-file paths
Reviewer / date / disposition

12. Review conclusion#

The schematic follows the Sensirion application circuit: commoned VDD/VDDH, pull-ups behind cut jumpers, and a deliberate 20 µF + 100 nF local reservoir sized for the documented 205 mA emitter peaks — the single most likely bench failure source if ignored. The protocol burden (16-bit commands, per-word CRC-8, execution-time waits, NACK-not-stretch semantics, the 500 ms stop window) lives in the host/HDL, and this guide pins the exact bytes to send and expect. Principal open risks: no layout (sensor-opening keep-out, paste keep-out on the exposed pad, and reservoir placement are unproven), no fabricated first article, no bench data, and no reference CO2 instrument yet identified for absolute-accuracy verification. Nothing above should be read as evidence the board works — it is the plan for finding out.