Files
diy-layout-creator/diylc/docs/plans/maker-board-roadmap.md
T
Bane Stojkovic 89ce96b6c8 Controllers (#1068)
* initial

* more components

* fixes

* Update TreePanel.java

* fix boost converter

* Improve wrapping of component names

* Update ULN2003Driver.java

* Update NRF24L01Transceiver.java

* imp

* updates

* improvements

* more components

* arduino

* uno

* icon

* cleanup

* mega

* mega

* improveent

* nano

* esp boards

* esp

* esp32

* esp32

* Update ESP8266NodeMCU.java

* d1

* Update WemosD1Mini.java

* pi

* consolidate esp32

* pi pico updates

* pi zero

* Update RaspberryPiZero.java

* pi pico

* cleanup

* pi improvements

* consolidate pins

* antenna consolidation

* improve solder pads

* teensy

* headers

* teensy fix, test cleanup

* s3

* Update ESP32DevKit.java

* usb standardization

* pico w

* button standardization

* arduino improvements

* Update AbstractMakerBoard.java

* Update RaspberryPiZero.java

* Update RaspberryPi.java

* pi 3

* pi 5 improvements

* Update RaspberryPiZero.java

* fix tests

* esp pinout fix

* Update ESP32DevKit.java

* pin name improvements

* Create tier-1-modern-boards.md

* new versions

* pinouts

* nano improvements

* sanitize node names

* label improvements

* minima fixes

* arduino uno labels

* nano labels

* Update ArduinoNano.java

* mega

* mega

* comment out future stuff

* release prep

* Update RaspberryPiPico.java

* Refactor abstract class

* labeling improvement

* label offset fixes

* Update Teensy.java

* consolidate tests

* micro variants

* Update RaspberryPi.java
2026-09-11 11:08:15 +02:00

27 KiB
Raw Blame History

clau# Maker Board Roadmap

Closing the gap between org.diylc.components.micro and what people building with microcontroller boards today actually reach for.

Status: proposed Scope: diylc-library, package org.diylc.components.micro Supersedes: tier-1-modern-boards.md

1. Goal

The micro package models 10 board classes across roughly 16 selectable variants. The scaffolding in AbstractMakerBoard — USB connector types, PCB meander antenna, castellated and through-hole pads, terminal blocks, FPC connectors, mounting holes, vendor logos — is complete enough that adding a board is mostly pin arrays and a draw branch. The expensive part is already paid for.

This document inventories what is modelled, lists what a modern maker cannot draw today, and sorts the additions into three tiers by how often their absence would actually block someone.

2. Decisions that govern this roadmap

# Decision Choice Rationale
D1 How coverage grows Named boards, drawn faithfully. No generic/parametric "configurable dev board" component. A parametric board would cover more of the long tail per hour, but the palette entry a maker searches for is the product name, and accurate silk/connectors/logos are the point of these components. One was built and reverted; the question is settled.
D2 New class vs. new Version constant Form factor decides. Same outline and pin positions → append a Version enum constant. Different footprint → new class. Already the established paradigm (ArduinoUno, RaspberryPiPico, RaspberryPiZero, ESP32DevKit). Keeps the palette short without forcing unrelated geometry into one draw method.
D3 Where pin data lives Hardcoded String[] arrays in the component class. Matches every existing board. An external pin-definition resource and per-pin type metadata (POWER_5V, GND, ADC, I2C_SDA…) were both considered and declined; no pin-data infrastructure is introduced here.
D4 Package boundary micro only. Adjacent gaps (Qwiic/STEMMA QT/Grove connectors, shields and HATs, stackable headers) are real but belong to connectivity / electromechanical and are out of scope for this document.
D5 Backward compatibility Append-only enums, unchanged defaults, unchanged control-point counts for existing variants. .diy files are a public contract; see §4.3. No file-format migration is needed anywhere in this roadmap.

Explicitly out of scope

  • A configurable catch-all board component (D1).
  • Pin-type metadata and any electrical rule check built on it (D3).
  • Shields, HATs, stacking, and the Qwiic/STEMMA QT/Grove connector family (D4).
  • Bumping the project version, packaging, and the deployment build.

3. Current coverage

Class Variants Notes
ArduinoUno R3, R4 WiFi, R4 Minima, Leonardo
ArduinoMega —
ArduinoNano classic, Every, 33 IoT, 33 BLE, 33 BLE Sense, RP2040 Connect, Nano ESP32
ESP32DevKit V1 30-pin, DevKitC V4 38-pin, S3 DevKitC-1 44-pin, C3 DevKitM-1 30-pin, C6 DevKitC-1 32-pin per-version pin arrays, geometry and draw branches
ESP8266NodeMCU —
WemosD1Mini — hardcodes SILK_PIN_NAMES_LEFT/RIGHT instead of drawPinLabels
RaspberryPi 3B+, 4B, 5
RaspberryPiZero Zero, Zero W, Zero 2 W
RaspberryPiPico Pico, Pico W, Pico 2, Pico 2 W castellated pad rendering
Teensy 4.0, 4.1, Teensy 3.2

Variants in bold landed with this roadmap; everything in §5.1 and §5.2 is now done. All ten are category = "Controllers", bomPolicy = SHOW_ONLY_TYPE_NAME, enableCache = true, and extend AbstractMakerBoard.

4. Shared mechanics

Applies to every item in every tier.

4.1 Component discovery

Components are found by classpath annotation scan in ComponentProcessor.getComponentTypes() (Reflections, TypesAnnotated, includePackage("org.diylc.components")). Any class carrying @ComponentDescriptor is picked up automatically — there is no manifest or registry to edit. Adding enum constants to an existing class needs nothing. Adding a new class needs nothing for discovery, but should be added to the hand-maintained list in org.diylc.components.maker.MakerComponentsTest#allMakerComponentClasses.

4.2 Version property pattern

public enum XxxVersion { A("Label A"), B("Label B"); ... toString() returns label; }

protected XxxVersion version = XxxVersion.A;          // default initializer

@EditableProperty(name = "Version")
public XxxVersion getVersion() {
  if (version == null) version = XxxVersion.A;        // null-guard for old files
  return version;
}
public void setVersion(XxxVersion version) {
  this.version = version;
  updateControlPoints();                              // only if geometry changes
  invalidateCache();                                  // required: enableCache = true
}

XStream serializes enum constants by name — .diy files contain <orientation>_90</orientation> and the like, and no custom enum converter is registered — so adding constants and reordering them are both backward compatible. Removing or renaming one is not. Ordinals are used only by the rotation transformers (Orientation, OrientationHV, Orientation45), never by a Version enum, so a version enum may be sorted for a tidy drop-down; ArduinoNano.NanoVersion is ordered by label for exactly that reason. Keep the default constant and the null-guard so existing files deserialize unchanged.

4.3 Serialization safety checklist (per changed class)

  • serialVersionUID stays 1L.
  • The default version field value is unchanged, so old files keep their look.
  • Control-point count must not change for existing variants. If a new variant has a different pin count, updateControlPoints() must size the array from the per-version pin list (as ESP32DevKit already does), and any code assuming a fixed PIN_NAMES.length must switch on version.
  • drawIcon() reflects only the default variant — leave it alone unless the default changes.

4.4 Test pattern

Each board has a *Test.java under diylc-library/src/test/java/org/diylc/components/micro/:

  • testControlPointCountAndNames() — count, every name non-empty, spot checks
  • testDimensionsAndPinGeometry() — getBodyShape().getBounds2D() against expected mm, and control-point offsets from board edges
  • testVersionProperty() — default, toString() labels, round-trip through the setter
  • a *Drawing smoke test — draw() in NORMAL / SELECTED / outline, headers on and off, against a BufferedImage with a no-op IDrawingObserver

Extend these in place; add one geometry test and one draw smoke test per new variant.

4.5 Sourcing dimensions and pin names

Every dimension constant and every pin array below must be cross-checked against vendor documentation before it is committed. Where this document states a size or a pin count without naming a source, it is an estimate to scope the work, not a datasheet citation.

What actually works as a source:

  • Arduino — docs.arduino.cc/resources/pinouts/<SKU>-full-pinout.pdf is canonical for PWM tildes and silkscreen names; docs.arduino.cc/resources/datasheets/<SKU>-datasheet.pdf carries the numbered header tables. The HTML product and cheat-sheet pages render client-side and yield nothing to a fetch.
  • Espressif — the esp-dev-kits user guides carry complete J1/J3 header tables as HTML.
  • PJRC — pinout cards, not yet used for the Teensy 3.2 bottom cluster (see §5.1 item 4).

Note that these PDFs need downloading and text extraction; a plain fetch returns binary. Do not assume variants of one board share a pinout — across the Nano family the PWM sets, the bus annotations and the power pins all differ per variant.

4.6 Build and verify

cd diylc
mvn -pl diylc-library -am test

Rendering-regression fixtures live in ../diylc-regression-data/ but are not wired into the library test run, so new variants do not break it. When those baselines are next regenerated, add sample placements for the new variants.


5. Tier 1

Boards a maker is very likely to reach for and cannot draw today.

5.1 Enum appends to existing classes — done

The cheapest fidelity wins in the whole roadmap — the geometry is already correct, so each is a pin array, a silk label and a few draw branches.

# Board Host class Change
1 Raspberry Pi Pico 2 / Pico 2 W (RP2350) RaspberryPiPico 2 constants
2 Raspberry Pi Zero 2 W RaspberryPiZero 1 constant
3 Arduino Uno R4 Minima ArduinoUno 1 constant
4 Teensy 3.2 Teensy 1 constant + pin array
5 Arduino Leonardo ArduinoUno 1 constant + pin array

Item 1 — Pico 2 / Pico 2 W. The Pico 2 is pin-, size- and connector-identical to the Pico (21 × 51 mm, 2×20 castellated plus through-hole, 3-pad SWD, micro-USB, BOOTSEL). The visible differences: the SoC silk reads RP2350 instead of RP2040, and Pico 2 W carries the same Infineon CYW43439 radio in the same position as Pico W, so its 3-pad SWD block sits at the Pico W offset.

  1. PicoVersion: append PICO_2("Pi Pico 2"), PICO_2_W("Pi Pico 2 W").
  2. Add helpers so the existing checks stay readable:
    private boolean isW()  { return version == PicoVersion.PICO_W || version == PicoVersion.PICO_2_W; }
    private boolean isV2() { return version == PicoVersion.PICO_2 || version == PicoVersion.PICO_2_W; }
    
  3. In updateControlPoints(), getBodyShape(), drawCastellatedPads() and draw(), replace getVersion() == PicoVersion.PICO_W with isW().
  4. The chip label becomes isV2() ? "RP2350" : "RP2040".
  5. PIN_NAMES is unchanged and shared across all four variants.
  6. drawIcon() unchanged (default is still PICO).

Tests: extend testVersionProperty(); add testPico2GeometryMatchesPico() asserting identical body bounds and control-point count for PICO/PICO_2 and PICO_W/PICO_2_W; draw smoke test for PICO_2_W. ~2–3 h, minimal risk.

Item 2 — Pi Zero 2 W. Identical 65 × 30 mm outline, identical 40-pin GPIO position, identical connector layout (mini-HDMI, 2× micro-USB, CSI FPC on the right edge, 4 mounting holes). The SoC is the RP3A0 package-on-package with integrated radio — physically a ~12 mm square where the drawing already places a 12 mm chip. Silk and label only.

  1. ZeroVersion: append PI_ZERO_2_W("Pi Zero 2 W").
  2. No geometry change; pin arrays untouched.
  3. draw() already prints "Raspberry " + getVersion() — verify the longer string still fits inside hdrBoxW; if not, drop to SILK_FONT or print getVersion().toString() alone for this case.
  4. Optional cosmetic touch: draw the SoC as a plain dark PoP square with no Broadcom split.

Tests: extend testVersionProperty(); geometry-equivalence assertion against PI_ZERO_W; draw smoke test. ~1–2 h, minimal risk — only watch the label width.

Item 3 — Uno R4 Minima. ArduinoUno models R3 and R4 WiFi but not the Minima, which shares the R4 WiFi board outline and header positions and differs in silk (no ESP32-S3 radio module, no LED matrix) and in the absence of the WiFi can. Append R4_MINIMA("UNO R4 Minima") and branch the draw code that places the radio module and matrix.

Item 4 — Teensy 3.2. Same 1.4 × 0.7" outline and 2×14 header positions as Teensy 4.0, so this is a pin array plus silk. Implemented with 34 control points — the two 1×14 edge rows, the five-hole bottom cluster and the severable VUSB pad — and an isCompact() helper that groups the 3.2 with the 4.0 against the longer 4.1. The bottom-cluster labels (VBAT, 3.3V, GND, Program, A14/DAC) are the one part not taken from a primary source and are worth checking against the PJRC pinout card.

Item 5 — Arduino Leonardo. Shares the Uno R3 shield footprint and header positions exactly. Differences are the ATmega32U4 silk, micro-USB in place of USB-B (drawMicroUsb instead of drawUsbB), and no separate USB-serial chip. Pin names are the R3 map with the native-USB annotations.

5.2 Version retrofit and new pin arrays — done

Item 6 — Modern Arduino Nano family. ArduinoNano has no version property; Tier 1 introduces one and adds the current lineup. All share the classic 0.73 × 1.70" outline and the 2×15 pin positions, but only the classic Nano populates the 2×3 ICSP block — on every later board that end of the PCB carries the radio module or USB bridge instead. So the classic keeps its 36 control points and the modern variants have 30. Serialization is safe because the classic is the default and is untouched; the shorter counts belong to enum constants no shipped file references.

public enum NanoVersion {
  CLASSIC("Nano (ATmega328)"),           // default; current behavior
  EVERY("Nano Every"),
  NANO_33_IOT("Nano 33 IoT"),
  NANO_33_BLE("Nano 33 BLE"),
  NANO_33_BLE_SENSE("Nano 33 BLE Sense"),
  NANO_RP2040_CONNECT("Nano RP2040 Connect"),
  NANO_ESP32("Nano ESP32");
}

What varies by version:

Aspect CLASSIC EVERY 33 IoT 33 BLE / Sense RP2040 Connect Nano ESP32
Separate MCU package m328P (rot. 45°) m4809 SAMD21 — (in module) RP2040 — (in module)
Part at the far end ICSP 2×3 header SAMD11 bridge NINA-W102 can NINA-B306 can NINA-W102 can NORA-W106 can
USB Mini-B Micro-B Micro-B Micro-B Micro-B USB-C
Pin-name array classic modern modern modern modern modern + GPIOxx
Control points 36 30 30 30 30 30

The enum carries the silk label, the MCU marking and the end-module marking, so draw() branches only on USB type, whether the MCU package is drawn separately (it is not when the die sits inside the module) and whether the end part is a shielded can or a bare QFN.

drawMiniUsb, drawMicroUsb, drawUsbC, drawMetalConnector and drawChip all already exist in AbstractMakerBoard.

Pin arrays: PIN_NAMES keeps the classic 36 entries. Each later board gets its own 30-entry array, transcribed from its official Arduino pinout diagram (docs.arduino.cc/resources/pinouts/ <SKU>-full-pinout.pdf) rather than assumed from the classic. A single shared "modern" array was wrong: the PWM sets and the power pins genuinely differ.

Version PWM pins Position 17 Position 18 Position 27
CLASSIC D3 D5 D6 D9 D10 D11 RST2 5V AREF
EVERY D3 D5 D6 D9 D10 RST2 5V AREF
NANO_33_IOT D2 D3 D5 D6 D9 D10 RST2 5V AREF
NANO_33_BLE / _SENSE D2–D13 (all) RST2 5V AREF
NANO_RP2040_CONNECT D2–D13 (all) REC (BOOTSEL) 5V AREF
NANO_ESP32 D0–D13 and A0–A7 B1 VUSB B0
NANO_R4 D3 D5 D6 D9 D10 D11 BOOT 5V AREF

The Nano R4 (ABX00142, Renesas RA4M1) additionally annotates D4/D5 as the CAN pins, A0 as the DAC and A1–A3 as the on-chip OPAMP inputs and output, and its end-of-board part is the Qwiic JST-SH socket rather than a radio module — drawn with drawFpcConnector, since it is a connector and not a shielded can.

PIN_NAMES_ESP32 additionally dual-labels with the Espressif GPIO number, e.g. D2 (~, GPIO5); those numbers are taken from the ABX00083 pinout diagram.

draw() gains version switches for the MCU chip label (and whether it is drawn rotated 45° like the classic TQFP or axis-aligned like a QFN), the end module, and the USB connector helper. Board outline and mounting holes are unchanged. Because the pin count is now version-dependent, setVersion() must call updateControlPoints() — it previously only invalidated the cache, which was harmless while the geometry was fixed.

The 5V / 3V3 logic-level silk from the original plan was dropped: the Nano draws no pin labels at all, so a lone voltage annotation would be invented silkscreen rather than what is on the board.

The modern Nanos also have castellated edges rather than plain through-holes: the outline is notched at every pin and the pads run out to the board edge, exactly as on the Pico. That rendering now lives in AbstractMakerBoard as drawCastellatedPads (one column of pads toward a given edge) and subtractCastellationNotches (the matching bites out of the outline), with getCastellatedPadSize / HoleSize / NotchSize / PadColor as the per-board overrides. RaspberryPiPico was refactored onto the same pair — its own method survives only as the wrapper that places the two columns and draws the SWD pads, so its rendering is unchanged. Any future castellated board (the ESP32 SuperMini and XIAO in §5.3 / §6) should reuse these rather than copy the geometry a third time.

Tests: testVersionProperty() (default CLASSIC, labels, round-trip); testPinNamesPerVersion() over all seven versions asserting no empty names, the A4 (SDA) annotation on a modern version and the GPIO dual-label on NANO_ESP32; testGeometryIsVersionIndependent() and testModernVersionsHaveNoIcspBlock() pinning the 36/30 split and the outline; draw smoke test looping all versions × headers on/off. The value is entirely in getting the labels and per-board silk right; the rendering scaffold is a light touch.

Item 7 — ESP32-C3 DevKitM-1 and ESP32-C6 DevKitC-1. The heaviest enum-style item, because ESP32DevKit gives every variant its own pin array and its own branch in getRelativeOffsets(), getBodyShape() and draw(). The C3 is a genuinely different board (single RISC-V core, ESP32-C3-MINI-1 module, one addressable RGB LED), not a re-label.

Both pin arrays were transcribed from the Espressif esp-dev-kits user guides (the J1/J3 header tables), not from memory — see D3's note in §4.5.

  • ESP32-C3-DevKitM-1: two 1×15 headers (30 pins) on 0.1" pitch, row spacing 22.86 mm (0.9"), ESP32-C3-MINI-1 module with PCB antenna at the top, a single micro-USB port at the bottom, BOOT + RST buttons.
  • ESP32-C6-DevKitC-1: two 1×16 headers (32 pins, the last position on each is NC) on the same 0.9" body, ESP32-C6-WROOM-1 module, two USB-C connectors (USB-to-UART and native).

