Add embedded device library registry with full lifecycle management, automated test integration, and pin assignment workflow. Library system: - Library registry embedded in binary via include_dir! (same as templates) - library.toml metadata format: name, version, bus type, pins, provided files - anvil add <name> extracts headers to lib/drivers/<name>/, test files to test/ - anvil remove <name> cleans up all files, config entries, and include paths - anvil lib lists installed libraries with status - anvil lib --available shows registry with student-friendly wiring summary - [libraries] section in .anvil.toml tracks installed libraries and versions - CMake auto-discovers lib/drivers/*/ for include paths at configure time TMP36 analog temperature sensor (reference implementation): - TempSensor abstract interface (readCelsius/readFahrenheit/readRaw) - Tmp36Analog: real hardware impl via Hal::analogRead with configurable Vref - Tmp36Mock: programmable values, read counting, no hardware needed - Tmp36Sim: deterministic noise via seeded LCG for repeatable system tests - test_tmp36.cpp: 21 Google Test cases covering mock, analog, sim, polymorphism - TMP36 formula: voltage_mV = raw * Vref_mV / 1024, temp_C = (mV - 500) / 10 Automated test integration: - Library test files (test_*.cpp) route to test/ during extraction - CMakeLists.txt auto-discovers test_*.cpp via GLOB, builds each as own target - anvil remove cleans up test files alongside driver headers - Zero manual CMake editing: add library, run test --clean, tests appear Pin assignment integration: - anvil add <name> --pin A0 does extract + pin assignment in one step - Without --pin, prints step-by-step wiring guidance with copy-paste commands - anvil pin --audit flags installed libraries with unassigned pins - Audit works even with zero existing pin assignments (fixed early-return bug) - LibraryMeta helpers: wiring_summary(), pin_roles(), default_mode() - Bus-aware guidance: analog pins, I2C bus registration, SPI with CS selection UX improvements: - anvil lib --available shows "Needs: 1 analog pin (e.g. A0)" not raw metadata - anvil add prints app code example, test code example, and next step - anvil pin --audit prints exact commands to resolve missing library pins - anvil remove shows test file deletion in output Files added: - libraries/tmp36/library.toml - libraries/tmp36/src/tmp36.h, tmp36_analog.h, tmp36_mock.h, tmp36_sim.h - libraries/tmp36/src/test_tmp36.cpp - src/library/mod.rs Files modified: - src/lib.rs, src/main.rs, src/commands/mod.rs - src/commands/lib.rs (add/remove/list/list_available with --pin support) - src/commands/pin.rs (audit library pin warnings, print_library_pin_warnings) - src/project/config.rs (libraries HashMap field) - templates/basic/test/CMakeLists.txt.tmpl (driver + test auto-discovery) Tests: 254 total (89 unit + 165 integration) - 12 library/mod.rs unit tests (registry, extraction, helpers) - 2 commands/lib.rs unit tests (class name derivation) - 30+ new integration tests covering library lifecycle, pin integration, audit flows, file routing, CMake discovery, config roundtrips, ASCII compliance, polymorphism contracts, and idempotent add/remove cycles
# {{PROJECT_NAME}}
Arduino project generated by [Anvil](https://github.com/nexusworkshops/anvil) v{{ANVIL_VERSION}}.
This project is self-contained. After creation, it only needs `arduino-cli`
in PATH -- the Anvil binary is not required for day-to-day work.
## Quick Start
On **Linux/macOS**:
```bash
./build.sh # compile only (verify)
./upload.sh # compile + upload to board
./upload.sh --monitor # compile, upload, open serial monitor
./monitor.sh # serial monitor (no compile)
./monitor.sh --watch # persistent monitor (reconnects after reset)
./test/run_tests.sh # host-side unit tests (no board needed)
```
On **Windows**:
```bat
build REM compile only
upload REM compile + upload
upload --monitor REM compile, upload, open serial monitor
monitor REM serial monitor
test\run_tests REM host-side unit tests
```
All scripts read settings from `.anvil.toml` and port config from
`.anvil.local` (if present).
## Selecting a Board
The scripts auto-detect your board when you run `upload` or `monitor`.
To save a specific device so it persists across sessions:
```bash
anvil devices # see what's connected
anvil devices --set COM3 # save that port (also captures VID:PID)
anvil devices --get # check what's saved
```
This writes `.anvil.local`, which is gitignored. Each machine keeps its own.
The VID:PID is captured automatically so the scripts can find your device
even if the COM port number changes after a replug.
## Project Structure
```
{{PROJECT_NAME}}/
{{PROJECT_NAME}}/
{{PROJECT_NAME}}.ino Entry point (setup + loop)
lib/
hal/
hal.h Hardware abstraction interface
hal_arduino.h Real hardware implementation
app/
{{PROJECT_NAME}}_app.h Application logic (testable)
test/
mocks/
mock_hal.h Google Mock HAL
sim_hal.h Stateful simulator HAL
test_unit.cpp Unit tests
CMakeLists.txt Test build system
run_tests.sh / .bat Test runner
build.sh / build.bat Compile sketch
upload.sh / upload.bat Compile + upload to board
monitor.sh / monitor.bat Serial monitor
_detect_port.ps1 Port detection helper (Windows)
.anvil.toml Project config (tracked by git)
.anvil.local Machine-specific config (gitignored)
```
## Architecture
All hardware access goes through the `Hal` interface. The app code
(`lib/app/`) depends only on `Hal`, never on `Arduino.h` directly.
This means the app can be compiled and tested on the host without
any Arduino hardware.
Two HAL implementations:
- `ArduinoHal` -- passthroughs to real hardware (used in the .ino)
- `MockHal` -- Google Mock for verifying exact call sequences in tests
## Configuration
### .anvil.toml (tracked by git)
Shared project settings:
```toml
[build]
fqbn = "arduino:avr:uno"
warnings = "more"
include_dirs = ["lib/hal", "lib/app"]
extra_flags = ["-Werror"]
[monitor]
baud = 115200
```
### .anvil.local (not tracked by git)
Machine-specific port assignment, created by `anvil devices --set`:
```toml
port = "COM3"
vid_pid = "0403:6001"
```
## Prerequisites
- `arduino-cli` in PATH with `arduino:avr` core installed
- For host tests: `cmake`, `g++` (or `clang++`), `git`
- Install everything at once: `anvil setup`