Skip to the content
2 layers80 × 60 mmAtmosmesh room, the printed circuit board in 3D

Atmosmesh room

konih/atmosmesh

ESP32 indoor air-quality station: PM, climate, and a local OLED — headed for MQTT, Home Assistant, and Grafana.

Size
80 × 60 mm
Copper layers
2
Thickness
1.6 mm
Parts
44
Nets
45
Pads
123
Tracks, vias
0, 0
Routed
Not yet
KiCad
KiCad 10.0 (file 20260206)
Created
14 Aug 2026
Updated
2 Nov 2026

Overview

Atmosmesh room is an open-source printed circuit board by konih, from the konih/atmosmesh repository on GitHub, published under the MIT licence. It is a 2-layer board of 80 × 60 mm with 44 parts on 45 nets.

Its parts include 7 capacitors and 1 IC. It belongs with the home automation and IoT and sensors and measurement boards and the ESP32 boards of this library.

README

hardware/kicad/atmosmesh-room/README.md

AtmosMesh Room carrier — provisional design

DO NOT ENERGISE THIS BOARD YET. The controller and every module connector order are now identified, but no supply voltage or output swing has been measured on the 5 V modules. This project is a protected, reviewable starting point, not a wiring approval.

The controller is the ideaspark ESP32 1.14 inch TFT LCD board (ESP32-WROOM-32), confirmed from docs/hardware/ideaspark-esp32-tft-pinout.png. Its 30 pins and their order are therefore no longer provisional: pads 1–15 are the left column and 16–30 the right column, both counted from the USB/button end. What remains unmeasured is the physical row spacing: 25.4 mm is still an assumption, so MEASURE THE ROW SPACING before cutting a socket or committing a hole pattern.

The integrated display is SPI, not I²C. It occupies GPIO23 (MOSI), GPIO18 (SCLK), GPIO15 (CS), GPIO2 (DC), GPIO4 (RST) and GPIO32 (backlight). GPIO21/22 carry no onboard device, so the carrier supplies the only I²C pull-ups it has.

Files

FilePurpose
atmosmesh-room.kicad_proKiCad 10 project; open this file
atmosmesh-room.kicad_schReviewable electrical contract
atmosmesh-room.kicad_pcbParked. Kept only as a netlist/silkscreen cross-check — not the build target
perfboard.mdThe build target: 31×27 hole plan, orientation rules and build order
atmosmesh-room-perfboard-drawing.svgZoomable front, mirrored back and logical wiring planning drawing
atmosmesh-room-perfboard-drawing.pngRendered preview of the planning drawing
validate_room_perfboard.pyDeterministic structural check on the perfboard plan
room.pretty/, fp-lib-table, sym-lib-tableLocal THT library contract
BOM.csvValues, fitting policy and verification notes
wiring.mdConnector contract and staged pre-power checks
validate_room_carrier.pyDeterministic structural safety check
generate_project.pyReproducible project generator; KiCad source remains editable
requirements-generator.txtPinned generator-only Python dependency

