Add ESPHome firmware templates, GND pour notes, v2 lessons learned

- firmware/: config + secrets templates committed, flashed config git-ignored
- README: document the GND pour on F.Cu/B.Cu and the module keep-out rule areas
- README: correct the calibration button wiring (S8 bCal_in, not an MCU GPIO)
- README: v2 list - dedicated 5 V power input, decoupling, mounting holes,
  I2C pull-ups, schematic annotation, RoHS finish, project name, antenna keep-out
This commit is contained in:
Hannes committed 2026-10-19 22:33:36 +02:00
1 parent 7cf9f71a15
commit ac5a556c11
5 files changed
+187 -38

No files matched your search

+51 -21
View File
@@ -23,20 +23,21 @@ running.
```
+5 V
|
+-------------------------+---------------------------+
| | |
| +----------v----------+ |
| | ESP32-C3 module |--- 3.3 V out --+|
| | (onboard 3V3 LDO) | ||
+--------------+ | ||
| UART 9600 +----------+----------+ ||
| | ||
+-------------------------+
| |
| +----------v----------+
| | ESP32-C3 module |--- 3.3 V out --+
| | (onboard 3V3 LDO) | |
+--------------+ | |
| UART 9600 +----------+----------+ |
| | |
+-----v-------+ +------v-------+ v
| Sensirion S8| | BME280 |<--- I2C (SDA/SCL) --+
| Sensirion S8| | BME280 |<--- I2C (SDA/SCL) -+
| NDIR CO2 | | T / RH / P |
+-------------+ +--------------+
SW1 (calibration button) -- RC debounce (1 k / 100 n) -- ESP32-C3 GPIO
SW1 (calibration button) -- RC (1 k / 100 n) -- Sensirion S8 bCal_in (pin 8)
5 V enters at the ESP32-C3 devkit's USB-C connector and is passed to the S8 via the 5 V net.
```
## Connections
@@ -52,6 +53,10 @@ SW1 (calibration button) -- RC debounce (1 k / 100 n) -- ESP32-C3 GPIO
| `/SCL` | pad 8 | — | pad 3 |
| `bCal_in` | — | pad 8 (`bCal_in`) | — |
The calibration button SW1 is wired to the **S8's own `bCal_in` input**, not to the MCU: pulling
`bCal_in` low starts the sensor's background calibration. C1 (100 nF) and R1 (1 kΩ to GND) form the
debounce/RC network on that line.
Sensirion S8 pins `Alarm_OC`, `PWM_1kHz`, `DVCC_out` and `UART_R/T` are left unconnected.
## Bill of materials
@@ -105,28 +110,53 @@ All parts are through-hole or plug-in modules on pin headers; hand soldered with
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.
## Grounding and copper
Both copper layers carry a **GND copper pour** (one zone on `F.Cu` + `B.Cu`, filled, thermal-relief
connection to pads with 0.5 mm gap, 0.5 mm thermal bridge). Four rule-area keep-outs (pads and
footprints excluded, copper pour allowed) mark the module areas, including the ESP32-C3 antenna
region.
## 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).
ESPHome on `esp32-c3-devkitm-1`, framework **esp-idf**. Config template:
[`firmware/esp-sensair.yaml.example`](firmware/esp-sensair.yaml.example), secrets template:
[`firmware/secrets.yaml.example`](firmware/secrets.yaml.example). The flashed config and
`secrets.yaml` are git-ignored — **never commit live keys.**
| Item | Value |
|---|---|
| I²C | `SDA = GPIO7`, `SCL = GPIO8`, bus scan enabled |
| BME280 | I²C address `0x76`, temperature / pressure / humidity, 60 s interval |
| Sensirion S8 | UART `TX = GPIO21`, `RX = GPIO20`, 9600 baud, 60 s interval |
| Home Assistant | native ESPHome API with noise encryption, OTA updates |
| Network | static IP, `fast_connect`, fallback hotspot + captive portal |
## 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.
1. **Power comes in through the ESP32-C3 devkit's USB-C 5 V pin.** The Sensirion S8 heater draws
current pulses of up to ~150 mA, and that current travels through the module's USB connector, its
5 V rail and its onboard regulator path. v2: a **dedicated 5 V power input** (2.54 mm header,
screw terminal or DC barrel jack) wired straight to the 5 V net, independent of the module's
USB-C, which then stays a programming/debug connection. Add to that: 220–470 µF bulk plus 100 nF
at the S8 supply pins, reverse-polarity protection (series Schottky or P-MOSFET), a jumper to
back-feed 5 V from the module's USB for programming-only setups, and a power-good LED. Before
changing anything: measure the ripple and droop on the 5 V rail with an oscilloscope while the S8
heater fires, so v2 fixes a quantified problem.
2. **Single 100 nF decoupling capacitor** for the whole board. v2: 100 nF per supply pin, bulk
capacitance at each sensor, and supply stitching vias into the ground pour.
3. **No mounting holes.** The board is held by its connectors only. v2: four M2.5 holes.
4. **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).
8. **Antenna keep-out** for the ESP32-C3 module is defined as a rule area (pads and footprints
excluded, copper pour allowed). v2: verify it against the module datasheet's antenna keep-out
figure, and check the pour's clearance to the antenna region specifically.
## Repository layout
@@ -141,7 +171,7 @@ S8 UART: 9600 baud, 8N1. BME280 I²C: standard address `0x76` (or `0x77` dependi
├── 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
├── firmware/ ESPHome config templates, secrets templates, notes
├── photos/ photographs of the assembled board
├── LICENSE CERN-OHL-S-2.0 (hardware)
└── LICENSE.MIT MIT (firmware config, BOM, docs)