From 8638ca56b149d655806ff1abfa8745fd494bc8a2 Mon Sep 17 00:00:00 2001
From: cocvn157 <120394358+cocvn157@users.noreply.github.com>
Date: Tue, 3 Nov 2026 23:09:18 +0700
Subject: [PATCH] docs(tutorials): add Designing an ESP32 WiFi Test Board
schematic tutorial (#886)
---
...wifi-test-board.circuit-schematic.snap.svg | 12 +
.../esp32-wifi-test-board.circuit.tsx | 566 +++++++++++++++
.../esp32-wifi-test-board-schematic.mdx | 642 ++++++++++++++++++
3 files changed, 1220 insertions(+)
create mode 100644 codetestingplayground/__snapshots__/esp32-wifi-test-board.circuit-schematic.snap.svg
create mode 100644 codetestingplayground/esp32-wifi-test-board.circuit.tsx
create mode 100644 docs/tutorials/esp32-wifi-test-board-schematic.mdx
diff --git a/codetestingplayground/__snapshots__/esp32-wifi-test-board.circuit-schematic.snap.svg b/codetestingplayground/__snapshots__/esp32-wifi-test-board.circuit-schematic.snap.svg
new file mode 100644
index 00000000..96cbd5e1
--- /dev/null
+++ b/codetestingplayground/__snapshots__/esp32-wifi-test-board.circuit-schematic.snap.svg
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/codetestingplayground/esp32-wifi-test-board.circuit.tsx b/codetestingplayground/esp32-wifi-test-board.circuit.tsx
new file mode 100644
index 00000000..41020155
--- /dev/null
+++ b/codetestingplayground/esp32-wifi-test-board.circuit.tsx
@@ -0,0 +1,566 @@
+import { SmdUsbC } from "@tsci/seveibar.smd-usb-c"
+
+const cp2102PinLabels = {
+ pin1: "DCD",
+ pin2: "RI",
+ pin3: "GND",
+ pin4: "D_PLUS",
+ pin5: "D_MINUS",
+ pin6: "VDD",
+ pin7: "REGIN",
+ pin8: "VBUS",
+ pin9: "RST",
+ pin10: "NC1",
+ pin11: "SUSPENDb",
+ pin12: "SUSPEND",
+ pin13: "NC2",
+ pin14: "NC3",
+ pin15: "NC4",
+ pin16: "NC5",
+ pin17: "NC6",
+ pin18: "NC7",
+ pin19: "NC8",
+ pin20: "NC9",
+ pin21: "NC10",
+ pin22: "NC11",
+ pin23: "CTS",
+ pin24: "RTS",
+ pin25: "RXD",
+ pin26: "TXD",
+ pin27: "DSR",
+ pin28: "DTR",
+ pin29: "PGND",
+}
+
+const esp32PinLabels = {
+ pin1: "GND",
+ pin2: "3V3",
+ pin3: "EN",
+ pin4: "SENSOR_VP",
+ pin5: "SENSOR_VN",
+ pin6: "IO34",
+ pin7: "IO35",
+ pin8: "IO32",
+ pin9: "IO33",
+ pin10: "IO25",
+ pin11: "IO26",
+ pin12: "IO27",
+ pin13: "IO14",
+ pin14: "IO12",
+ pin15: "GND",
+ pin16: "IO13",
+ pin17: "SD2",
+ pin18: "SD3",
+ pin19: "CMD",
+ pin20: "CLK",
+ pin21: "SD0",
+ pin22: "SD1",
+ pin23: "IO15",
+ pin24: "IO2",
+ pin25: "IO0",
+ pin26: "IO4",
+ pin27: "IO16",
+ pin28: "IO17",
+ pin29: "IO5",
+ pin30: "IO18",
+ pin31: "IO19",
+ pin32: "NC",
+ pin33: "IO21",
+ pin34: "RXD0",
+ pin35: "TXD0",
+ pin36: "IO22",
+ pin37: "IO23",
+ pin38: "GND",
+}
+
+const jlc = (part: string) => ({ jlcpcb: [part] })
+
+const ledPinLabels = {
+ pin1: ["anode", "pos"],
+ pin2: ["cathode", "neg"],
+}
+
+const DeterministicTrace = (props: { from: string; to: string }) => (
+
+)
+
+export default () => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+)
diff --git a/docs/tutorials/esp32-wifi-test-board-schematic.mdx b/docs/tutorials/esp32-wifi-test-board-schematic.mdx
new file mode 100644
index 00000000..2baa82d6
--- /dev/null
+++ b/docs/tutorials/esp32-wifi-test-board-schematic.mdx
@@ -0,0 +1,642 @@
+---
+title: Designing an ESP32 WiFi Test Board
+description: >-
+ Build a schematic-first ESP32-WROOM-32E test board with a real USB-C sink,
+ correct CC pull-downs, a CP2102N USB-UART bridge, and Espressif's
+ cross-coupled DTR/RTS auto-program circuit.
+---
+
+import CircuitPreview from "@site/src/components/CircuitPreview"
+
+## Overview
+
+This tutorial builds a schematic-only ESP32 WiFi test board. It is a complete
+reference design for bringing up USB power, USB data, UART programming, and the
+ESP32 module. The source uses repository-supported tscircuit components and exact
+JLCPCB assembly references, but it does not claim a routed PCB or fabrication
+release.
+
+The board is centered on an ESP32-WROOM-32E-N4 module (JLCPCB `C701341`), a
+CP2102N-A02-GQFN28R bridge (`C964632`), and a TYPE-C-31-M-12 USB-C receptacle
+(`C165948`). Every major component has an explicit JLCPCB part number in the
+source so the schematic can be turned into a real prototype without replacing
+placeholder parts.
+
+The live schematic is generated from the same topology as
+`codetestingplayground/esp32-wifi-test-board.circuit.tsx`:
+
+ ({ jlcpcb: [part] })
+
+const ledPinLabels = {
+ pin1: ["anode", "pos"],
+ pin2: ["cathode", "neg"],
+}
+
+const DeterministicTrace = (props: { from: string; to: string }) => (
+
+)
+
+export default () => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+)
+`} />
+
+## USB-C power input
+
+`SmdUsbC` models the C165948 16-pad USB-C receptacle, including the duplicate
+VBUS, ground, and USB 2.0 data pads. `VBUS1` and `VBUS2` feed the same 5 V
+net, `GND1` and `GND2` feed ground, and `DP1`/`DP2` and `DM1`/`DM2` are each
+joined before reaching the CP2102N.
+
+A USB-C sink must advertise its power capability on both CC lines. R1 and R2
+are independent 5.1 kΩ Rd pull-downs to ground: one from `CC1` and one from
+`CC2`. They are not a single resistor across the two pins. The selected
+0402 resistor is JLCPCB `C25905`.
+
+## Power and USB-UART
+
+The 5 V rail enters the AMS1117-3.3 (`C6186`) through C1. C2 and C3 provide
+the regulator output bulk and high-frequency decoupling. The CP2102N's `REGIN`
+and `VBUS` pins see 5 V, while `VDD` is supplied from the 3.3 V rail. CP2102N
+`TXD` connects to ESP32 `RXD0`, and CP2102N `RXD` connects to ESP32 `TXD0`.
+
+The USB data pins are connected as a differential pair. The design does not
+pretend that a four-pin USB symbol is a USB-C receptacle: the actual connector
+component carries all USB-C pads and the CC pins.
+
+## Espressif auto-program circuit
+
+The auto-program network follows the cross-coupled two-transistor arrangement
+used by Espressif development boards:
+
+- `DTR` drives Q1's base through R3 and Q2's emitter.
+- `RTS` drives Q2's base through R4 and Q1's emitter.
+- Q1's collector pulls `EN` low.
+- Q2's collector pulls `IO0` low.
+
+This topology matters. Merely connecting DTR and RTS to the two ESP32 pins does
+not provide the same behavior when both modem-control lines are asserted. The
+cross-coupled pair produces the useful states:
+
+| DTR | RTS | EN | IO0 |
+| --- | --- | --- | --- |
+| 1 | 1 | 1 | 1 |
+| 0 | 0 | 1 | 1 |
+| 1 | 0 | 0 | 1 |
+| 0 | 1 | 1 | 0 |
+
+R5 and C5 provide the EN pull-up and reset capacitor. R6 and SW1 provide the
+IO0 pull-up and BOOT button, while SW2 is the manual reset button. The 1 µF EN
+capacitor is intentional: Espressif documents it as necessary for reliable
+automatic reset with the transistor network.
+
+## ESP32 module and indicators
+
+The ESP32-WROOM-32E-N4 uses the real `jlcpcb:C701341` footprint. Power,
+ground, EN, IO0, and UART0 are wired; unused module pins are explicitly marked
+no-connect. IO4 drives the green status LED through R7, avoiding a load on the
+IO2 strapping pin. The red power LED is driven from 3.3 V through R8.
+
+The source also gives every passive and button its exact JLCPCB part number and
+`jlcpcb:` footprint, and names all USB data nets. The checked-in schematic SVG is
+the only generated artifact.
+
+## Build and snapshot
+
+From `codetestingplayground`, run:
+
+```bash
+bunx tsci build esp32-wifi-test-board.circuit.tsx
+bunx tsci snapshot esp32-wifi-test-board.circuit.tsx
+```
+
+`tsci snapshot` writes `__snapshots__/esp32-wifi-test-board.circuit-schematic.snap.svg`,
+the one generated artifact checked in with this tutorial. The source gives traces
+deterministic names and declares logical pin labels so schematic rebuilds stay
+comparable. The autorouter and DRC can fail on a schematic-only source, so use
+`bunx tsci build --ignore-errors` to skip those non-fatal PCB checks. Before
+creating a PCB, route and inspect it, verify the USB-C footprint and antenna
+keepout, and confirm the selected JLC parts are currently in stock.