Files
anvil/templates/basic
Eric Ratliff 2739d83b99 Add board presets, devices --clear, and test/UX fixes
Board presets:
- anvil new --board mega (uno, mega, nano, nano-old, leonardo, micro)
- anvil new --list-boards shows presets with compatible clones
- FQBN and baud rate flow into .anvil.toml via template variables
- Defaults to uno when --board is omitted

Devices --clear:
- anvil devices --clear deletes .anvil.local, reverts to auto-detect
2026-02-19 07:41:12 -06:00
..
2026-02-18 20:36:57 -06:00

# {{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`