6.2 KiB
Parametric Feather Case
An OpenSCAD enclosure generator for the Adafruit ESP32 Feather V2, stacked FeatherWings, an optional protected 18650 pack, and an optional 1/4-20 camera mount. It produces a body, removable lid, OLED button plungers, and fit calibration coupons.
Interactive Ruby wizard
The HighLine wizard asks the project-specific questions, saves the answers in YAML, and builds a self-contained case directory with OpenSCAD source, STL and/or 3MF geometry, and rendered previews.
Install the Ruby dependency into this repository:
bundle install
Then run:
bundle exec bin/feather-case
The menu can create a case, reopen one for dimensional tuning after a test
print, or rebuild an existing case. Generated definitions live under
cases/<name>/; exports, previews, revision history, and vendor/bundle are
ignored by Git.
OpenSCAD and Blender must be available on PATH. On Ubuntu:
sudo apt-get install openscad blender
Set OPENSCAD=/path/to/openscad or BLENDER=/path/to/blender when either
program is installed elsewhere. The wizard checks both tools before replacing
an existing package.
Each generated directory contains a dependency-free build.rb. After copying
that directory to another Ubuntu machine, run ruby build.rb to reproduce its
exports and previews. The saved generator source is used by default so a
fine-tuning pass cannot silently pick up later geometry changes.
OpenSCAD's 3MF output contains portable model geometry. It does not contain a Bambu printer, filament, plate, or process profile; select those settings after opening the files in Bambu Studio.
The design targets support-free FDM printing with a 0.6 mm nozzle. PLA and PETG are suitable for general use; ASA is the preferred starting material for outdoor exposure. The enclosure is not weather-sealed.
Reference geometry
All dimensions are millimetres. Board coordinates come from Adafruit's source files:
- ESP32 Feather V2 PCB
- ESP32 Feather V2 CAD
- 128x64 OLED FeatherWing PCB
- 128x64 OLED FeatherWing CAD
- Adafruit 69 x 18 mm protected 18650 pack
The board origin is its USB edge at (0, 0). The case uses X from the USB wall
toward the rear, Y from the plain side toward the battery/JST side, and Z up
from the exterior bottom.
Generate parts
Open feather_case.scad in OpenSCAD and use the Customizer, or override values from the command line:
# Generic one-Wing case
openscad -o body.stl -D 'part="body"' feather_case.scad
openscad -o lid.stl -D 'part="lid"' feather_case.scad
# Three-Wing GPS case with battery and camera mount
openscad -o gps-body.stl \
-D 'part="body"' \
-D 'top_profile="gps"' \
-D 'wing_count=3' \
-D 'battery_enabled=true' \
-D 'tripod_insert_enabled=true' \
feather_case.scad
openscad -o gps-lid.stl \
-D 'part="lid"' \
-D 'top_profile="gps"' \
-D 'wing_count=3' \
-D 'battery_enabled=true' \
-D 'tripod_insert_enabled=true' \
feather_case.scad
# 128x64 OLED lid and all four captive buttons
openscad -o oled-lid.stl \
-D 'part="lid"' \
-D 'top_profile="oled128x64"' \
-D 'button_reset=true' \
feather_case.scad
openscad -o oled-buttons.stl \
-D 'part="buttons"' \
-D 'top_profile="oled128x64"' \
-D 'button_reset=true' \
feather_case.scad
The standard stack height is wing_count * wing_pitch. Set
stack_height_override to the measured distance from the Feather PCB top to
the top FeatherWing PCB when using unusual headers. It takes precedence over
the computed height.
Custom wire egress
extra_cutouts accepts any number of entries:
// [face, shape, u, z, width, height, radius]
extra_cutouts = [
["left", "circle", 35, 10, 8, 8, 4],
["rear", "roundrect", 20, 12, 14, 7, 2],
["right", "slot", 28, 15, 18, 5, 2.5]
];
Faces are front, rear, left, and right. For front/rear faces, u is
the global Y coordinate; for left/right faces it is global X. The Z value is
the opening centre. Shapes are circle, rect, roundrect, and slot.
Cutouts that enter the floor or lid-lip keepout raise an assertion instead of
silently weakening those features.
Calibration
Heat-set insert holes vary significantly by insert brand, filament, nozzle, temperature, and printer calibration. Treat the supplied values as starting points.
- Export and print
part="insert_coupon"in the intended material. - Test both M2.5 and 1/4-20 inserts in the five stepped holes.
- Set
m25_insert_hole_diameterandtripod_insert_hole_diameterto the best coupon values. - Print
part="switch_coupon"and choose the best hole for the actual DMWD switch batch. - Print
part="fit_coupon"and tunefit_clearancebefore committing to the complete lid and body.
For ASA, tune dimensional compensation with coupons rather than applying an assumed global shrink percentage. Start with four or more walls, good chamber temperature control, and the same extrusion settings intended for the case.
Assembly
- Heat-set the optional 1/4-20 insert from inside the case. Its threaded opening faces the exterior bottom.
- Heat-set four M2.5 inserts into the board standoffs.
- Fasten the ESP32 Feather V2, then install the stacking headers and Wings.
- For battery builds, place the protected 69 x 18 mm pack in the cradle, route its lead through the partition notch, and mount the latching switch in the battery-side wall.
- Heat-set the four lid inserts downward into the corner bosses.
- For OLED builds, insert each enabled printed plunger through the lid from the inside. The elongated flange stays in the internal recess.
- Engage the lid rim and fasten four standard M2.5 socket-head screws into the 2.5 mm-deep counterbores.
Confirm the USB plug, switch, battery, insert, and lid fits without force before leaving a lithium-ion battery installed. The battery cradle is intended for Adafruit's protected pack, not an unprotected loose cell.