Espressif publishes these outlines only as dimension drawings, so BOARD_WIDTH_RISCV (25.4 mm) and the row spacing are taken from the shared DevKitC form factor and the body length is derived as top margin + pin field + bottom margin using the same margins as the S3 DevKitC-1. That derivation is called out in a comment on the constants and is the thing to check if a board ever measures wrong.

  1. DevKitVersion: append ESP32_C3_DevKitM_1("ESP32-C3 DevKitM-1 (32-Pin)") and ESP32_C6_DevKitC_1("ESP32-C6 DevKitC-1 (32-Pin)").
  2. Add PIN_NAMES_C3 and PIN_NAMES_C6.
  3. Add BOARD_WIDTH_C3 / BOARD_LENGTH_C3 (and _C6) plus module and antenna sizes; the C3 module is smaller than WROOM-32, so SHIELD_*_S3 is the better starting point.
  4. getControlPointNodeName(int): two new branches.
  5. getRelativeOffsets(): two branches. Both are the simple two-straight-columns layout — copy the 30-pin branch and change the loop bounds and row-spacing constant.
  6. getBodyShape(): rounded rectangle plus PCB-antenna notch at the top, as the 30-pin and S3 cases already do.
  7. draw(): module shield labelled ESP32-C3-MINI-1 / ESP32-C6-WROOM-1 via drawMetalConnector, PCB antenna via drawPcbAntenna, BOOT/RST via drawButton, USB via drawMicroUsb ×2 (C3) or drawUsbC ×2 (C6), one RGB LED dot.
  8. drawIcon() unchanged (default stays 30-pin V1).

