Circuit review & bench-test guide
AXS-043 — CCS811 eCO2/TVOC gas-sensor PMOD module
Document purpose#
This document explains the axs-043-eco2 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-043-eco2.kicad_sch), the module README, and the ams CCS811 datasheet (v1-06, 2019-Feb-07).
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 — register values, currents, timings, burn-in behavior — 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 ams (ScioSense) CCS811B-JOPD500, a metal-oxide (MOX) gas sensor with an integrated MCU that converts raw resistance readings into equivalent CO2 (eCO2, 400–29206 ppm) and equivalent total VOC (eTVOC, 0–32768 ppb) estimates. Unlike the SCD40 (AXS-042), this is not a true CO2 measurement — eCO2 is inferred from VOCs, mainly of human origin. The module substitutes the CCS811 for the catalog's original ENS160 (no stock KiCad assets) and teaches the same lessons: boot-to-application state machine (APP_START), measurement-mode selection, data-ready interrupt, baseline save/restore, and the nWAKE handshake.
I2C address is 0x5A (default, JP4 1-2) or 0x5B (JP4 2-3). nWAKE is grounded by default (JP3 1-2, always awake) or handed to the host on PMOD pin 2 (JP3 2-3). nINT reaches PMOD pin 1 through a 10 kΩ pull-up and 100 Ω series resistor. nRESET is pulled up on-module only and is not routed to the PMOD — resets are done through the I2C SW_RESET mailbox.
Functional block diagram#
PMOD host J1
3V3 (6,12) ──┬──────┬──────┬──────────────┐
GND (5,11) ──┼──────┼──────┼───────┐ │
C1 100n C2 10µ R3 10k │ │
│ │ │ │ │
SCL (3,9) ───┴──────┴──────┼────> U1 CCS811 (MOX eCO2/TVOC, addr 0x5A/0x5B)
SDA (4,10) ────────────────┼────> │
(pull-ups R1/R2 4.7k │ │ ADDR <── JP4 (1-2 GND=0x5A / 2-3 3V3=0x5B)
via JP1/JP2) │ │ nWAKE <─ JP3 (1-2 GND=awake / 2-3 host pin 2)
│ │ nRESET <─ R5 10k to 3V3 (on-module only)
pin 1 ECO2_INT_N <── R4 100R ── nINT (open-drain, R3 10k pull-up)
pin 2 ECO2_WAKE_N ──> JP3 pos. 3 │ PWM/Sense/AUX: no-connect per datasheet
2. Safety and scope boundaries#
- Electrically benign 3.3 V board; peak heater current is bounded at 54 mA (abs max, modes 2/3) with ≈26 mA typical while measuring — a 100 mA bench current limit is comfortable.
- The CCS811 operating supply is 1.8–3.3 V (3.6 V absolute maximum). The 3.3 V PMOD rail sits at the top of the operating range: any bench supply overshoot or a misadjusted 3.6+ V rail eats the entire margin. Check the rail before attach. VDD is sampled during boot and must not vary during operation; max power-on VDD ramp time is 3 ms.
- Accuracy claims are heavily conditioned: the MOX element changes most over the first 48 hours of operation (burn-in); the datasheet permits using readings 60 minutes after first power-on in modes 1–3, and requires a 20-minute run-in after each MEAS_MODE write before readings are accurate. Early readings pinned at eCO2 = 400 ppm / eTVOC = 0 ppb are normal, not a fault. Do not "fail" a fresh board for boring output.
- eCO2 is an estimate from VOC response. Never present it as a CO2 measurement or compare it 1:1 against the SCD40 without saying so.
- MOX sensors are poisoned by siloxanes (RTV silicone, some fluxes, conformal coatings). Keep such materials away from the sensor, including during assembly and rework.
- This prototype has no layout, no fab, and no bench history. All values are verification targets.
3. Power and control sequence#
- 3V3/GND come from the PMOD host; no local regulator. C1/C2 decouple the pulsed MOX heater supply.
- Power-on: with nRESET held high by R5 and nWAKE low (JP3 default), the device boots in 18–20 ms (tSTART) into boot mode (FW_MODE = 0). It is not measuring yet.
- Host verifies HW_ID (0x20 = 0x81), checks STATUS (0x00) for APP_VALID = 1, then writes the register address 0xF4 (APP_START) with no data byte. Within 1 ms the device is in application mode (FW_MODE = 1).
- Host writes MEAS_MODE (0x01) to select a drive mode; this board's bring-up uses mode 1 (constant power, one measurement per second). DATA_READY in STATUS sets each cycle; nINT (if enabled by INT_DATARDY) pulls PMOD pin 1 low until ALG_RESULT_DATA is read.
- If JP3 is moved to 2-3, the host owns nWAKE on PMOD pin 2 and must drive it low before and throughout every I2C transaction; the device is ready within 50 µs of the falling edge (tWAKE) and nWAKE must stay high ≥20 µs (tDWAKE) between wakes.
- Reset paths: I2C SW_RESET mailbox 0xFF with the 4-byte key 0x11 0xE5 0x72 0x8A (back to boot mode in 1–2 ms), or a power cycle. nRESET is deliberately not routed off-module.
4. Interfaces#
PMOD pin map (Type 6 extended, J1)#
| Pin | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Net | ECO2_INT_N | ECO2_WAKE_N | SCL | SDA | GND | 3V3 | NC | NC | SCL | SDA | GND | 3V3 |
Pin 2 is only driven into the sensor when JP3 is set 2-3; in the default position the net dead-ends at the jumper.
Jumpers#
| Ref. | Type | Default | Function |
|---|---|---|---|
| JP1 | 2-pad solder jumper, bridged | fitted | SDA pull-up R1 in circuit; cut when a chained module provides pull-ups |
| JP2 | 2-pad solder jumper, bridged | fitted | SCL pull-up R2 in circuit; cut likewise |
| JP3 | 3-pad solder jumper, 1-2 bridged | nWAKE = GND (always awake) | 2-3 hands nWAKE to the host as ECO2_WAKE_N on PMOD pin 2 |
| JP4 | 3-pad solder jumper, 1-2 bridged | ADDR = GND → 0x5A | 2-3 sets ADDR = 3V3 → 0x5B |
Test points#
None are defined in the schematic. Probe at J1 pins and jumper pads. Layout should add TPs for nINT, nWAKE, nRESET, SDA, SCL, and 3V3.
5. Component-by-component review#
Every reference designator in generate_design.py is covered.
5.1 Active device and connector#
| Ref. | Part / datasheet summary | Function and why needed | If absent/open | If shorted, wrong, or misassembled |
|---|---|---|---|---|
| U1 | ams CCS811B-JOPD500, LGA-10 2.7×4.0 mm, MOX eCO2/TVOC with integrated MCU, VDD 1.8–3.3 V | The sensor and its algorithm engine | No ACK; module inert | Rotated LGA misconnects the heater pins; PWM (4) and Sense (5) must be tied together inside this design's no-NTC option they float per datasheet note — see review note below; solder voids under the EP break the ground return |
| J1 | 12-pin PMOD plug | Host power, I2C, interrupt, optional wake | No power/bus | Reversed insertion puts 3V3/GND on signal pins |
PWM/Sense review note: the datasheet's recommended circuit connects pins 4 and 5 together (heater loop). This schematic leaves PWM, Sense, and AUX as no-connects, citing the datasheet's external-NTC-unused guidance. This is a deliberate deviation to re-verify against the datasheet and ScioSense application note before layout — if pins 4-5 must be commoned even without the NTC network, the schematic needs a one-wire fix. Flagged OPEN.
5.2 Pull-ups, series parts, and decoupling#
| Refs. | Value | Function | If omitted or wrong |
|---|---|---|---|
| R1 | 4.7 kΩ (Yageo RC0603FR-074K7L) | SDA pull-up to 3V3 through JP1 | Bus floats without another pull-up source |
| R2 | 4.7 kΩ (Yageo RC0603FR-074K7L) | SCL pull-up to 3V3 through JP2 | Same, on the clock |
| R3 | 10 kΩ (Yageo RC0603FR-0710KL) | Pull-up for the open-drain nINT output | nINT never returns high reliably; host sees a stuck interrupt |
| R4 | 100 Ω (Yageo RC0603FR-07100RL) | Series protection between sensor nINT and host pin (fault-current limiting on a sensor-driven line) | Direct pin-to-pin coupling; a host driving against the sensor sources unlimited current |
| R5 | 10 kΩ (Yageo RC0603FR-0710KL) | nRESET pull-up, on-module only (datasheet: 4.7 kΩ pull-up and/or decoupling "may be necessary to avoid erroneous noise-induced resets") | nRESET has a weak internal pull-up, but noise-induced resets become plausible; with R5 open the reset behavior is unverified |
| C1 | 100 nF 16 V X7R (Murata GRM188R71C104KA01D) | VDD high-frequency decoupling (datasheet requires a decoupling cap close to VDD) | Heater-pulse noise on VDD; risk of boot-sampling errors since VDD is sampled at boot |
| C2 | 10 µF 10 V X5R 0805 (Murata GRM21BR61A106KE19L) | Bulk reservoir for the pulsed MOX heater (datasheet circuit shows 4.7 µF; 10 µF is a superset) | Supply droop during heater pulses; marginal operation on soft supplies |
| JP1/JP2/JP3/JP4 | solder jumpers | See section 4 | A 3-pad jumper with no side bridged floats ADDR or nWAKE: ADDR must be tied per datasheet, and a floating nWAKE can park the device in sleep — always bridge exactly one side |
5.3 ERC-only artifacts#
| Refs. | What they are | Review note |
|---|---|---|
| #FLG01 (3V3), #FLG02 (GND) | KiCad PWR_FLAG symbols | ERC markers only; no physical part, no test action |
6. Datasheet summary and design interpretation#
| Device | Key manufacturer facts used here | Board-specific interpretation |
|---|---|---|
| CCS811 (v1-06) | VDD 1.8–3.3 V operating, 1.8–3.6 V abs max; IDD ≈26 mA typ while measuring, 30 mA abs-max average (mode 1), 54 mA abs-max peak (modes 2/3), 19 µA sleep; I2C 10–400 kHz, addresses 0x5A/0x5B via ADDR; clock stretching 0–100 ms max — the host I2C master must support clock stretching; tSTART 18–20 ms after power-on, 1–2 ms after reset; tAPP_START ≤1 ms; tWAKE ≤50 µs after falling nWAKE; tDWAKE ≥20 µs; nRESET low ≥15 µs; HW_ID (0x20) = 0x81; HW_Version (0x21) = 0x1X; STATUS (0x00) bits FW_MODE(7)/APP_VALID(4)/DATA_READY(3)/ERROR(0); MEAS_MODE (0x01) DRIVE_MODE bits 6:4, INT_DATARDY bit 3; ALG_RESULT_DATA (0x02) 8 bytes; BASELINE (0x11) 2-byte save/restore; ERROR_ID (0xE0); SW_RESET (0xFF) key 0x11 0xE5 0x72 0x8A; eCO2 400–29206 ppm, eTVOC 0–32768 ppb; burn-in 48 h (usable after 60 min), run-in 20 min after each MEAS_MODE write; mode changes to a slower mode require 10 min in mode 0 first | The 3.3 V rail is at the top of the operating range — verify no overshoot. The 100 ms clock-stretch ceiling is the notorious CCS811 erratum territory: many MCU/FPGA masters (and bit-banged masters with fixed timeouts) fail here; the AruviX HDL I2C master must implement SCL-released detection with a ≥100 ms timeout, or run SCL slow (10–100 kHz) during bring-up. nWAKE grounded via JP3 default removes the tWAKE burden for first bring-up; the 2-3 position exists to teach the handshake later |
| Baseline management | BASELINE (0x11) holds an encoded baseline; automatic baseline correction runs over ≥24 h windows; manual save/restore per ams AN000370; conditioning (run-in) must be observed before writing BASELINE | Save the baseline after long clean-air operation, restore after power cycles for faster useful readings; never write a baseline into an un-conditioned sensor |
| Passives | Yageo RC series; Murata capacitors | Standard parts, no special constraints at 3.3 V |
Official references: CCS811 datasheet v1-06 (SparkFun-hosted ams PDF), ScioSense CCS811 product page (ams gas sensing was transferred to ScioSense; check there for current documentation and application notes AN000369/AN000370/AN000371), Yageo RC thick-film resistors, Murata capacitor search. Note the CCS811 is end-of-life at ScioSense (successor ENS160 — the catalog's original choice); confirm stock before committing the BOM.
7. Expected values before bench testing#
All values are datasheet/design targets, not measurements.
| Quantity | Design target | What to measure |
|---|---|---|
| SDA/SCL idle level | 3.3 V high through R1/R2 | DMM at J1 pins 3/4 |
| SDA/SCL to 3V3, unpowered | ≈4.7 kΩ each (JP1/JP2 fitted); open if cut | Ohmmeter |
| nINT idle | ≈3.3 V through R3 (via R4 at pin 1) | DMM at J1 pin 1 |
| nWAKE at sensor | 0 V (JP3 1-2 default) | DMM at JP3 common pad |
| ADDR at sensor | 0 V (JP4 1-2) → address 0x5A | DMM at JP4 common pad |
| Boot time | ready for I2C 18–20 ms after power | Delay before first transaction |
| Idle/boot supply current | well under measuring levels; sleep spec 19 µA (nWAKE high) — "verify against datasheet" for a boot-idle figure, which v1-06 does not tabulate separately | Bench supply |
| Supply current, mode 1 measuring | ≈26 mA typ pulses; ≤30 mA average (abs max); ≤54 mA peaks if modes 2/3 tried | Bench supply / scope |
| HW_ID (0x20) | 0x81 | First transaction |
| HW_Version (0x21) | 0x1X (top nibble 1) | Read |
| STATUS after boot | FW_MODE = 0, APP_VALID = 1, ERROR = 0 (e.g. 0x10) | Read 0x00 |
| STATUS after APP_START | FW_MODE = 1 (e.g. 0x90; 0x98 once data ready) | Read 0x00 |
| First readings (new sensor) | eCO2 pinned 400 ppm, eTVOC 0 ppb — normal during early burn-in/run-in | ALG_RESULT_DATA |
| Readings after 20 min run-in | eCO2 400–29206 ppm range; responds to VOC stimulus (alcohol swab, breath) within seconds | ALG_RESULT_DATA trend |
| Clock stretch events | up to 100 ms SCL held low | Scope/analyzer on SCL |
8. Manual schematic and assembly review checklist#
- Verify U1 pin-1 corner (index area) orientation; LGA-10 with EP — X-ray or edge-wetting inspection after reflow.
- Confirm EP soldered to GND (it is the device ground per the block diagram).
- Resolve the PWM/Sense question before layout: datasheet Figure 11 note 1 says "PWM (Pin 4) and Sense (Pin 5) must be connected together"; the schematic floats them. Confirm against ScioSense guidance and fix or document. (Currently flagged OPEN in section 5.1.)
- JP1/JP2 bridged or deliberately cut; JP3 and JP4 each have exactly one side bridged; record positions.
- Buzz J1 pin 1 → R4 → R3/nINT node; pin 2 → JP3 pad 3; pins 3/4 → SCL/SDA (and 9/10 duplicates).
- Confirm R5 connects nRESET to 3V3 and that nRESET is not routed to J1.
- C1 close to VDD (layout task); C2 adjacent.
- 3V3-to-GND: no hard short.
- Siloxane hygiene: no silicone adhesives/coatings near the sensor; note flux chemistry used at assembly.
9. Ordered bench-test procedure#
Stop at the first abnormal result. Assumed bench: PMOD host (3.3 V, verified ≤3.3 V no-overshoot) or current-limited 3.3 V supply, limit ≈100 mA. Run SCL at 100 kHz or slower until clock-stretch handling is proven.
A. Unpowered inspection and resistance tests#
- Complete the checklist in section 8 under magnification.
- Ohmmeter: SDA-to-3V3 ≈4.7 kΩ, SCL-to-3V3 ≈4.7 kΩ (JP1/JP2 fitted verification; cut = open). nINT-node-to-3V3 ≈10 kΩ (R3); J1 pin 1 to the sensor nINT pad ≈100 Ω (R4).
- JP3 common to GND: ≈0 Ω (default). JP4 common to GND: ≈0 Ω (default).
- 3V3-to-GND: no hard short (rises as C2 charges).
B. First power-up, bus idle#
- Apply 3.3 V, limit 100 mA. Wait ≥20 ms (tSTART).
- Supply current: expect a small boot-mode value, far below measuring levels; record it. Tens of mA before MEAS_MODE is set is suspicious.
- DMM: SDA, SCL ≈3.3 V; nINT (J1 pin 1) ≈3.3 V.
C. Address ACK and first transaction: HW_ID#
- I2C scan at ≤100 kHz: expect ACK at 0x5A only (JP4 default). With JP4 re-bridged 2-3, expect 0x5B only. Both ACKing, or neither, means a strap/solder problem.
- First transaction — HW_ID readback:
- Set pointer:
S 0x5A+W ACK 0x20 ACK P - Read:
S 0x5A+R ACK data NACK P - Expected data: 0x81. (Combined repeated-start form is equally valid.) Anything else: wrong device, bus corruption, or clock-stretch mishandling by the master.
- Read HW_Version 0x21: expect 0x1X. Read STATUS 0x00: expect FW_MODE = 0 (boot), APP_VALID = 1, ERROR = 0 — typically 0x10.
- If ERROR = 1: read ERROR_ID 0xE0 (this also clears the error) and decode bits 0–5 (WRITE_REG_INVALID, READ_REG_INVALID, MEASMODE_INVALID, MAX_RESISTANCE, HEATER_FAULT, HEATER_SUPPLY).
D. App-start sequence and measurement mode#
- Confirm STATUS shows APP_VALID = 1 and FW_MODE = 0.
- APP_START: write the register address alone, no data byte:
S 0x5A+W ACK 0xF4 ACK P. Wait ≥1 ms (tAPP_START). - Re-read STATUS: expect FW_MODE = 1 (e.g. 0x90). FW_MODE still 0 means the app did not start — check APP_VALID and ERROR_ID.
- MEAS_MODE: write drive mode 1 with data-ready interrupt enabled:
S 0x5A+W ACK 0x01 ACK 0x18 ACK P(DRIVE_MODE = 001, INT_DATARDY = 1; use 0x10 if polling STATUS instead of using nINT). - Within ~1 s: STATUS DATA_READY (bit 3) sets each second; with 0x18, nINT (J1 pin 1) pulses low each cycle and releases when ALG_RESULT_DATA is read. Scope it: this is the interrupt-wiring test for R3/R4.
E. First data read and burn-in honesty#
- Read ALG_RESULT_DATA (0x02), 8 bytes: byte 0/1 = eCO2 ppm (MSB first), byte 2/3 = eTVOC ppb, byte 4 = STATUS, byte 5 = ERROR_ID, bytes 6/7 = RAW_DATA (current source 6 bits + 10-bit raw ADC).
- Expected early behavior — do not mislabel it a failure: a new sensor in burn-in, or any sensor in its first 20-minute run-in after MEAS_MODE, legitimately reports eCO2 = 400 ppm, eTVOC = 0 ppb flat. Datasheet conditions: 48-hour early-life burn-in (readings usable after 60 min in modes 1–3) and 20-minute conditioning after each mode write; conditioning must also pass before writing BASELINE.
- Stimulus test (direction, not magnitude): an alcohol swab waved near the sensor must spike eTVOC (and eCO2 upward) within seconds, decaying after removal. This proves the MOX element and heater work long before absolute accuracy is meaningful.
- Log STATUS/ERROR_ID with every sample; any ERROR bit fails the run until decoded.
F. Baseline, wake handshake, and reset paths (second session)#
- After ≥20 min run-in in clean air (ideally after 48 h burn-in), read BASELINE (0x11, 2 bytes) and store it with the board record. Restore it after a power cycle and confirm readings converge faster. Follow ams AN000370 semantics; never restore a stale baseline across mode changes.
- JP3 2-3 wake handshake test: move JP3 to 2-3; host must drive ECO2_WAKE_N (pin 2) low ≥ tWAKE-settled (device ready ≤50 µs after the falling edge) before each transaction, hold it low throughout, and keep it high ≥20 µs (tDWAKE) between transactions. Verify: with pin 2 held high, the device must NACK (asleep, ~19 µA); with pin 2 low, HW_ID reads 0x81 again.
- SW_RESET: write
0xFF 0x11 0xE5 0x72 0x8Ain one transaction; wait 2 ms; STATUS must show FW_MODE = 0 again; repeat APP_START to recover. - Mode-change discipline check: switching to a slower mode (e.g. 1 → 3) requires 10 minutes in mode 0 first; verify the driver enforces it.
G. Clock-stretch stress (before HDL sign-off)#
- With a scope on SCL, capture stretch events during ALG_RESULT_DATA reads and around APP_START; the datasheet allows up to 100 ms.
- Sweep SCL 10 → 100 → 400 kHz; the AruviX I2C master must complete transfers at each speed or degrade gracefully. Any master timeout shorter than 100 ms is a design bug on this bus, not a sensor fault.
10. Troubleshooting map#
| Symptom | First measurements | Likely areas |
|---|---|---|
| No ACK at 0x5A/0x5B | SDA/SCL idle, ADDR pad voltage, nWAKE pad voltage | JP4 unbridged/floating, JP3 unbridged (device asleep), JP1/JP2 cut without external pull-ups, U1 solder |
| ACK at 0x5B when 0x5A expected | JP4 bridge side | Strap bridged 2-3, or 3V3 solder whisker to ADDR |
| HW_ID not 0x81 | Repeat at 10 kHz; scope SCL for stretching | Master clock-stretch mishandling (classic CCS811 failure), bus corruption |
| APP_START does not set FW_MODE | STATUS APP_VALID bit; ERROR_ID | No valid app firmware (APP_VALID = 0), data byte wrongly appended to the 0xF4 write |
| MEAS_MODE write errors | ERROR_ID bit 2 (MEASMODE_INVALID) | Reserved bits set, unsupported mode code |
| DATA_READY never sets | STATUS each second; supply current | MEAS_MODE still 0 (idle), heater fault (ERROR_ID bits 4/5), VDD droop during heater pulses (C1/C2) |
| nINT never asserts but DATA_READY sets | INT_DATARDY bit; R3/R4 continuity | MEAS_MODE written 0x10 not 0x18, open R3/R4, pin-1 wiring |
| nINT stuck low | Read ALG_RESULT_DATA (releases it) | Data never read; solder short on the nINT net |
| Readings stuck 400 ppm / 0 ppb | Time since power-on and mode write | Normal burn-in/run-in behavior — wait 20 min (and up to 48 h for spec accuracy) before judging |
| Wild/pinned-high readings | ERROR_ID MAX_RESISTANCE; environment | Sensor poisoning (siloxanes), end-of-life element, contaminated assembly |
| Random resets to boot mode | VDD at U1 during heater pulses; R5 | Supply droop/noise on nRESET (datasheet warns of noise-induced resets), boot-time VDD variation |
11. Bench record template#
| Field | Record |
|---|---|
| Board revision / serial | |
| JP1–JP4 positions; measured pull-up/strap resistances | |
| Host/supply, current limit, measured rail (incl. overshoot check) | |
| Address-scan result | |
| HW_ID / HW_Version / FW_Boot_Version (0x23) / FW_App_Version (0x24) | |
| STATUS before and after APP_START | |
| MEAS_MODE value written; time of write | |
| Supply current in mode 1 (average and pulse capture) | |
| Time-stamped eCO2/eTVOC log incl. stimulus response | |
| Clock-stretch capture (max duration observed, SCL speed) | |
| BASELINE value saved / restore result | |
| Wake-handshake test result (if JP3 2-3 exercised) | |
| SW_RESET recovery result | |
| Deviations, captures, raw-file paths | |
| Reviewer / date / disposition |
12. Review conclusion#
The schematic is a reasonable CCS811 application: strap-selectable address, default-grounded nWAKE for painless bring-up with a jumpered path to the real handshake, an on-module-only nRESET (forcing the more instructive SW_RESET path), protected open-drain interrupt routing, and heater-aware decoupling. Three open items dominate: (1) the PWM/Sense pins are floated where the datasheet's application circuit ties pins 4 and 5 together — resolve before layout; (2) the 100 ms clock-stretch requirement must be designed into the AruviX I2C master, since this is the CCS811's best-known integration failure; (3) the part is end-of-life at ScioSense, so BOM availability (or a pivot back to the ENS160 once symbols exist) needs a decision. Beyond those: no layout, no fabricated first article, and no bench data exist — the burn-in/run-in expectations above are written precisely so that a fresh board's boring 400 ppm/0 ppb output is not misread as either success or failure.