feat(uno-q): expose participant files to the agent + document mux scan

- Mount each student's own App Lab files into the app container so the
  agent can read/fix them: mount-user-workspace.sh binds ~/sketches (rw),
  ~/ArduinoApps/* (rw), ~/Arduino/libraries (ro) under /app/workspace via
  a root oneshot ordered before arduino-app-cli.service (the /app bind is
  rprivate, so binds must precede container start; App Lab has no app.yaml
  volumes field). Wired into provision-node-app, provision-fleet (systemd,
  best-effort sudo), and package-onboard-app (bundled under host-setup/).
- uno-q-hardware skill: document the mux-aware i2c_scan output format
  (0x70:mux, 0x70.2=0x1d) and tell the agent its student's files live at
  /app/workspace. See USER-WORKSPACE.md.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Omar Sobh
2026-07-23 16:35:17 -07:00
co-authored by Claude Opus 4.8
parent a9a5176f7c
commit 0156f97b36
7 changed files with 263 additions and 0 deletions
@@ -32,6 +32,42 @@ Sketches always target the MCU (`arduino:zephyr:unoq`).
- `analogRead()` returns 01023; volts = `raw * 3.3 / 1023.0`.
- For a 5 V sensor, divide down: 5 V → 10 kΩ → A0 → 20 kΩ → GND.
## Checking sensors — the `i2c_scan` tool (mux-aware)
To see what's wired to the board's I2C, call **`i2c_scan`**. It probes the MCU's
Arduino Wire bus (Qwiic + I2C headers) — this is where student sensors hang, NOT
Linux `/dev/i2c-*` (those are MPU-side and unreachable from the app container).
The APESS kit hangs its ADXL355s behind a **PCA9548A I2C mux at `0x70`**, and two
sensors can share address `0x1d` on different channels — so the scan walks the mux
too. Read the comma-separated result like this:
- `0x1d` — a device directly on the bus (e.g. a lone ADXL355 wired to Qwiic).
- `0x70:mux` — an I2C mux is present at `0x70`.
- `0x70.2=0x1d` — a device at `0x1d` behind mux `0x70` on **channel 2**.
- `none` — nothing ACKed.
So `0x70:mux,0x70.2=0x1d,0x70.5=0x1d` = the mux plus two ADXL355s, one on channel 2
and one on channel 5. If a student sees only `0x70:mux`, their sensors aren't wired
to the mux channels (or aren't powered) — a mux with nothing behind it. If they see
nothing at all, check power and SDA/SCL. **ADXL355** = `0x1d` (or `0x1e` if ADDR is
pulled high); the FabLab kit reads it at `0x1d`.
## The student's own files — help fix their implementation
The participant's Arduino work is mounted into this container under **`/app/workspace/`**:
- `/app/workspace/sketches/<name>/<name>.ino` — sketches they wrote in App Lab's
sketch editor (this is where most implementations live).
- `/app/workspace/apps/<name>/` — full App Lab apps they built.
- `/app/workspace/libraries/` — installed Arduino libraries (read-only reference).
Read these to review, correct, and complete a student's code when they ask for help
("why doesn't my sensor read?", "fix my sketch"). You can edit files under
`sketches/` and `apps/`; `libraries/` is reference only. If `/app/workspace/` is
empty, the workspace mounts aren't set up on this board yet — say so rather than
guessing at their code.
## On-board LEDs
- RGB LED 1/2 are MPU-owned (`/sys/class/leds/*`, use the `sysfs_led` tool).