Parametric FreeCAD model of a replacement motor-drive insert that plugs into a cardboard roller-blind tube and couples it to a NEMA-17 / 5 mm motor shaft with an M3 radial set screw.
All geometry is generated from scratch by
create_roller_blind_insert.py using the
FreeCAD 1.x Python API (Part workbench). The authoritative dimensions live once
at the top of that script and are mirrored into an editable Parameters
spreadsheet inside the .FCStd. The Kiri Engine scan was used only as a rough
visual proportion reference — no critical dimension is derived from it (the
optional /mnt/data/3DModel.zip was not present on this machine; it is not
required, since the measured dimensions are authoritative).
There are two versions of the insert. V1 uses a round shaft bore plus an M3
radial set screw. V2 (*_d_bore) is optimized for the actual NEMA-17
D-shaft: it has a blind D-shaped bore and no set-screw hardware at all. The
roller-tube interface (body, ribs, flange) and the motor-housing envelope are
identical between the two versions.
| File | Description |
|---|---|
| V1 — round bore + M3 set screw | |
roller_blind_motor_insert.FCStd |
Editable parametric model (feature tree + Parameters spreadsheet). |
roller_blind_motor_insert.step |
Exact B-rep solid (STEP AP214). |
roller_blind_motor_insert.3mf |
High-quality watertight mesh for BambuStudio (mm, unscaled). |
| V2 — D-shaft bore, no set screw | |
roller_blind_motor_insert_d_bore.FCStd |
Editable parametric D-bore model (standard fit). |
roller_blind_motor_insert_d_bore.step |
Exact B-rep D-bore solid. |
roller_blind_motor_insert_d_bore.3mf |
Primary D-bore print — standard-fit mesh for BambuStudio. |
nema17_d_bore_fit_test.3mf |
Small T/S block: one tight + one standard D-bore for a hand shaft-fit test. |
d_bore_section.svg |
XY cross-section through the housing (visual bore inspection). |
| Shared | |
roller_blind_insert_fit_test.FCStd |
Editable source for the short tube-fit coupon. |
roller_blind_insert_fit_test.3mf |
First 15 mm of the insertion end (body + ribs) for tube-fit testing. |
create_roller_blind_insert.py |
The parametric generator (re-run to rebuild everything). |
validation_report.json |
Machine-readable validation output from the last build. |
/Applications/FreeCAD.app/Contents/Resources/bin/freecadcmd create_roller_blind_insert.pyEdit a value in PARAMS (or in the Parameters spreadsheet for the live main
primitives) and re-run to produce a freshly validated solid and all exports.
The part is concentric about the Z axis, built bottom → top with the
insertion tip at Z = 0:
Z = 43.3 ┌───┐ top of motor housing / shaft-bore entrance
│ │ Ø9.0 motor-shaft housing (M3 set screw at Z=38.3, +X)
Z = 33.3 ┌┴───┴┐ top of flange
│ │ Ø24.5 flat flange (4.8 thick)
Z = 28.5 └┐ ┌┘ flange underside (blind bore bottom at Z=28.3)
│▓▓▓│ Ø13.5 ribbed main body
Z = 23.5 │███│ ribs full height (Ø16.5 tip) ─┐
│███│ ├ 18 mm rib
Z = 10.5 │███│ full-height rib section (13 mm) │ total
│╲ ╱│ tapered rib section (5 mm, 1.5→0 mm) │
Z = 5.5 │ │ rib-free insertion lead-in ──────────────┘
Z = 0.0 └───┘ insertion tip (0.4 chamfer)
- Main body — Ø13.5 mm × 28.5 mm,
Z 0 → 28.5, 0.4 mm insertion chamfer. - Four retention ribs at 0/90/180/270°. Each rib has a curved outer face
swept at the rib-tip radius, so the maximum tip-to-tip diameter is exactly
16.5 mm (no over-square corners). Tangential width 2.5 mm; 1.5 mm radial
height above the body. Full height
Z 10.5 → 23.5(13 mm); linear taperZ 5.5 → 10.5(5 mm) ramping the radial height 0 → 1.5 mm; no rib belowZ 5.5. The taper outer face is a true cone section (radius 6.75 → 8.25 mm). - Flange — Ø24.5 mm × 4.8 mm,
Z 28.5 → 33.3. - Motor housing — Ø9.0 mm × 10.0 mm,
Z 33.3 → 43.3. - Shaft bore — Ø5.1 mm, blind, 15 mm deep from the top (
Z 43.3 → 28.3), 0.4 mm entry chamfer. - M3 set screw — Ø3.2 mm radial passage along +X at
Z = 38.3, intersecting the shaft bore, with a compact +X boss for engagement (below).
Robust Part-workbench booleans, reproducible from Python:
- Main body cylinder.
- One rib = (tip-cylinder ∩ box) ∪ (cone ∩ box) → curved tip + coned taper.
- Four ribs by 90° rotation, fused into
RetentionRibPattern. - Fuse body + ribs + flange + housing + set-screw boss (
InsertBody). - Cut the blind shaft bore, then the radial set-screw passage.
- Apply fillets/chamfers as parametric features with automatic radius fallback.
- Validate (
isValid, single solid, bounding box) and export.
Named feature tree (no Fusion001-style names): Parameters, MainBody,
RetentionRibPattern, Flange, MotorHousing, SetScrewBoss, InsertBody,
ShaftBore, BoredBody, SetScrewPassage, SetScrewBored, RibRootFillet,
BodyFlangeFillet, InsertionChamfer, BoreEntryChamfer, FlangeEdgeBreak
(top feature labelled FinalInsert). The main axial primitives are live
Part::Cylinder objects bound to the Parameters spreadsheet by expressions,
so they update on edit; the rib pattern is regenerated by the script (the
authoritative parametric generator).
The housing is Ø9.0 mm with a Ø5.1 mm bore, so the plain radial wall is only
(9.0 − 5.1) / 2 = 1.95 mm. That is too thin for a robust M3 heat-set insert
pocket, so no heat-set pocket is cut — it would leave a structurally invalid
wall. Instead a compact flat boss (2.75 mm radius, reaching X = 6.0 mm) is
added on the +X side only, giving roughly 3.45 mm of material along the screw
axis (from the bore wall at R2.55 to the boss face at X6.0) for an M3 screw to
engage a nut, a manually tapped thread, or a future insert. The boss stays well
inside the Ø24.5 flange envelope, so it does not enlarge the bounding box.
This is the only feature that breaks perfect rotational symmetry, and only in
the set-screw region, as specified.
Every noncritical blend was attempted at its target value with incremental fallback; all succeeded at their full target in this build:
| Feature | Target | Applied |
|---|---|---|
| Rib-root fillet | 0.5 mm | 0.5 mm |
| Body↔flange underside | 1.0 mm | 1.0 mm |
| Insertion chamfer | 0.4 mm | 0.4 mm |
| Bore-entry chamfer | 0.4 mm | 0.4 mm |
| Flange edge break | 0.25 mm | 0.25 mm |
If a future parameter change makes any blend fail, the generator automatically reduces it (0.1 mm steps, down to a small floor) or omits it, always preserving the authoritative body, rib-tip (16.5 mm), flange, and housing dimensions.
Independently re-read from the exported STEP/3MF, not just the build session:
| Check | Result |
|---|---|
Shape.isValid() |
True |
| Number of solids | 1 (single fused, manifold solid) |
| Bounding box (X × Y × Z) | 24.5 × 24.5 × 43.3 mm |
| Overall axial length | 43.3 mm (28.5 + 4.8 + 10.0 ✓) |
| Z extents | 0.0 → 43.3 mm (insertion tip at Z = 0 ✓) |
| Main body diameter | 13.5 mm |
| Max rib-tip diameter | 16.5 mm (exact) |
| Max overall diameter (flange) | 24.5 mm |
| Housing diameter | 9.0 mm |
| Shaft bore diameter / depth | 5.1 mm / 15.0 mm blind (bottom Z = 28.3) |
| Estimated volume | ≈ 6922 mm³ |
| Export mesh | 17 114 facets, watertight, non-manifold-free |
| 3MF re-import bounding box | 24.5 × 24.5 × 43.3 mm (mm preserved, unscaled) |
Fit-test coupon: valid single solid, 16.5 × 16.5 × 15.0 mm, ≈ 2249 mm³.
A second version optimized for the actual NEMA-17 D-shaft. The roller-tube interface (Ø13.5 body, four ribs, Ø16.5 tip), the Ø24.5 flange, the Ø9 × 10 mm housing, and the 43.3 mm overall length are unchanged. The only differences:
- All set-screw hardware removed — no radial M3 passage, no boss, no heat-set recess, no captive nut, no external asymmetry. The part is now fully rotationally symmetric except for the four retention ribs and the single internal D flat.
- The round Ø5.1 bore is replaced by a compound blind bore matching the real shaft (round shoulder at the motor face, then D-flat to the tip).
The shaft has ~4 mm of fully round Ø5 shaft at the motor face, then a 15 mm D-flat to the tip (~19 mm total). A bore that is D-shaped the whole way cannot accept the round shoulder, so the bore is now compound, from the top of the motor housing (Z = 43.3) downward:
| Section | Depth | Z range | Profile |
|---|---|---|---|
| Round entrance | 4.0 mm | 43.3 → 39.3 | full circle Ø5.30 (clears the round shoulder) |
| D torque section | 15.0 mm | 39.3 → 24.3 | Ø5.30 circle truncated by the −X flat |
| Total (blind) | 19.0 mm | 43.3 → 24.3 | bottom is solid (blind), vented on-axis |
Axial vent (added): a Ø2 mm hole on the axis runs from the blind-bore bottom (Z = 24.3) straight out through the tip (Z = 0). Because the bore has no set-screw hole, it is otherwise a fully sealed pocket — a close-fitting shaft acts as a piston and trapped air (plus suction on withdrawal) can stop it seating partway. The vent lets that air escape into the tube interior so the shaft can reach full depth. It does not touch the D torque surfaces.
The D flat is a circular profile truncated by one straight chord on the
−X side (flat_opp = 4.80 at the calibrated DC 0.30 fit), parallel to Z, and
the full 15 mm of it does the torque transfer. A 0.4 mm chamfer eases the
round→D transition (it sits in the round section, so the 15 mm D engagement is
not reduced). The round mouth gets a 0.2 mm entry chamfer.
Section-view validation (sampled from the solid): the top 4 mm reads fully circular (−X extent = −2.64 ≈ full radius), the next 15 mm reads D-shaped (−X extent = −2.14 = the flat), total depth 19.0 mm, blind bottom solid, centred.
Because the bore is blind you can't see the flat's clocking while sliding the insert onto the shaft. A Ø3 mm × 1 mm dimple is recessed into the flange top face on the −X side (radius 10 mm), aligned with the internal flat — line the dimple up with the shaft's flat and it drops straight on.
The insert prints tip-down, so the flange underside (the Ø24.5 disk
overhanging the Ø13.5 body) would be a flat horizontal overhang and print poorly.
That underside is replaced with a 45° conical funnel (FlangeFunnelHeight
= 5.5 mm, Z 23.0 → 28.5) flaring from the body diameter up to the flange OD. At
45° each layer steps out by one layer height, so it is self-supporting — no
supports, no sagging underside. The flange OD, thickness at the rim, top face,
housing, ribs (Ø16.5 tips preserved), and bore are unchanged; the tube end now
seats against the cone, which also helps centre it.
The measurements given were: Ø5.0 circular, 3.5 mm flat width, 4.5 mm flat-to-opposite-curve. Those three cannot all be exact for a single-chord truncation of a 5.0 mm circle:
- A Ø5.0 circle cut to a 4.5 mm flat-to-opposite depth geometrically yields a 3.0 mm flat width (not 3.5).
- Getting a 3.5 mm flat and 4.5 mm depth would require a Ø5.18 mm circle, contradicting the "Ø5.0 circular profile / do not use a 5.1 round bore" rule.
A real 5.0 / 4.5 NEMA-17 D-shaft is in fact ~3.0 mm across the flat; the 3.5 mm
reading is a slight caliper over-read on the rounded flat edges. The diameter
and the flat-to-opposite depth are the fit-critical values, so they are honoured
exactly and the flat width is taken as the geometric consequence (~3.0 mm).
This makes the bore match the shaft's true envelope rather than cutting the flat
too shallow. If your shaft really does measure Ø5.18-ish, change DBORE_FITS in
the generator and re-run.
The bore is the shaft plus a printing clearance, using a uniform radial-gap
model: a gap g offsets the whole D outward, so both the circular diameter and
the flat-to-opposite grow by 2g. Fits are parameterised by the diametral
clearance DC = 2g — how much larger the round bore is than the 5.0 mm shaft.
Why the first fit test failed. v2's original bores used DC = 0.05 / 0.10 mm (Ø5.05 / Ø5.10). On FDM, holes print 0.1–0.3 mm undersized (inner-perimeter over-extrusion + contraction), so those bores came out ≤ 5.0 mm and bound on the shaft. Realistic slip-fit clearances for a 5 mm shaft in PETG are more like DC ≈ 0.3–0.6 mm. That is what the new ladder brackets.
Named variants (DBORE_CLEARANCE in the generator):
| Variant | DC | Circular Ø | Flat-to-opposite | Flat width | Min housing wall |
|---|---|---|---|---|---|
| snug | 0.20 | 5.20 mm | 4.70 mm | 3.07 mm | 1.90 mm |
| standard ★ | 0.30 | 5.30 mm | 4.80 mm | 3.10 mm | 1.85 mm |
| loose | 0.45 | 5.45 mm | 4.95 mm | 3.15 mm | 1.78 mm |
★ Calibrated: on the ladder print, bore 3 (DC 0.30 mm) was the best fit
on this Bambu/PETG setup, so standard is set to DC 0.30 and is the primary
_d_bore export. (Re-run the ladder if you change filament or printer.)
A compact 49 × 16 × 17 mm block with five blind 15 mm-deep D-bores (flats on −X), engraved on the top face with the clearance in tenths of a millimetre:
| Label | 3 |
4 |
5 |
6 |
7 |
|---|---|---|---|---|---|
| Diametral clearance DC | 0.30 | 0.40 | 0.50 | 0.60 | 0.70 mm |
| Circular bore Ø | 5.30 | 5.40 | 5.50 | 5.60 | 5.70 mm |
Prints in a few minutes. Push the real motor shaft into each by hand; the label
of the bore that gives a firm-but-seats-fully fit is your DC. Then set the
production bore to that value (edit DBORE_CLEARANCE["standard"] or add the exact
DC and re-run) and reprint the primary _d_bore part.
| Check | Result |
|---|---|
Shape.isValid() / solids |
True / 1 (single manifold solid) |
| Overall bounding box | 24.5 × 24.5 × 43.3 mm (unchanged from V1) |
| Bore (compound) depth | 19.0 mm blind (4 round + 15 D, bottom Z = 24.3) |
| Circular bore diameter (standard DC 0.30) | 5.30 mm |
| Flat chord width (derived) | 3.10 mm |
| Flat-to-opposite-curve | 4.80 mm |
| Flat position | X = −2.15 mm, flat parallel to Z, on −X side |
| Minimum housing wall thickness | 1.85 mm (continuous — no radial holes) |
| D profile constant over full depth | Yes — section at Z = 28.8 / 35.8 / 42.8 identical |
| Section topology (mid-housing) | outer circle R4.5 + D void (1 arc + 1 flat line) |
| Volume | ≈ 6927 mm³ |
| 3MF re-import bbox / watertight | 24.5 × 24.5 × 43.3 mm / watertight, manifold |
Section view for visual inspection: d_bore_section.svg.
Strength check: the housing wall is continuous all the way around (the standard D-bore reaches only R2.65 on the curved side vs. the R4.5 housing wall → 1.85 mm min wall), there are no radial holes, and removing the set screw makes this version mechanically stronger than V1. Torque now transfers through the full 15 mm D flat instead of a single set screw.
Intended print material: PETG.
- The 13.5 mm main body is sized for the inside of the cardboard tube.
- The four ribs create a 16.5 mm rib-tip diameter; the cardboard is expected to flex slightly around the ribs.
- The ribs are intended to wedge tightly and transfer motor torque to the tube.
- The bottom 5 mm insertion-tip region is rib-free, so the insert starts into the tube easily.
- The 5 mm tapered rib section then progressively increases the interference fit as the insert is pushed home.
- Print a test fit first (use
roller_blind_insert_fit_test.3mf) before applying full motor torque — cardboard tube ID varies.
- Filament: PETG
- Layer height: 0.20 mm
- Walls / perimeters: 4–5
- Top layers: 5 · Bottom layers: 5
- Infill: 40–60 %, gyroid or cubic
- Slow external walls
- No supports (unless the set-screw boss overhang needs them)
Exported already oriented for printing: insertion end on the build plate, Z axis vertical, motor housing pointing up. No supports, rafts, or brims are baked into the 3MF — configure slicing in BambuStudio.