Tests mirror the existing per-version blocks. ~1 day, moderate risk — geometry constants need datasheet cross-checking, but the change is contained entirely within ESP32DevKit.

5.3 New classes

Genuinely different footprints, so per D2 each gets its own class.

# Board Shape Why Tier 1
8 ESP32-CAM ~40 × 27 mm, 2×8 headers, OV2640 camera FPC, microSD slot After the DevKit, the most-used ESP32 board in hobby projects. Nothing close exists.
9 ESP32 SuperMini ~22.5 × 18 mm, 2×8 castellated, PCB antenna. One class, Version {C3, S3} Now the default cheap ESP32 board. Model on RaspberryPiPico's castellated pad rendering.
10 Arduino Pro Micro ~33 × 18 mm, 2×12, ATmega32U4, micro-USB The HID and custom-keyboard staple; no equivalent in the set.
11 Arduino Pro Mini ~33 × 18 mm, 2×12 + 6-pin FTDI header. Version {5V 16 MHz, 3.3V 8 MHz} Still ubiquitous on breadboards. Identical outline between the two variants; differs in silk and regulator.
12 STM32 Pill ~53 × 22 mm, 2×20 on 0.1". Version {Blue Pill F103, Black Pill F401, Black Pill F411} Cheapest ARM path, still everywhere. Shared outline makes this one class.

