mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-13 02:32:09 +10:00
a743de4024
* 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 * displays tweaks * display improvements * neopix * displays * improvements * led matrix * strip * led bar graph * jewel * tft * tft * Update maker-peripherals.md * nokia * led bar * labels * tft * cleanup * oled * cleanup * display enhancement * displays * neopixel * displays * displays * new tft * displays * icon * variants * 2-digit 0.56 inch 7 segment * Added ability to hide component categories in the component tree and toolbar from the Config menu * led bar * Update variants.xml * color selection for bar graph * Added 1.8" sd * tft fixes * Update WS2812BRing.java * neopixel improvements * netlist and node name improvements * oled tweak * cleanup * mockito fix --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
259 lines
16 KiB
Markdown
259 lines
16 KiB
Markdown
# Maker Peripherals — `Displays & Outputs`
|
||
|
||
Status: **13 components shipped**, in the as-yet-unreleased `6.7.0` block of
|
||
`diylc-core/src/main/resources/update.xml`.
|
||
Scope: `diylc-library`, package `org.diylc.components.displays`.
|
||
Companion: `maker-board-roadmap.md`, which covers `org.diylc.components.micro`.
|
||
|
||
Nothing in this package has been in a release, so defaults, control-point counts and serialized
|
||
field names can still be changed freely. **That stops the moment 6.7.0 ships.**
|
||
|
||
## 1. What is in the palette
|
||
|
||
| Class | Variants | Other properties |
|
||
|---|---|---|
|
||
| `CharacterLCD` | 16x2, 20x4 × I2C backpack, parallel HD44780 | Backlight Color, Screen |
|
||
| `OLEDDisplay` | 0.96" SSD1306 128x64, 0.91" SSD1306 128x32, 1.3" SH1106 128x64 × I2C, 7-pin SPI, 6-pin SPI | Pixel Color, Screen |
|
||
| `TFTDisplay` | 2.8" / 2.4" ILI9341, 0.96" / 1.8" ST7735, 1.54" ST7789, 1.28" GC9A01 round | Screen |
|
||
| `Nokia5110LCD` | single part (PCD8544 84x48) | Backlight Color, Screen |
|
||
| `SevenSegmentDisplay` | 1-digit 0.56", 4-digit 0.36", 4-digit 0.56", 4-digit TM1637 module | Common, Punctuation, LED / Board / Body colour |
|
||
| `LEDMatrix` | MAX7219 single 8x8, compact 8x8, 4-in-1 32x8, 8-in-1 64x8 | Dot Color |
|
||
| `LEDBarGraph` | 8, 10, 12 segments | Orientation, body / border colour |
|
||
| `WS2812BBreakout` | single LED | — |
|
||
| `WS2812BStick` | 8 LEDs | — |
|
||
| `WS2812BJewel` | 7 LEDs | — |
|
||
| `WS2812BRing` | 12, 16, 24 LEDs | — |
|
||
| `WS2812BStrip` | 30 / 60 / 144 LED·m⁻¹ × 1–144 LEDs | — |
|
||
| `WS2812BPanel` | Adafruit 8x8 NeoMatrix | — |
|
||
|
||
Twelve extend `AbstractMakerBoard`. `LEDBarGraph` is the exception: a DIP-outline part, so it
|
||
follows `DIL_IC` on `AbstractLabeledComponent` with its own transformer and inherits none of the
|
||
maker helpers. It is still in this category because that is where someone looks for a bar graph.
|
||
|
||
## 2. Conventions this package follows
|
||
|
||
These are the rules worth knowing before touching anything here. Most were learned by getting them
|
||
wrong once.
|
||
|
||
**Variants.** A `Version`-style enum on the existing class where the footprint family is shared; a
|
||
new class where it is not. The test is structural, not cosmetic: `WS2812BJewel` is a separate class
|
||
from `WS2812BRing` because it is a disc rather than an annulus, with a centre LED and its own pad
|
||
arrangement — five variant-specific structures is a different part.
|
||
|
||
**Figures live on the variant.** Hardcoded `Size` constants and `String[]` arrays in the component
|
||
class, per-variant wherever a variant changes them. No pin-definition resource, and no pixel
|
||
literals in `draw()` — every dimension derives from a `Size`.
|
||
|
||
**A different silkscreen is not a variant; a different pin count is.** The same two pads on an
|
||
SSD1306 carry the clock and data lines in both interfaces — the module's BS jumpers choose the
|
||
protocol, not the pins — so `SCL`/`SCK`/`CLK`/`D0` are one pin and `SDA`/`MOSI`/`D1` are another,
|
||
and boards that print them differently are the same board. Node names pick one spelling and move on.
|
||
A 6-pin SPI board is the opposite case: its chip select is tied low on the PCB rather than brought
|
||
out, so it cannot share a bus, and that is a variant because it reaches the netlist.
|
||
|
||
**Say whether a figure is measured or derived.** Active areas computed from a nominal diagonal at a
|
||
panel's aspect ratio are derivations, and are commented as such so nothing is built on them. Where a
|
||
part's own measurement contradicts a derivation the measurement wins and carries its own field — but
|
||
check first that it really contradicts it. A supplied figure sitting within half a millimetre of
|
||
what an existing rule already produces is more likely a reading than a departure, and has twice
|
||
turned out to be one; query it before it earns a mechanism.
|
||
|
||
**Orientation is sourced per variant, never standardised.** Which edge a board's header leaves by is
|
||
a fact about the part. Control point zero is always the leftmost pin, so with the pin order fixed a
|
||
top header and a bottom header are mirror images, not the same board turned round. `TFTDisplay`
|
||
divides three and three, and every constant states its own edge — the short constructor takes the
|
||
flag too, so none can inherit a default. Standardising this family onto one orientation was tried
|
||
and had to be undone: it had moved two boards away from the truth.
|
||
|
||
**Do not let one property stand in for another.** `isRound()` was serving as "the header is at the
|
||
bottom" and broke the moment a rectangular board had a bottom header; `isDualRow()` was serving as
|
||
"this is a bare package". Carry both questions explicitly even while the answers agree.
|
||
|
||
**Pins are drawn and covered, never skipped.** `drawPinHeader` is what registers a conductive area,
|
||
so a header hidden under a module or a moulding is drawn first and painted over. Leaving the call
|
||
out looks identical and silently drops those pins from continuity and the netlist.
|
||
|
||
**Silk where it fits, nowhere else.** Pin names go through `getSilkPinLabel`, so a name is written
|
||
once. A row with no clear strip beside it gets no labels rather than crowded ones — the matrix's
|
||
covered rows, the LCD's I2C backpack and the TFTs' SD rows all go unlabelled deliberately. A
|
||
`SILK_NAMES` array exists only where the node name is actively wrong on the board, not merely long.
|
||
|
||
**The glass prints the part's own spec.** `Display.VALUE` puts the variant string on the lit area,
|
||
generated from the properties rather than typed, carrying no prose and no language. `Display.NONE`
|
||
gives the unpowered part. No invented demo content, ever.
|
||
|
||
**BOM.** Every class sets `bomPolicy = SHOW_ONLY_TYPE_NAME` and returns the variant string from
|
||
`getVariantLabel()`, because `BomMaker` groups rows on type name plus value — without it every
|
||
variant of a class collapses into one line and the BOM cannot say which part to buy.
|
||
|
||
**Shared arrays are shared by identity.** Where two variants have the same pinout they reference one
|
||
array constant and the test asserts `assertSame`, so a correction to one reaches both. Two copies
|
||
that happen to match would pass every name check and drift the day one is corrected.
|
||
|
||
**Nested types at the bottom of the file.** Where a variant needs more than a couple of extra
|
||
figures they go into a nested value class rather than onto the enum constructor —
|
||
`OLEDDisplay.Layout`, `TFTDisplay.Glass`, `SevenSegmentDisplay.Module`. A constructor past about
|
||
fifteen arguments is the signal.
|
||
|
||
## 3. Figures that are not measurements
|
||
|
||
Kept visible so no one mistakes them for sourced data and builds on them.
|
||
|
||
- **`SevenSegmentDisplay` digit widths** — 8.1 mm on both 0.56" packages (unverified) and 5.2 mm on
|
||
the 0.36" (inferred from the 0.56" ratio, so resting on an unchecked figure). **Deliberately left
|
||
as inferences:** they size the drawn glyph and nothing else, and the glyph is already a declared
|
||
departure from the package at `DIGIT_DRAW_SCALE` 0.88. An error here is cosmetic and bounded,
|
||
unlike a wrong pin array.
|
||
- **`SevenSegmentDisplay.Module` hole figures** — 1.778 and 1.524 mm, which are the 14 and 12 pixel
|
||
offsets the class drew before they were figures at all, converted exactly so the drawing did not
|
||
change.
|
||
- **`Nokia5110LCD`** — the 3.5 mm clearance from the bottom edge to the pin row.
|
||
- **`WS2812BStrip`** — tape width (10 mm / 12 mm) is a stated norm rather than a measurement, and
|
||
the end-pad lead-in derives from the pad and package footprints.
|
||
- **`TFTDisplay`** — the SD rows' horizontal placement is centred across the board by derivation;
|
||
only their offset from the edge was given.
|
||
- **`OLEDDisplay`** — the 6-pin SPI boards borrow the 7-pin boards' outlines. A 6-pin module is a
|
||
PCB of its own with one fewer pad, and nothing but its outline would say whether it matches.
|
||
|
||
## 4. Testing
|
||
|
||
Per-class tests in `diylc-library/src/test/java/org/diylc/components/displays/`, using
|
||
`MakerBoardTestSupport` (`assertRow`, `assertRowSpacing`, `assertBoardSize`, `assertDrawsCleanly`,
|
||
`assertScreenTextIsDrawn`, `renderPixels`).
|
||
|
||
What these tests are for, beyond the obvious count-and-dimension checks:
|
||
|
||
- **Assert relationships, not transcriptions.** A board is exactly as wide as its modules; a glass
|
||
clears the mounting holes; no hole is drilled where a pad is; a lit area that is measured really
|
||
does disagree with the rule it replaced. A test that restates the constant passes while the
|
||
component is wrong.
|
||
- **No duplicate node names,** on every variant. The cost is legibility, not connectivity: nodes are
|
||
identified by component and control point index and the netlist graph is keyed on position, so two
|
||
pads named `GND` stay two nodes that merely print the same, and a reader cannot tell which one a
|
||
connection reached. They are invisible on the canvas too, since `getDisplayPinLabel` cuts the
|
||
suffix off and both silk as `GND`. `Teensy` is the one board that still repeats a bare name.
|
||
- **A drawing smoke test** over every variant, state and orientation.
|
||
- When a refactor is meant to change nothing, **render before and after and compare pixels.** The
|
||
`digitCount` work was verified that way, and it caught a sub-pixel hole shift the unit tests
|
||
missed.
|
||
|
||
`MakerComponentsTest` carries the generic discovery and icon coverage. A class ships by moving from
|
||
`unreleasedMakerComponentClasses` to `releasedMakerComponentClasses` and uncommenting its
|
||
`@ComponentDescriptor`.
|
||
|
||
## 5. Release
|
||
|
||
The slice is worth shipping on its own: it is archetype-complete, part of it (7-segment, character
|
||
LCD, bar graph, addressable strips) reaches builds with no microcontroller in them, and the slices
|
||
after it are large and differently shaped, so batching would mean a much later and far less
|
||
reviewable release. A release is also the only validation loop that reaches people who own the
|
||
parts.
|
||
|
||
### 5.1 What shipping makes permanent
|
||
|
||
Only this list needs checking beforehand, because only this list is a contract afterwards:
|
||
|
||
- class names, and serialized field names and types
|
||
- **control-point counts**
|
||
- **control-point positions relative to point 0** — these are stored per instance, so moving a pin
|
||
relative to the body misplaces every wire in an existing file
|
||
|
||
Everything else is fixable in a later release without breaking a file: bezel placement, colours,
|
||
silk, hole positions, digit widths. Every figure in §3 falls here, which is why none of them blocks
|
||
a release.
|
||
|
||
### 5.2 Pre-release checklist
|
||
|
||
1. **Audit the pin layout of all 13** — count, node names, and each pin's position relative to the
|
||
body. Not the cosmetics; those are §5.1's second list.
|
||
2. **Settle `TFTDisplay`'s 2.8" SD row.** It is the least verified thing in the package: the row was
|
||
added on the argument that the "(Touch + SD)" label implied a missing header, and its 3.0 mm
|
||
offset was read from "the same offset as the bottom row" rather than measured. Four control
|
||
points that become permanent.
|
||
3. **Re-check `TFTDisplay` generally.** It is where the churn concentrated — both ILI9341s went
|
||
14 to 18 control points, and the 0.96", 1.8" and 1.54" each had every pin move relative to the
|
||
body when their orientation was corrected.
|
||
4. **Render a contact sheet of all 13 and look at it.** Cheap, and it caught several real errors
|
||
that the unit tests passed straight over.
|
||
|
||
Regression samples (§6.3) are deliberately *not* on this list. They protect against future change,
|
||
which is what a released contract makes dangerous — so they are the first task after shipping, not
|
||
a blocker on it.
|
||
|
||
### 5.3 Release notes
|
||
|
||
One `NEW_FEATURE` per palette entry in the `6.7.0` block, part name then variant list. **A released
|
||
block is never edited.** A new variant of a component that is new in the same block goes onto that
|
||
component's existing line rather than being logged as an `IMPROVEMENT` — there is no earlier release
|
||
for it to improve on.
|
||
|
||
## 6. Next steps
|
||
|
||
### 6.1 Parts worth adding, ranked by how often they appear in builds
|
||
|
||
1. **1.3" 240x240 ST7789**, and the 1.14" and 2.0" ST7789 the Pico ecosystem buys. `TFTDisplay` now
|
||
absorbs offset panels, either header edge and second rows, so each is one `Controller` constant.
|
||
Needs per board: outline, header offset and edge, pin names in printed order, hole inset and
|
||
drill, bezel height, and whether the lit area is centred or measured.
|
||
2. **MAX7219 8-digit 7-segment module** — the clock and counter staple, and this package already
|
||
models a MAX7219 cascade for the matrix. Unblocked: `DisplayType` now carries digit count, pin
|
||
array and module board figures, so this is a constant.
|
||
3. **6-digit TM1637 and 2-digit 0.56"** — the rest of the clock and thermometer range. Same.
|
||
4. **E-paper, 1.54" / 2.13" / 2.9" SSD1680.** Once judged niche; that call is stale, as ESP32 badge
|
||
builds and the Waveshare and Good Display modules made it ordinary. The flexible-cable mounting
|
||
is real new drawing work, which is the only reason it is not higher.
|
||
5. **WS2812B 16x16 and flexible 8x32 matrices** — the one addressable form the package lacks.
|
||
6. **The bare WS2812B 5050 LED**, as against a breakout. People solder these directly.
|
||
7. **16x4 character LCD.** Also the RGB-backlight 1602, which is *not* the free colour default it
|
||
looks like: it is an 18-pin part whose three backlight anodes are real pins, so it is an
|
||
`LCDInterface` constant with its own array.
|
||
8. **Nixie tubes — IN-12, IN-14, B7971.** The strongest audience overlap on this list: DIYLC already
|
||
has a `Tubes` category, and the people in it build Nixie clocks.
|
||
9. **2.42" SSD1309 OLED**, 14- and 16-segment alphanumeric, HT16K33 backpacks. Real, second tier.
|
||
|
||
Explicitly rejected: a tint property on `TFTDisplay`. A 240x320 colour panel has no tint to set, and
|
||
offering one invites a drawing that says something false about the hardware.
|
||
|
||
### 6.2 The "& Outputs" half of the name is unfulfilled
|
||
|
||
Every member of this category emits light. **There is no analog panel meter, no VU meter, no speaker
|
||
or driver, and no magic-eye tube anywhere in the library** — `misc/Buzzer` and
|
||
`electromechanical/PilotLampHolder` are the whole non-display output range.
|
||
|
||
This is a bigger gap than anything in §6.1, and it reaches the audience DIYLC already has: a VU
|
||
meter and a loudspeaker appear in amp and effect builds containing no microcontroller at all,
|
||
`Dial Scale` is already next door in `misc`, and a moving-coil meter is a simpler drawing than any
|
||
display here. Whether these belong in this category or in `Electro-Mechanical` is not an interesting
|
||
question; that they are absent is the finding.
|
||
|
||
### 6.3 Regression coverage — the standing risk
|
||
|
||
**No `.diy` file among the 1418 in `diylc-regression-data` references `org.diylc.components.micro`
|
||
or `org.diylc.components.displays`,** so 23 components have no rendering or netlist baseline. Unit
|
||
tests guard the figures we chose; they cannot catch a pin dropping out of the netlist or a component
|
||
misbehaving in a real project. Samples were declined for this slice; the case is stronger now that
|
||
orientations, pin arrays and geometry have all moved.
|
||
|
||
### 6.4 Later slices
|
||
|
||
**`sensors` (9 drafts).** Ship the four that are the unrivalled answer in their function — HC-SR04,
|
||
DHT11/22, PIR HC-SR501, MPU6050 — and leave the five commodity KY-style three-pin boards, which
|
||
carry most of the sourcing cost for the least distinctiveness. **Do not** collapse the tail into a
|
||
parameterised "three-pin sensor module": that is the generic configurable board that was already
|
||
built and reverted, and it fails for the same reason — people search the palette for a product name.
|
||
|
||
**`modules` (21 drafts).** The largest and least homogeneous batch, and the worst geometry drift in
|
||
the tree (`ULN2003Driver` has 24 raw pixel offsets, `PCA9685ServoDriver` 22, `L298NMotorDriver` 18).
|
||
Split by function rather than shipping as one category. Settle one overlap first: the drafted
|
||
`ActiveBuzzerModule` (KY-012) against the existing `misc/Buzzer`.
|
||
|
||
**`robotics` (4 drafts).** Blocked on an architectural decision, not on part selection.
|
||
`AbstractMotor` is a parallel fork of `AbstractMakerBoard`, re-implementing `rotatePoints`,
|
||
`drawPins`, `getFinalBorderColor` and `getCachingBounds` plus its own `PIN_COLOR`, `PIN_SIZE` and
|
||
silk fonts. Four components do not justify a second hierarchy: either lift the shared behaviour into
|
||
a common base or take the duplication deliberately.
|
||
|
||
**i18n.** Component display names and enum labels are plain strings, absent from
|
||
`diylc-swing/src/main/resources/lang/*.txt`, as they are for the shipped boards. No work required
|
||
here; noted for a future pass.
|