fix: add camera node USB power ports
CI/CD / lint-and-typecheck (pull_request) Successful in 7s
CI/CD / test (pull_request) Successful in 7s
CI/CD / build (pull_request) Failing after 9s
CI/CD / deploy (pull_request) Has been skipped

This commit is contained in:
2026-05-23 13:33:06 +00:00
parent af68bfaa3a
commit 9a50d0c801
7 changed files with 41104 additions and 32927 deletions
+6 -5
View File
@@ -23,7 +23,7 @@
**Design direction:** **Design direction:**
- Stand-mounted upright camera node enclosure; the case still does **not** mount to the GoPro. - Stand-mounted upright camera node enclosure; the case still does **not** mount to the GoPro.
- Visual direction now matches the original green appliance-style reference: tall vertical body, large inset front panel, centered OLED near the upper third, blank middle area, two long rounded lower slots, and bottom-center cable exit. - Visual direction now matches the original green appliance-style reference: tall vertical body, large inset front panel, centered OLED near the upper third, blank middle area, two long rounded lower slots, bottom USB-C female power input, and right-side USB-A female passthrough power port for the GoPro.
- This replaces the rejected wide/low generic electronics-box layout from the first v4 attempt. - This replaces the rejected wide/low generic electronics-box layout from the first v4 attempt.
- Primary mounting is reusable cloth zip ties / Velcro straps through low-profile external rear belt-loop channels, not a clamp/dovetail. - Primary mounting is reusable cloth zip ties / Velcro straps through low-profile external rear belt-loop channels, not a clamp/dovetail.
- Front has a recessed/flush full-height service lid similar to a field-service status panel. - Front has a recessed/flush full-height service lid similar to a field-service status panel.
@@ -33,8 +33,8 @@
- single 3 mm RGB status LED replacing red/green status LEDs. - single 3 mm RGB status LED replacing red/green status LEDs.
- small rocker on/off switch. - small rocker on/off switch.
- two long rounded lower front slots styled after the reference. - two long rounded lower front slots styled after the reference.
- Front-panel screen, LED, rocker, cable-relief, and lower-slot openings are actual through-cuts through the full lid and locating lip so the back side of the printed lid is not skinned over. - Front-panel screen, LED, rocker, and lower-slot openings are actual through-cuts through the full lid and locating lip so the back side of the printed lid is not skinned over.
- Body includes screw bosses, recessed lid pocket, lid locating geometry, bottom cable exit/strain-relief notch, and two rear horizontal external belt-loop strap channels to resist rotation on a stand. - Body includes screw bosses, recessed lid pocket, lid locating geometry, a bottom USB-C female power inlet cutout, a right-side USB-A female passthrough power cutout, and two rear horizontal external belt-loop strap channels to resist rotation on a stand.
- Internal envelope is sized for known module dimensions plus service clearance: - Internal envelope is sized for known module dimensions plus service clearance:
- ESP32-C3 Super Mini: 22.5 × 18 mm. - ESP32-C3 Super Mini: 22.5 × 18 mm.
- ESP-01S: ~24.7 × 14.3 × 12 mm. - ESP-01S: ~24.7 × 14.3 × 12 mm.
@@ -65,7 +65,8 @@ BAT 87% LINK OK
- current-limiting resistor placement. - current-limiting resistor placement.
- Wiring/service: - Wiring/service:
- USB cable diameter and bend radius. - USB cable diameter and bend radius.
- whether power enters through bottom notch, side notch, or panel connector. - bottom USB-C female panel/breakout connector flange, body depth, and mounting requirements.
- right-side USB-A female panel/breakout connector flange, body depth, and mounting requirements for GoPro 5 V passthrough.
- actual regulator/power distribution board footprint if used. - actual regulator/power distribution board footprint if used.
- Fasteners: - Fasteners:
- M2 vs M2.5 vs self-tapping screws for lid. - M2 vs M2.5 vs self-tapping screws for lid.
@@ -78,7 +79,7 @@ BAT 87% LINK OK
- rear strap bridge bridging/support behavior. - rear strap bridge bridging/support behavior.
- body/lid fit after PETG shrinkage. - body/lid fit after PETG shrinkage.
- lid lip clearance and screw boss robustness. - lid lip clearance and screw boss robustness.
- cable notch strength and strain relief. - USB-C/USB-A cutout edge quality, wall strength, and connector retention/strain relief.
**Suggested OpenSCAD validation/export commands:** **Suggested OpenSCAD validation/export commands:**
+29 -23
View File
@@ -9,11 +9,12 @@ Each camera node is two ESP boards in a small upright stand-mounted case. The ca
``` ```
┌─────────────────┐ ┌─────────────────┐
│ USB Power Bank │── USB ──→ GoPro (power only) │ USB Power Bank │
│ (off-the-shelf)│── USB ──→ Camera Node Case │ (off-the-shelf)│
└────────────────┘ └────────────────┘
USB-C cable into bottom USB-C female input
┌────────┴────────────────────────────┐
┌─────────────────────────────────────┐
│ Camera Node Case v4 │ ← Velcro/cloth straps to stand │ Camera Node Case v4 │ ← Velcro/cloth straps to stand
│ ┌──────────────────────────────┐ │ │ ┌──────────────────────────────┐ │
│ │ Flush/recessed service lid │ │ │ │ Flush/recessed service lid │ │
@@ -22,6 +23,7 @@ Each camera node is two ESP boards in a small upright stand-mounted case. The ca
│ │ Small rocker power switch │ │ │ │ Small rocker power switch │ │
│ └──────────────────────────────┘ │ │ └──────────────────────────────┘ │
│ ESP-01S camera bridge ↔ ESP32-C3 │ │ ESP-01S camera bridge ↔ ESP32-C3 │
│ side USB-A female power output ────┼── USB cable ──→ GoPro power
└─────────────────────────────────────┘ └─────────────────────────────────────┘
``` ```
@@ -35,8 +37,10 @@ Each camera node is two ESP boards in a small upright stand-mounted case. The ca
| 3 mm power LED | 1 | <$1 | Separate always-power/5V indicator | | 3 mm power LED | 1 | <$1 | Separate always-power/5V indicator |
| 3 mm RGB status LED | 1 | <$1 | Replaces separate red/green status LEDs; firmware can map node states to color | | 3 mm RGB status LED | 1 | <$1 | Replaces separate red/green status LEDs; firmware can map node states to color |
| Small rocker switch | 1 | ~$1$3 | On/off switch; prototype CAD assumes 13 × 19 mm snap-in opening | | Small rocker switch | 1 | ~$1$3 | On/off switch; prototype CAD assumes 13 × 19 mm snap-in opening |
| USB-C female panel/breakout connector | 1 | ~$1$4 | Bottom power input; prototype CAD assumes ~10.5 × 4.5 mm rounded visible opening plus shallow underside recess; measure purchased part |
| USB-A female panel/breakout connector | 1 | ~$1$4 | Right-side GoPro power passthrough output; prototype CAD assumes ~16 × 8 mm side opening; measure purchased part |
| USB power bank (5000 mAh+) | 1 | ~$10 | Powers camera node and GoPro | | USB power bank (5000 mAh+) | 1 | ~$10 | Powers camera node and GoPro |
| Short USB cables / wiring | as needed | ~$2$5 | Power bank → node + GoPro; internal power/signal wiring | | Short USB cables / wiring | as needed | ~$2$5 | Power bank → node USB-C input; node 5 V passthrough → USB-A female → GoPro USB cable; internal power/signal wiring |
| M2 or small self-tapping screws | 4 | <$1 | Front service lid screws; pilot holes are parametric | | M2 or small self-tapping screws | 4 | <$1 | Front service lid screws; pilot holes are parametric |
| PETG filament | ~3550 g | ~$1 | 3D printed case body + lid | | PETG filament | ~3550 g | ~$1 | 3D printed case body + lid |
| Reusable cloth zip ties / Velcro straps | 2 | ~$1 | Primary stand mount through rear strap channels | | Reusable cloth zip ties / Velcro straps | 2 | ~$1 | Primary stand mount through rear strap channels |
@@ -48,7 +52,7 @@ Each camera node is two ESP boards in a small upright stand-mounted case. The ca
**Current source:** `hardware/case/camera-node-case-v4.scad` **Current source:** `hardware/case/camera-node-case-v4.scad`
**Pipeline:** `hardware/DESIGN_PIPELINE.md` **Pipeline:** `hardware/DESIGN_PIPELINE.md`
The current v4 CAD replaces the rejected wide/low electronics-box layout with a tall appliance-style enclosure matching the original upright reference: a clean vertical body, large inset front panel, OLED near the top, open blank middle area, two long rounded lower slots, and a bottom-center cable exit. It also replaces the v3 clamp/dovetail concept with a simpler strap-mounted field enclosure: The current v4 CAD replaces the rejected wide/low electronics-box layout with a tall appliance-style enclosure matching the original upright reference: a clean vertical body, large inset front panel, OLED near the top, open blank middle area, two long rounded lower slots, a bottom USB-C female power input, and a right-side USB-A female passthrough power port for the GoPro. It also replaces the v3 clamp/dovetail concept with a simpler strap-mounted field enclosure:
1. **Case body** — shell sized around ESP32-C3 Super Mini + ESP-01S with service/wiring clearance. 1. **Case body** — shell sized around ESP32-C3 Super Mini + ESP-01S with service/wiring clearance.
2. **Flush/recessed full-height front service lid** — screw-on front panel with locating lip and a restrained raised/recessed border. 2. **Flush/recessed full-height front service lid** — screw-on front panel with locating lip and a restrained raised/recessed border.
@@ -59,7 +63,7 @@ The current v4 CAD replaces the rejected wide/low electronics-box layout with a
- small rectangular rocker switch cutout. - small rectangular rocker switch cutout.
- two long rounded lower front slots styled after the reference appliance face. - two long rounded lower front slots styled after the reference appliance face.
4. **Rear strap channels** — two low-profile external belt-loop cloth zip-tie / Velcro strap paths to reduce rotation on a tripod/stand without visually dominating the body. 4. **Rear strap channels** — two low-profile external belt-loop cloth zip-tie / Velcro strap paths to reduce rotation on a tripod/stand without visually dominating the body.
5. **Bottom cable exit** — cable/strain-relief notch for USB/power wiring. 5. **USB power ports** — bottom USB-C female power input and right-side USB-A female passthrough power output for a GoPro USB power cable.
### Export wrappers ### Export wrappers
@@ -88,14 +92,14 @@ openscad -D 'part="preview"' -o hardware/case/camera-node-case-v4-preview.stl ha
openscad -D 'part="front_review"' -o hardware/case/camera-node-case-v4-front-review.stl hardware/case/camera-node-case-v4.scad openscad -D 'part="front_review"' -o hardware/case/camera-node-case-v4-front-review.stl hardware/case/camera-node-case-v4.scad
``` ```
`camera-node-case-v4-preview.stl` is the seated fit-check assembly. `camera-node-case-v4-front-review.stl` is a non-print review layout with the body and front panel separated so the OLED, LED, rocker, cable-relief, and lower-slot cutouts are obvious in a slicer. `camera-node-case-v4-preview.stl` is the seated fit-check assembly. `camera-node-case-v4-front-review.stl` is a non-print review layout with the body and front panel separated/angled so the OLED, LED, rocker, USB connector, and lower-slot cutouts are obvious in a slicer.
### Print Settings ### Print Settings
- **Material:** PETG preferred for heat/outdoor use and strap-tab durability. - **Material:** PETG preferred for heat/outdoor use and strap-tab durability.
- **Layer:** 0.2 mm typical. - **Layer:** 0.2 mm typical.
- **Infill:** 20% gyroid minimum; 30%+ recommended around rear strap bridges. - **Infill:** 20% gyroid minimum; 30%+ recommended around rear strap bridges.
- **Supports:** likely minimal/none depending on orientation; verify rear strap bridge spans and cable notch in slicer. - **Supports:** likely minimal/none depending on orientation; verify rear strap bridge spans and USB-C/USB-A port cutouts in slicer.
- **Post-processing:** fit 4 lid screws; deburr OLED/LED/switch cutouts; soften strap-channel edges if the printed radius is too sharp for cloth ties. - **Post-processing:** fit 4 lid screws; deburr OLED/LED/switch cutouts; soften strap-channel edges if the printed radius is too sharp for cloth ties.
## Expected Status Screen Content ## Expected Status Screen Content
@@ -120,16 +124,16 @@ Suggested fields:
```text ```text
USB Power Bank USB Power Bank
── USB-A → Camera Node Case ── USB-C cable → bottom USB-C female input on Camera Node Case
├── rocker switch → node power rail ├── rocker switch → node power rail
├── PWR LED indicator ├── PWR LED indicator
├── ESP32-C3 Super Mini ├── ESP32-C3 Super Mini
├── ESP-01S / ESP8266 ├── ESP-01S / ESP8266
├── 1.3-inch OLED display ├── 1.3-inch OLED display
── RGB status LED ── RGB status LED
└── 5 V passthrough rail → side USB-A female output
└── USB-A → GoPro USB port └── USB cable → GoPro USB port
(power only — no data) (power only — no data)
UART / control inside case: UART / control inside case:
ESP-01S TX ──→ ESP32-C3 RX ESP-01S TX ──→ ESP32-C3 RX
@@ -154,14 +158,14 @@ Travel Router ──(AP)──────────────────
Pi Hub (10.60.1.56) Pi Hub (10.60.1.56)
``` ```
The ESP8266/ESP-01S and GoPro talk over Wi-Fi. The only cable to the GoPro is USB power from the battery pack. The ESP8266/ESP-01S and GoPro talk over Wi-Fi. The only cable to the GoPro is USB power from the case side USB-A passthrough port.
## Field Setup ## Field Setup
1. Mount GoPro on tripod/stand. 1. Mount GoPro on tripod/stand.
2. Route two reusable cloth zip ties / Velcro straps through the rear v4 case channels. 2. Route two reusable cloth zip ties / Velcro straps through the rear v4 case channels.
3. Strap the case to a tripod/stand leg; use both strap paths to resist rotation. 3. Strap the case to a tripod/stand leg; use both strap paths to resist rotation.
4. Connect power bank to case and GoPro. 4. Connect the power bank to the case bottom USB-C input; connect the GoPro USB power cable to the case side USB-A passthrough output.
5. Toggle rocker switch on. 5. Toggle rocker switch on.
6. Verify PWR LED, RGB status LED, and OLED status: camera ID, REC state, battery, link, timer. 6. Verify PWR LED, RGB status LED, and OLED status: camera ID, REC state, battery, link, timer.
7. Monitor from `http://10.60.1.56:8080`. 7. Monitor from `http://10.60.1.56:8080`.
@@ -177,7 +181,9 @@ Prototype v4 nominal CAD dimensions:
| Front recessed lid | visible panel ~48 × 2 × 74; total with locating lip ~48 × 3 × 74 | | Front recessed lid | visible panel ~48 × 2 × 74; total with locating lip ~48 × 3 × 74 |
| OLED visible window assumption | ~31 × 16 | | OLED visible window assumption | ~31 × 16 |
| Rocker cutout assumption | ~13 × 19 | | Rocker cutout assumption | ~13 × 19 |
| Bottom USB-C power input cutout | ~10.5 × 4.5 opening with ~18 × 10 shallow underside recess |
| Right-side USB-A passthrough cutout | ~16 Y/front-back × 8 Z opening through side wall |
| Rear strap channels | two low-profile external belt-loop paths, ~33 mm usable slot width, ~4.2 mm strap-thickness clearance | | Rear strap channels | two low-profile external belt-loop paths, ~33 mm usable slot width, ~4.2 mm strap-thickness clearance |
| Board clearance targets | ESP32-C3 22.5 × 18 mm + ESP-01S 24.7 × 14.3 × 12 mm plus wiring/service clearance | | Board clearance targets | ESP32-C3 22.5 × 18 mm + ESP-01S 24.7 × 14.3 × 12 mm plus wiring/service clearance |
These dimensions are placeholders for the first CAD prototype. Measure the actual OLED module, rocker switch, LEDs, screws, USB cable bend radius, and strap width/thickness before committing to production prints. These dimensions are placeholders for the first CAD prototype. Measure the actual OLED module, rocker switch, LEDs, screws, USB-C/USB-A connector flanges and body depths, USB cable bend radius, and strap width/thickness before committing to production prints.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+36 -14
View File
@@ -12,6 +12,8 @@
// - Small rocker switch cutout: 13 x 19 mm rectangular snap-in opening. // - Small rocker switch cutout: 13 x 19 mm rectangular snap-in opening.
// - LEDs: two 3 mm panel LEDs (PWR + RGB STAT) with 3.2 mm holes. // - LEDs: two 3 mm panel LEDs (PWR + RGB STAT) with 3.2 mm holes.
// - Boards: ESP32-C3 Super Mini 22.5 x 18 mm, ESP-01S 24.7 x 14.3 x 12 mm. // - Boards: ESP32-C3 Super Mini 22.5 x 18 mm, ESP-01S 24.7 x 14.3 x 12 mm.
// - USB-C bottom power inlet and side USB-A passthrough are panel/breakout placeholders;
// measure purchased connector flanges/bodies before production prints.
$fn = 56; $fn = 56;
@@ -57,9 +59,16 @@ strap_bridge_y = strap_gap_y + 2.4;
strap_z1 = 23.0; strap_z1 = 23.0;
strap_z2 = 50.0; strap_z2 = 50.0;
// Cable exit // USB power connector placeholder cutouts
cable_notch_w = 13.0; usb_c_cutout_w = 10.5; // bottom USB-C female inlet visible opening, X width
cable_notch_h = 6.5; usb_c_cutout_d = 4.5; // bottom USB-C female inlet visible opening, Y/front-back
usb_c_recess_w = 18.0; // shallow underside panel-mount/breakout recess
usb_c_recess_d = 10.0;
usb_c_y = -7.5; // close to front/service side but clear of screw bosses/lower slots
usb_a_cutout_d = 16.0; // side USB-A female opening, Y/front-back dimension
usb_a_cutout_h = 8.0; // side USB-A female opening, Z height
usb_a_z = 26.0; // mid/lower right side, clear of front lid screws/strap bridges
usb_a_y = 2.0;
// ----- Utility geometry ----- // ----- Utility geometry -----
module rounded_box(size=[10,10,10], r=2, center_xy=true) { module rounded_box(size=[10,10,10], r=2, center_xy=true) {
@@ -77,6 +86,15 @@ module xz_rounded_prism(w, d, h, r=2) {
square([w-2*r, h-2*r], center=true); square([w-2*r, h-2*r], center=true);
} }
module yz_rounded_prism(d, x, h, r=2) {
// Rounded rectangle in the visible Y/Z plane, extruded through X.
// First argument maps to global Y, third argument maps to global Z.
rotate([0,90,0])
linear_extrude(height=x, center=true)
offset(r=r)
square([h-2*r, d-2*r], center=true);
}
module y_cylinder(d, h, center=true) { module y_cylinder(d, h, center=true) {
rotate([90,0,0]) cylinder(d=d, h=h, center=center); rotate([90,0,0]) cylinder(d=d, h=h, center=center);
} }
@@ -138,9 +156,16 @@ module camera_node_body_v4() {
translate([0, -case_d/2 + front_recess_d + wall + cavity_d/2, case_h/2]) translate([0, -case_d/2 + front_recess_d + wall + cavity_d/2, case_h/2])
cube([case_w - 2*wall, cavity_d, case_h - 2*wall], center=true); cube([case_w - 2*wall, cavity_d, case_h - 2*wall], center=true);
// Bottom center cable exit / strain-relief notch. // Bottom USB-C female power inlet: shallow underside recess plus
translate([0, -case_d/2 + 2.0, -0.05]) // rounded through-slot for a flush/panel-mount breakout placeholder.
xz_rounded_prism(cable_notch_w, 9.0, cable_notch_h, r=1.8); translate([0, usb_c_y, -0.35])
rounded_box([usb_c_recess_w, usb_c_recess_d, 0.9], r=1.5);
translate([0, usb_c_y, -0.2])
rounded_box([usb_c_cutout_w, usb_c_cutout_d, wall + 1.2], r=1.6);
// Right-side USB-A female passthrough power port for the GoPro.
translate([case_w/2 - 0.10, usb_a_y, usb_a_z])
yz_rounded_prism(usb_a_cutout_d, wall + 2.8, usb_a_cutout_h, r=0.9);
} }
// Four protected screw bosses are added after shell hollowing so the // Four protected screw bosses are added after shell hollowing so the
@@ -193,11 +218,6 @@ module camera_node_lid_v4() {
translate([0, panel_through_y, 33.0]) translate([0, panel_through_y, 33.0])
xz_rounded_prism(rocker_w, panel_through_d, rocker_h, r=0.8); xz_rounded_prism(rocker_w, panel_through_d, rocker_h, r=0.8);
// Bottom-center cable relief in the removable front panel so the cable
// exit is obvious and not visually hidden by the service lid.
translate([0, panel_through_y, 0.8])
xz_rounded_prism(cable_notch_w, panel_through_d, cable_notch_h, r=1.8);
// Two long rounded horizontal slots near the lower front, matching the reference. // Two long rounded horizontal slots near the lower front, matching the reference.
translate([0, panel_through_y, 17.0]) translate([0, panel_through_y, 17.0])
xz_rounded_prism(front_slot_w, panel_through_d, front_slot_h, r=front_slot_h/2 - 0.15); xz_rounded_prism(front_slot_w, panel_through_d, front_slot_h, r=front_slot_h/2 - 0.15);
@@ -227,16 +247,18 @@ module camera_node_preview_v4(show_lid=true) {
translate([0, -case_d/2 - 0.08, (case_h - lid_h)/2 + oled_z]) translate([0, -case_d/2 - 0.08, (case_h - lid_h)/2 + oled_z])
color("black") xz_rounded_prism(oled_bezel_w, 0.6, oled_bezel_h, r=1.3); color("black") xz_rounded_prism(oled_bezel_w, 0.6, oled_bezel_h, r=1.3);
// Internal board volume guides (not printed): ESP32-C3 and ESP-01S envelopes. // Internal board/connector volume guides (not printed): ESP modules and USB connector envelopes.
color([0,0.45,0,0.35]) translate([-9, -1, 26]) cube([22.5, 18, 4], center=true); color([0,0.45,0,0.35]) translate([-9, -1, 26]) cube([22.5, 18, 4], center=true);
color([0,0.2,0.8,0.35]) translate([9, -1, 45]) cube([24.7, 14.3, 12], center=true); color([0,0.2,0.8,0.35]) translate([9, -1, 45]) cube([24.7, 14.3, 12], center=true);
color([0.1,0.1,0.1,0.35]) translate([0, usb_c_y, 3.8]) cube([16, 9, 5], center=true);
color([0.1,0.1,0.1,0.35]) translate([case_w/2 - 5.5, usb_a_y, usb_a_z]) cube([11, usb_a_cutout_d + 2, usb_a_cutout_h + 2], center=true);
} }
// Non-print review layout: separates the body and front lid while keeping both // Non-print review layout: separates the body and front lid while keeping both
// front faces oriented toward -Y. Use this STL when checking that the screen, // front faces oriented toward -Y. Use this STL when checking that the screen,
// LED, rocker, cable, and lower-slot cutouts are visible in a slicer. // LED, rocker, USB connector, and lower-slot cutouts are visible in a slicer.
module camera_node_front_review_v4() { module camera_node_front_review_v4() {
translate([-34, 0, 0]) color("lightgray") camera_node_body_v4(); translate([-34, 0, 0]) rotate([0,0,-18]) color("lightgray") camera_node_body_v4();
translate([34, -case_d/2 + lid_t/2 + 0.03, (case_h - lid_h)/2]) translate([34, -case_d/2 + lid_t/2 + 0.03, (case_h - lid_h)/2])
color("gainsboro") camera_node_lid_v4(); color("gainsboro") camera_node_lid_v4();
} }