Item 9 replaces the "Tier 2, note only" treatment the SuperMini had in the superseded document: it is a different footprint from the DevKit (so a separate class, per D2) and is common enough now to belong in Tier 1.


6. Tier 2

Whole ecosystems worth a deliberate push. Each is one class plus a Version enum where the vendor standardised a footprint, and separate classes where they did not.

Board / family Structure Notes
Seeed XIAO one class, Version {ESP32-C3, ESP32-S3, RP2040, nRF52840, SAMD21} Seeed standardised a ~21 × 17.5 mm castellated footprint across the family — a textbook single-class case under D2.
Adafruit Feather one class, Version {M0 Express, M4 Express, ESP32-S3, RP2040} Standardised 0.9 × 2.0" outline.
Adafruit QT Py / ItsyBitsy one class each Different footprints from Feather and from each other.
BBC micro:bit one class, Version {v1, v2} Enormous in education. The gold edge connector is genuinely new drawing work, which is why it is not Tier 1.
Arduino MKR one class, Version {WiFi 1010, Zero, NB 1500} Shared ~25 × 61.5 mm outline.
Heltec WiFi LoRa 32 one class, Version {V2, V3} LoRa + OLED. The Meshtastic community is large and entirely unserved today.
LilyGO T-Display-S3 one class ESP32-S3 with an integrated TFT.
TTGO LoRa32 one class Distinct footprint from the Heltec boards.
M5Stack M5StackCore (Core2), M5StickC (Plus / Plus2), M5Atom (Atom / StampS3) Four distinct form factors; group by footprint, not by brand.
Waveshare RP2040-Zero one class ~18 × 23.5 mm castellated.
Pimoroni Tiny 2040 one class Sibling footprint to RP2040-Zero but not identical.
Pi-compatible SBCs OrangePiZero, RadxaZero, LePotato Same 40-pin header, different outlines, so named classes rather than one shared one (D1, D2).

