Files
esp_sensair/README.md
T

178 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ESP32-C3 CO₂ & Environment Sensor Board
A small environmental monitoring board: **ESP32-C3** module with a **Sensirion S8** NDIR CO₂ sensor
(UART) and a **BME280** temperature / humidity / pressure sensor (I²C). Flashed with ESPHome and
integrated into Home Assistant.
**Status:** prototype v1 — designed in KiCad, fabricated at PCBWay, hand assembled, powered up and
running.
| | |
|---|---|
| Board size | 50.05 × 40.05 mm |
| Layers | 2 |
| Assembly | through-hole / pin-header plug-in modules |
| Firmware | ESPHome (see [`firmware/`](firmware/)) |
| Schematic | [`docs/esp-sensair-schematic.pdf`](docs/esp-sensair-schematic.pdf) |
| Fabrication data | [`gerber/`](gerber/) (Gerber X2 + Excellon + ODB job) |
![3D render](docs/esp-sensair-3d-top.png)
## Block diagram
```
+5 V
|
+-------------------------+---------------------------+
| | |
| +----------v----------+ |
| | ESP32-C3 module |--- 3.3 V out --+|
| | (onboard 3V3 LDO) | ||
+--------------+ | ||
| UART 9600 +----------+----------+ ||
| | ||
+-----v-------+ +------v-------+ v
| Sensirion S8| | BME280 |<--- I2C (SDA/SCL) --+
| NDIR CO2 | | T / RH / P |
+-------------+ +--------------+
SW1 (calibration button) -- RC debounce (1 k / 100 n) -- ESP32-C3 GPIO
```
## Connections
| Signal | ESP32-C3 module | Sensirion S8 | BME280 |
|---|---|---|---|
| `+5V` | pad 11 | pad 0 (heater supply) | — |
| `GND` | pad 12 | pad 1 | pads 0, 4 |
| `+3V3` | pad 13 (module output) | — | pads 1, 5 |
| `/TX` | pad 21 | pad 6 (`UART_RxD`) | — |
| `/RX` | pad 20 | pad 5 (`UART_TxD`) | — |
| `/SDA` | pad 7 | — | pad 2 |
| `/SCL` | pad 8 | — | pad 3 |
| `bCal_in` | — | pad 8 (`bCal_in`) | — |
Sensirion S8 pins `Alarm_OC`, `PWM_1kHz`, `DVCC_out` and `UART_R/T` are left unconnected.
## Bill of materials
| Ref | Part | Package | Function |
|---|---|---|---|
| U1 | ESP32-C3 Wi-Fi/BLE module (16 pads) | custom `esp_sensair_stuff:ESP32-C3` | MCU, radio, 3.3 V regulator on module |
| U2 | Sensirion S8 NDIR CO₂ sensor | custom `esp_sensair_stuff:Sensair S8` | CO₂ measurement, UART, 5 V heater |
| U3 | BME280 (plug-in breakout) | custom `esp_sensair_stuff:BME280` | temperature, relative humidity, pressure, I²C |
| SW1 | Tactile push button 6 mm | `Button_Switch_THT:SW_PUSH_6mm` | S8 manual (background) calibration trigger |
| R1 | 1 kΩ | `Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P7.62mm_Horizontal` | button debounce, low-pass to GND |
| C1 | 100 nF | `Capacitor_THT:C_Disc_D10.5mm_W5.0mm_P5.00mm` | button debounce / supply decoupling |
Machine-readable BOM: [`bom/esp-sensair-bom.csv`](bom/esp-sensair-bom.csv)
## Fabrication
Order data used for the v1 prototype:
| Parameter | Value |
|---|---|
| Fabricator | PCBWay |
| Layers | 2 |
| Board size (ordered) | 40 × 50 mm |
| Board size (design) | 40.05 × 50.05 mm |
| Board material | FR-4 |
| Board thickness | 1.6 mm |
| Finished copper weight | 1 oz (35 µm) |
| Surface finish | HASL with lead |
| Design rules used | 0.15 mm track / 0.15 mm clearance, via 0.7 mm / 0.3 mm drill |
| Drill sizes present | 0.8 mm, 1.0 mm, 1.1 mm (39 plated holes, 4 vias) |
| Non-plated holes | none |
| Solder mask / silkscreen | as ordered (see `gerber/`) |
| Stencil | not ordered (THT assembly) |
| Qty / lead time / cost | _fill in from your order confirmation_ |
Fabrication files:
- `gerber/esp-sensair.zip` — Gerber X2 plot + drill files, ready to upload
- `gerber/esp+sensair-job.gbrjob` — Gerber job / stackup description
> **Note on the job file:** the v1 project was started from a 4-layer KiCad stackup, so
> `esp+sensair-job.gbrjob` declares `LayerNumber: 4` and labels the copper layers `L1`/`L4` even
> though only the outer layers are used. The board was fabricated correctly as a 2-layer board.
> For the next revision: set the stackup to 2 layers in *Board Setup → Stackup* before exporting,
> so the job file is self-consistent for anyone re-ordering the board.
## Assembly
All parts are through-hole or plug-in modules on pin headers; hand soldered with a soldering iron.
The Sensirion S8 requires a 5 V supply (its NDIR heater draws current pulses of up to ~150 mA) and
about 30 s of preheat time before it reports valid CO₂ values.
## Firmware
ESPHome, see [`firmware/`](firmware/) for the config and the Home Assistant wiring.
S8 UART: 9600 baud, 8N1. BME280 I²C: standard address `0x76` (or `0x77` depending on the breakout).
## Known issues and lessons learned (v1 → v2)
1. **No copper pours.** Neither layer has a ground plane. v2: solid GND pour on the bottom layer
with stitching vias around the ESP32-C3 module.
2. **No mounting holes.** The board is held by its connectors only. v2: four M2.5 holes.
3. **No I²C pull-ups populated.** The design relies on the pull-ups of the BME280 breakout.
v2: add 4.7 kΩ pull-up footprints on `SDA`/`SCL`.
4. **Single 100 nF decoupling capacitor** for the whole board. v2: 100 nF per supply pin plus a
10–100 µF bulk capacitor close to the S8 heater supply, which is the actual current-pulse source.
5. **Schematic is not annotated** (references `U`, `U`, `U`), so KiCad BOM export is unusable.
v2: annotate, set MPNs, and export the BOM from the schematic.
6. **Leaded HASL** is not RoHS-compliant. v2: HASL lead-free, and ENIG for any impedance-controlled
design.
7. **Project name contains `+`.** It propagates into the Gerber file names (`esp+sensair-Front.gbr`),
which some fabricator upload portals and drill parsers reject. v2: `esp-sensair`.
8. **Antenna keep-out** for the ESP32-C3 module should be checked explicitly against the module
datasheet (no copper, no silkscreen, no vias under the antenna area).
## Repository layout
```
.
├── esp+sensair.kicad_pro KiCad project
├── esp+sensair.kicad_sch schematic
├── esp+sensair.kicad_pcb board layout
├── esp_sensair_stuff.kicad_sym custom symbols (ESP32-C3, Sensirion S8, BME280)
├── esp_sensair_stuff.pretty/ custom footprints, drawn from component datasheets
├── fp-lib-table project-local footprint library table (${KIPRJMOD})
├── gerber/ Gerber X2, Excellon drills, job file, ready-to-upload zip
├── bom/ bill of materials (CSV)
├── docs/ schematic PDF, layer plots, 3D render
├── firmware/ ESPHome configuration
├── photos/ photographs of the assembled board
├── LICENSE CERN-OHL-S-2.0 (hardware)
└── LICENSE.MIT MIT (firmware config, BOM, docs)
```
## Rebuilding the board
1. Open `esp+sensair.kicad_pro` in KiCad 10.
2. Run DRC; fix anything you change.
3. Export Gerbers/drill (the settings are stored in the project) and upload `gerber/*.zip` to your
fabricator with the parameters from the fabrication table.
4. Order parts per BOM, solder through-hole parts and pin headers.
5. Flash the ESPHome configuration and add the device to Home Assistant.
## License
Dual licensed, SPDX identifiers:
| Scope | Licence | File |
|---|---|---|
| Hardware: schematic, layout, symbols, footprints, fabrication data | **CERN-OHL-S-2.0** (CERN Open Hardware Licence v2, strongly reciprocal) | [`LICENSE`](LICENSE) |
| Firmware configuration, BOM, scripts, documentation | **MIT** | [`LICENSE.MIT`](LICENSE.MIT) |
SPDX notices to keep in derived files:
```
SPDX-License-Identifier: CERN-OHL-S-2.0
SPDX-FileCopyrightText: 2026 Hannes Gehrmann
```
Making a board from these files and distributing it is explicitly allowed; if you modify the design
and convey it, CERN-OHL-S requires you to publish the modified design under the same licence and to
mark what you changed (sections 3.2 and 3.3).