XIAO ESP32S3 camera web apps — AP (hotspot) mode
The board becomes its own WiFi hotspot. Clients join the board's SSID and the page is ALWAYS at http://192.168.4.1. No router, no internet needed. Best for classrooms: one board per student/team, isolated networks.
Read the xiao-esp32s3 skill (same repo) first for base workflow and pitfalls
(especially: PSRAM flag mandatory, DTR reset-stuck recovery, no serial reads
while a demo must keep running).
Step 1 — ALWAYS ask the user first
Never invent credentials. Ask the user for:
- AP 이름(SSID) — e.g.
XIAO_01. For classroom fleets suggest numbered names (XIAO_01..XIAO_20). - AP 비밀번호 — 8+ chars (WPA2 minimum). If the user wants an open AP, confirm explicitly.
- 채널 (optional, default 1) — for MULTIPLE boards in one room, spread
across 1 / 6 / 11 (board N → channel
[1,6,11][N % 3]); 20 boards all on channel 1 will jam each other. - Which app: collector, inference viewer, or both.
Step 2 — generate the sketch from the template
Templates in assets/ are verified working code — do not rewrite them:
assets/web_collect.ino.tpl— dataset collector (gallery + delete + ZIP download)assets/web_infer.ino.tpl— live inference viewer (needs the<project>_inferencingEdge Impulse library installed in the sketchbook)
Copy the template to <workspace>\<NN>_<name>\<NN>_<name>.ino (folder = ino
name), then replace the placeholders literally:
| Placeholder | Meaning | Example |
|---|---|---|
__AP_SSID__ |
hotspot name | XIAO_01 |
__AP_PASS__ |
hotspot password (8+ chars) | class1234 |
__AP_CHANNEL__ |
WiFi channel (bare number, no quotes) | 6 |
__EI_PROJECT__ |
inference app only — Edge Impulse project name, matching the installed <name>_inferencing library folder |
clfc |
Step 3 — compile, upload
arduino-cli compile --fqbn esp32:esp32:XIAO_ESP32S3 --board-options PSRAM=opi <SKETCH_DIR>
arduino-cli upload -p COM4 --fqbn esp32:esp32:XIAO_ESP32S3 --board-options PSRAM=opi <SKETCH_DIR>
PSRAM=opi is mandatory (camera + model need PSRAM). The inference build
needs --clean if the Edge Impulse library was just swapped.
Step 4 — verify
# the AP should appear in a WiFi scan within ~15 s of flashing
netsh wlan show networks | Select-String "<AP_SSID>"
(netsh caches scans — retry after 20 s before concluding failure.)
This check needs a WiFi adapter on the PC, and many desktops do not have
one. If netsh wlan show interfaces reports that the Wireless AutoConfig
service is not running, or Get-NetAdapter lists only Ethernet, no amount of
retrying will show the AP — the machine physically cannot scan. Do not read
that as a failed flash. Fall back to serial (below), or have the user check
from their phone.
Watching the board over serial
In AP mode the PC usually cannot reach the board at all, so serial is often
the only verification available to you. Use the xiao-serial-monitor skill.
mon # interactive, port auto-detected
.\scripts\mon.ps1 -Seconds 15 # bounded, for your own debugging
Expected on success:
AP started. Open http://192.168.4.1
Collector ready
Camera init failed instead means the sketch halts before ever starting the
AP — the board is a plain XIAO ESP32S3 without the Sense camera module, or the
module is not seated. Scanning for the SSID forever will never reveal this;
one serial read does.
Two things worth knowing rather than avoiding:
- Opening the port resets the board via DTR, so the log restarts from boot. That is what you want here — these lines only print once at startup.
- If a board ends up stuck showing only the ROM banner afterwards
(pitfall 8 of
xiao-esp32s3), re-runningarduino-cli uploadclears it, and leaves the sketch running for the demo.
When the user wants to watch it themselves, hand them the command rather than
launching the interactive monitor from a tool call — it never returns. In
Claude Code the ! prefix runs it in their session:
! <path>\mon.ps1
Full check: connect a device to the AP and open http://192.168.4.1 — tell the user connecting from THEIR phone/PC will drop that device's internet while connected; that is expected in AP mode.
Notes
- Collector page: captures go to an in-browser gallery (label badges, per-shot
delete, "전체 ZIP 다운로드" produces
label.N.jpgfiles ready for Edge Impulse). Refreshing the page clears the gallery — download the ZIP first. - Inference page: whole-frame colored box + top label + per-class confidence bars (classification model — per-object location boxes need a FOMO model).
- The camera renders rotated 90°; the inference template already compensates (CW feature rotation, verified empirically).