7. Tier 3

Long tail and specialty. Add on request or when a specific project needs one.

  • Pro / industrial Arduino — Giga R1, Portenta H7, Nicla Sense, Due, Zero, Micro.
  • Raspberry Pi variants — CM4 / CM5 plus IO board, Pi 400 / 500.
  • AI accelerators — Jetson Orin Nano, Google Coral Dev Board.
  • Other SBCs and RISC-V — BeagleBone Black, Milk-V Duo, ESP32-P4, CH32V003.
  • Legacy — Teensy LC, Teensy 2.0++, Digispark ATtiny85, Wemos D1 R32.
  • Bare modules for custom-PCB work — ESP-01, ESP-12F, ESP32-WROOM-32, nRF52840 module. These are footprints rather than dev boards; if they are ever added, check whether they belong in micro at all or alongside the SMD packages.

8. Cross-cutting fixes

Small, independent, and worth folding into whichever Tier 1 item is done first.

  1. Teensy z-order. Teensy.java:54 declares zOrder = IDIYComponent.BOARD, while every other breadboard-friendly board in the package (ArduinoNano, RaspberryPiPico, ESP32DevKit, ESP8266NodeMCU, WemosD1Mini) uses COMPONENT. Breadboard is also BOARD, so a Teensy dropped on a breadboard renders in placement order rather than reliably on top. Looks like an oversight; changing it affects only draw order, not serialization.
  2. Version never reaches the BOM. getValue() returns null and every board uses bomPolicy = SHOW_ONLY_TYPE_NAME, so a Uno R3 and a Uno R4 WiFi both print as "Arduino Uno". A maker's BOM is a shopping list and the variant is the part they buy. Worth deciding on a uniform approach before the roadmap roughly triples the number of variants.
  3. Editable-property set drifts across the family. Headers exists on ArduinoNano and RaspberryPiZero but not on ArduinoUno, Teensy or ESP32DevKit; there is no "show pin labels" toggle anywhere; WemosD1Mini hardcodes SILK_PIN_NAMES_LEFT / SILK_PIN_NAMES_RIGHT instead of using the shared drawPinLabels. Settling a uniform Version / Headers / Show Labels / Board Color set now stops ten more boards inheriting the inconsistency.
  4. Pin-name conventions differ. ESP32DevKit uses GND_1, ArduinoNano uses GND1. And AbstractMakerBoard.getDisplayPinLabel truncates at the first _ and (, so ArduinoNano's D3 (~) silently loses its PWM marker on the silkscreen. Pick one convention before adding more arrays.

Items 1 and 4 are behavioural changes small enough to carry their own regression-suite run; items 2 and 3 are decisions to make before the bulk of the roadmap lands.

9. Suggested sequencing

  1. §5.1 enum appends — done: Pico 2 / 2 W, Zero 2 W, Uno R4 Minima, Leonardo, Teensy 3.2.
  2. §5.2 Item 6, modern Nano and Item 7, ESP32-C3 / C6 — done.
  3. Cross-cutting fixes (§8) — cheap, and fix 4 is better done before more pin arrays exist.
  4. §5.3 new classes — ESP32-CAM and SuperMini first; they close the largest remaining gaps.
  5. Tier 2 — one family at a time, each an independent commit.

Each item is an independent commit; none depends on another except where sequencing is noted.

10. Open decisions

  1. BOM treatment of Version (§8.2). Options: leave as-is; switch these boards to a BOM policy that includes the variant; or expose the variant through a value-like property. Affects every board in the package, so worth deciding once.
  2. Uniform property set (§8.3). Which of Headers and a new "Show Pin Labels" toggle should exist on all boards, and whether retrofitting Headers onto ArduinoUno / Teensy / ESP32DevKit is wanted. New boolean fields deserialize as false in old files, so the default must be chosen to preserve the current look.
  3. ESP32-C6 in the same pass as C3? §5.2 Item 7 is written for both since they share a body. If time-boxing, ship C3 first and add C6 as a one-branch follow-up.
  4. Nano pin-label verbosity (§5.2 Item 6). Recommendation as written: annotate bus pins on all modern variants, add the GPIO number only for NANO_ESP32.
  5. i18n. Component display names in @ComponentDescriptor are not currently in diylc-swing/src/main/resources/lang/*.txt for these boards, and the enum labels are plain strings shown in the property editor. No translation work is required by this roadmap; noted for a future i18n pass.