Safety architecture

  • ESP32 GPIO and 3V3 must never receive 5 V.
  • Never wire GPIO23, 18, 15, 2, 4 or 32 — the dev board's own TFT drives them. GPIO12 is the flash-voltage strap (high at boot can stop the board starting) and GPIO1/GPIO3 are the CP2102 USB-UART used by task flash and task monitor. generate_project.py refuses to emit a net on any of them and validate_room_carrier.py fails if one appears.
  • GPIO21/SDA and GPIO22/SCL reach the external sensor branch through 330 Ω series resistors. Those resistors limit fault current and damp edges; they are not a measurement noise source.
  • R_PU_SDA and R_PU_SCL (3.3 kΩ to 3.3 V) are the bus pull-ups. They are required because the display is SPI: nothing on the controller board pulls I²C up. They sit on the sensor side of the 330 Ω resistors so the series resistance stays a fault limit rather than part of the pull-up divider. With both breakouts populated the parallel result is roughly 2.0 kΩ, about 1.6 mA at 3.3 V, inside the I²C 3 mA sink limit, so they stay fitted rather than DNP. Every resistor value on this board is justified in wiring.md's sizing table.
  • Both sensors receive direct 3.3 V and local 220 nF decoupling. There is deliberately no diode or resistor in a sensor supply: a breakout's pull-ups reference its own VDD, so dropping sensor VDD drags the pull-ups down with it and buys nothing, while adding a droop path under the SHT41's measurement current bursts. The build uses 100 nF for C1, C3, C4 and C7 — the confirmed ceramic stock value, inside D-022's own 47–220 nF range.
  • The confirmed five-pin VEML7700 connector is VIN, 3Vo, GND, SCL, SDA: VIN receives 3.3 V and 3Vo is regulator output and remains NC.
  • PIR power can come only from a confirmed USB/5 V pin, through JP_PIR_5V which is DEFAULT OPEN, then a 1N5819. PIR OUT drives a 2N3904 through 10 kΩ; GPIO33 sees only the collector and a 10 kΩ pull-up to 3.3 V. Motion logic is active-low.
  • The buzzer is a confirmed Keyes 3-pin module, header order S/VCC/−. GPIO25 drives S directly through R_BEEP_S 100 Ω, active HIGH, exactly as AtmosMesh v1 drives the same part. The low-side NPN and flyback diode are gone because the transducer is self-oscillating inside the can — the breakout PCB carries no parts, so the middle VCC pin is a no-op and GPIO25 sources the whole operating current. The evidence is that v1 sounds this part with a bare 50 ms DC digitalWrite(HIGH), which neither a piezo disc nor a passive coil can do. That type is inferred, not measured: one ohmmeter reading across S and − settles it, and R_BEEP_S is never raised — see the table in wiring.md before changing anything.
  • JP_5V_SRC selects where +5V_DOMAIN comes from: the board's VIN (pins 1–2) or an external bench supply on J_5V_EXT (pins 2–3). A 3-pin header takes exactly one shunt, so the two sources can never be bridged back into the host's USB port. Use the external, current-limited supply for first power-up and whenever the SDS011 fan runs.
  • The SDS011 takes 5 V through JP_SDS_5V, DEFAULT OPEN, with no series diode: its minimum is 4.7 V and a Schottky at fan current drops below that. Its UART is crossed — sensor TXD to GPIO16/RX2, GPIO17/TX2 to sensor RXD — each through a 1 kΩ series resistor that bounds a driver fight to about 3.3 mA. The generator refuses both a straight-through UART and a diode on that rail.
  • Three indicator LEDs show which domains are live. D_LED_SDS and D_LED_PIR draw through their own default-open jumpers, so a lit LED is direct evidence that the jumper it reports on is closed. Use red or green: a blue or white LED's ~3.0 V forward drop leaves too little across R_LED_3V3 on the 3.3 V rail.
  • No Zener clamp is used. This is now positively evidenced rather than assumed: the Zener assortment in docs/elektronik-inventar.md is the 1N47xx series starting at 1N4733 = 5.1 V, which clamps far too late to protect a 3.3 V GPIO. A 3.3 V part (1N4728) is not held.

The build target is perfboard

The operator builds this by hand on a 31 × 27 hole perfboard, so no board is fabricated. The schematic is the electrical contract and perfboard.md is the build plan.

atmosmesh-room.kicad_pcb is parked: it is still generated from the netlist and still carries the safety silkscreen, which is why its checks remain in validate_room_carrier.py, but its placement is not maintained as a fabrication candidate. Do not order it.

Placement and routing state

The VEML7700 sits at a board edge and must be optically shielded from the TFT backlight. The SHT41 sits at the opposite ventilated edge, away from the ESP32 regulator, PIR electronics and buzzer. The 5 V PIR block is fenced at the right edge. The antenna clearance is marked on User.Drawings and silk; its final copper keepout/overhang cannot be fixed until the exact board orientation is photographed.

Copper is intentionally unrouted because the Ideaspark row spacing and orientation, plus each module connector order, are unverified. This prevents a plausible-looking provisional drawing from being mistaken for a fabrication-ready board. Do not "finish the ratsnest" by assuming a generic ESP32 DevKit image.

The complete net table, double-sided through-hole placement guidance, assembly order, unpowered checks, staged commissioning and stop conditions are in wiring.md.

Validation

From this directory:

sh
python3.12 -m venv .generator-venv
.generator-venv/bin/pip install -r requirements-generator.txt
.generator-venv/bin/python generate_project.py
python3 validate_room_carrier.py
kicad-cli sch erc --severity-all --exit-code-violations \
  -o atmosmesh-room-erc.rpt atmosmesh-room.kicad_sch
kicad-cli pcb drc --severity-all --schematic-parity --refill-zones \
  -o atmosmesh-room-drc.rpt atmosmesh-room.kicad_pcb
kicad-cli sch export pdf -o atmosmesh-room-schematic.pdf atmosmesh-room.kicad_sch

DRC reports the deliberately unrouted nets as unconnected; schematic parity must remain clean and there must be no other DRC violation. Routing stays blocked until the exact physical parts are verified.

Parts

