195 lines
7.9 KiB
Markdown
195 lines
7.9 KiB
Markdown
# 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:
|
||
|
||
```bash
|
||
bundle install
|
||
```
|
||
|
||
Then run:
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
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.
|
||
|
||
The wizard can add clearance beyond either short end of the Feather PCB for
|
||
right-angle headers, plug housings, and wire bends. Front clearance moves the
|
||
board and its standoffs away from the USB-C wall; rear clearance extends the
|
||
opposite end of the case.
|
||
|
||
USB programming access can be omitted for a closed front wall or paired with
|
||
an enclosed plug guide. The guide runs from the wall toward the connector and
|
||
automatically stops short based on the configured connector overhang and end
|
||
gap. New cases default to a 2 mm USB connector overhang, an enabled wall
|
||
opening, and an enabled guide; with the standard 2 mm front clearance the guide
|
||
has no inward length and behaves as the normal wall opening.
|
||
|
||
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](https://github.com/adafruit/Adafruit-ESP32-Feather-V2-PCB)
|
||
- [ESP32 Feather V2 CAD](https://github.com/adafruit/Adafruit_CAD_Parts/tree/main/5400%20ESP32%20Feather%20V2)
|
||
- [128x64 OLED FeatherWing PCB](https://github.com/adafruit/Adafruit-OLED-FeatherWing-PCB)
|
||
- [128x64 OLED FeatherWing CAD](https://github.com/adafruit/Adafruit_CAD_Parts/tree/main/4650%20OLED%20FeatherWing)
|
||
- [Adafruit 69 x 18 mm protected 18650 pack](https://www.adafruit.com/product/1781)
|
||
|
||
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](feather_case.scad) in OpenSCAD and use the Customizer,
|
||
or override values from the command line:
|
||
|
||
```bash
|
||
# 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`, with a 12.25 mm default
|
||
pitch. Set `stack_height_override` to the measured distance from the top surface
|
||
of the Feather PCB to the top surface of the uppermost FeatherWing PCB when
|
||
using unusual headers. Do not include components on the Wing; profile-specific
|
||
component heights and top gaps are added separately. The measured override
|
||
takes precedence over the computed height.
|
||
|
||
For the 128×64 OLED profile, `oled_component_height` is the height of the
|
||
tallest board feature (the switch tops), while `oled_display_height` controls
|
||
the display-face reference shown in the assembly preview. The defaults are
|
||
2.4 mm and 1.5 mm above the Wing PCB, respectively. The enclosure ceiling
|
||
remains based on the taller switches plus `oled_face_gap`, placing the display
|
||
face about 1.7 mm below the lid's inner plane. The default 0.7 mm captive-button
|
||
contact extension spans most of the 0.8 mm switch-to-lid gap.
|
||
|
||
## Custom wire egress
|
||
|
||
`extra_cutouts` accepts any number of entries:
|
||
|
||
```openscad
|
||
// [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` (the USB-C short wall), `rear` (the opposite short wall),
|
||
`left` (the plain/non-JST long wall), and `right` (the JST/battery long wall).
|
||
For front/rear faces, `u` is the global Y coordinate; for left/right faces it
|
||
is global X. The wizard presents this as distance from the selected wall's
|
||
left edge while viewing it from outside. The Z value is the opening centre.
|
||
Shapes are `circle`, `rect`, `roundrect`, and `slot`. Cutouts that enter the
|
||
floor or lid-lip keepout, approach another opening too closely, or overlap the
|
||
USB opening or guide 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.
|
||
|
||
1. Export and print `part="insert_coupon"` in the intended material.
|
||
2. Test both M2.5 and 1/4-20 inserts in the five stepped holes.
|
||
3. Set `m25_insert_hole_diameter` and `tripod_insert_hole_diameter` to the best
|
||
coupon values.
|
||
4. Print `part="switch_coupon"` and choose the best hole for the actual DMWD
|
||
switch batch.
|
||
5. Print `part="fit_coupon"` and tune `fit_clearance` before 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
|
||
|
||
1. Heat-set the optional 1/4-20 insert from inside the case. Its threaded
|
||
opening faces the exterior bottom.
|
||
2. Heat-set four M2.5 inserts into the board standoffs.
|
||
3. Fasten the ESP32 Feather V2, then install the stacking headers and Wings.
|
||
4. 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.
|
||
5. Heat-set the four lid inserts downward into the corner bosses.
|
||
6. For OLED builds, insert each enabled printed plunger through the lid from
|
||
the inside. The elongated flange stays in the internal recess.
|
||
7. 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.
|