44
QtyValueFootprintReferences
4100nFroom:C_Disc_P5.00mmC1, C3, C4, C7
41kroom:R_Axial_P7.62mmR_LED_PIR, R_LED_SDS, R_SDS_RX, R_SDS_TX
4M3room:MountingHole_3.2mm_M3H1, H2, H3, H4
2100uFroom:C_Radial_P2.00mmC2, C5
210kroom:R_Axial_P7.62mmR_PIR_IN, R_PIR_PU
23.3kroom:R_Axial_P7.62mmR_PU_SCL, R_PU_SDA
2330Rroom:R_Axial_P7.62mmR_SCL, R_SDA
2DEFAULT_OPENroom:Jumper_2_Open_P2.54mmJP_PIR_5V, JP_SDS_5V
1100Rroom:R_Axial_P7.62mmR_BEEP_S
1100kroom:R_Axial_P7.62mmR_PIR_PD
11N5819room:D_Axial_P7.62mmD_PIR
12N3904 C/B/Eroom:TO92_CBEQ_PIR
13V3/GNDroom:TestPoint_2Pin_THTTP_3V3
1470Rroom:R_Axial_P7.62mmR_LED_3V3
1470uFroom:C_Radial_P2.00mmC6
15V/GNDroom:TestPoint_2Pin_THTTP_5V
1DSUN_PIR GND/OUT/VCCroom:PinHeader_1x03_P2.54mmJ_PIR
1EXT 5V IN / GNDroom:PinHeader_1x02_P2.54mmJ_5V_EXT
1GND/GNDroom:TestPoint_2Pin_THTTP_GND
1IDEASPARK_ESP32_1V14_TFT_30PINroom:Ideaspark_30Pin_ProvisionalU1
1KEYES BUZZER S/VCC/-room:PinHeader_1x03_P2.54mmJ_BEEP
1LED PIR 5V LIVEroom:D_Axial_P7.62mmD_LED_PIR
1LED RED 3V3 LIVEroom:D_Axial_P7.62mmD_LED_3V3
1LED SDS 5V LIVEroom:D_Axial_P7.62mmD_LED_SDS
1SCL/GNDroom:TestPoint_2Pin_THTTP_SCL
1SDA/GNDroom:TestPoint_2Pin_THTTP_SDA
1SDS011 5V/GND/RXD/TXDroom:PinHeader_1x04_P2.54mmJ_SDS
1SELECT: 1-2 USB / 2-3 EXTroom:PinHeader_1x03_P2.54mmJP_5V_SRC
1SHT41 VIN/GND/SCL/SDAroom:PinHeader_1x04_P2.54mmJ_SHT
1VEML7700 VIN/3Vo/GND/SCL/SDAroom:PinHeader_1x05_P2.54mmJ_VEML

More from konih/atmosmesh

1
  • 2 layers139 × 58 mmAtmosmesh bench, the printed circuit board in 3D

    Atmosmesh bench

    konih/atmosmesh

    ESP32 indoor air-quality station: PM, climate, and a local OLED — headed for MQTT, Home Assistant, and Grafana.

    29 partsMIT

Similar boards

  • 2 layers78 × 60 mmIce viz, the printed circuit board in 3D

    Ice viz

    muni-works/vcad

    BRep CAD kernel in Rust/WASM

    44 parts442Apache-2.0
  • 2 layers115 × 14.5 mmUFC Function Select, the printed circuit board in 3D

    UFC Function Select

    jrsteensen/OpenHornet

    OpenHornet 1:1 F/A-18C Simulator Repository

    44 parts431
  • 2 layers37.7 × 20 mmCandleLight, the printed circuit board in 3D

    CandleLight

    HubertD/candleLight

    stm32f0 usb can adapter (KiCAD)

    44 parts400
  • 2 layers88.9 × 88.4 mmTeensypi v91, the printed circuit board in 3D

    Teensypi v91

    simondlevy/Hackflight

    Minimalist flight-control toolkit for makers

    44 parts334GPL-3.0
  • 2 layers125 × 98 mm3-in-1, the printed circuit board in 3D

    3-in-1

    mudmin/AnotherMaker

    This is where I will store code snippets for AnotherMaker Videos

    44 parts258
  • 2 layers65 × 56.5 mmRPiG3iMac, the printed circuit board in 3D

    RPiG3iMac

    qbancoffee/imac_g3_ivad_board_init

    iMac G3 IVAD board initialization with an arduino

    44 parts240LGPL-3.0
  • 2 layers54.4 × 49.3 mmFx3 tn20k adapter, the printed circuit board in 3D

    Fx3 tn20k adapter

    Stefan-Olt/MISRC

    MISRC Is a multi channel RF capture device for FM RF, S-Video, CVBS RAW capture and anything else, but intended and supported for the decode family of projects vhs-decode, ld-decode, hifi-decode.

    44 parts236CC-BY-4.0
  • 2 layers250 × 32 mmPsu, the printed circuit board in 3D

    Psu

    shmoergh/moduleur

    Fully analog DIY-friendly modular synth

    44 parts222

Questions

How big is the Atmosmesh room PCB?

It measures 80 × 60 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Atmosmesh room use?

44 parts. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Atmosmesh room KiCad files?

From the konih/atmosmesh repository on GitHub, at the commit this page was made from: the board is hardware/kicad/atmosmesh-room/atmosmesh-room.kicad_pcb and its schematic hardware/kicad/atmosmesh-bench/AtmosmeshAqua/AtmosmeshAqua.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Atmosmesh room design in my own project?

Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).