For anyone who missed Marsupial's

Build your own HID-mouse compatible spinner project, here are two parametric mounts created in OpenSCAD.

The first one has a chamfered bezel.

- The OpenSCAD code generates a model with both the nut and the mount.

- The .zip files linked below reorient the mount so it is print-ready. (i.e. face down)

- Be sure to download the .zip files for both the desired mount

**and** the nut. The mount .zip files

*do not* include the nut.

`// Rotary encoder mount and nut created using thread library found at https://www.thingiverse.com/thing:31363`

// Metric Screw Thread Library

// by Maximilian Karl <karlma@in.tum.de> (2012)

//

//

// only use module thread(P,D,h,step)

// with the parameters:

// P - screw thread pitch

// D - screw thread major diameter

// h - screw thread height

// step - step size in degree

//

module screwthread_triangle(P) {

difference() {

translate([-sqrt(3)/3*P+sqrt(3)/2*P/8,0,0])

rotate([90,0,0])

cylinder(r=sqrt(3)/3*P,h=0.00001,$fn=3,center=true);

translate([0,-P/2,-P/2])

cube([P,P,P]);

}

}

module screwthread_onerotation(P,D_maj,step) {

H = sqrt(3)/2*P;

D_min = D_maj - 5*sqrt(3)/8*P;

for(i=[0:step:360-step])

hull()

for(j = [0,step])

rotate([0,0,(i+j)])

translate([D_maj/2,0,(i+j)/360*P])

screwthread_triangle(P);

translate([0,0,P/2])

cylinder(r=D_min/2,h=2*P,$fn=360/step,center=true);

}

module thread(P,D,h,step) {

for(i=[0:h/P])

translate([0,0,i*P])

screwthread_onerotation(P,D,step);

}

//

////////////////////////////////////////////

//

// Variables:

//

////////////////////////////////////////////

ThreadPitch = 1; // Screw thread pitch

ThreadMajorDiameter = 49; // Screw thread major diameter

ThreadedRodHeight = 23.8; // Threaded rod height

ThreadStep = 2; // Thread step size in degrees

PlateThick = 2.4; // Mount plate/bezel thickness

BezelTopDia = 50; // Bezel top diameter

BezelBottomDia = 55; // Bezel bottom diameter

BezelCenterHole = 21; // Bezel center hole

ScrewHoleBottom = 3.45; // Bottom of screw hole diameter

ScrewHoleTop = 3.45; // Top of screw hole diameter, for non-countersunk screws use same value as ScrewHoleBottom

ScrewDistance = 15; // Distance from center of shaft to center of screw hole, usually 14 or 15

CenterCylinder = 40; // Center cylinder diameter

NutDiameter = 64; // Nut diameter (point-to-point)

NutThickness = 4; // Nut thickness

WiggleRoom = 1.02; // Scale multiplier for threaded rod X-axis and Y-axis that allows nut to turn easier

NutOffsetX = 70; // X-axis offset distance of nut

//

// Number of fragments (polygon sides) used to render a full circle.

$fn = 180; // Default = 180 Typical range = 6 - 360

// 6 will render a circular hole as a hexagon, 8 will render a circular hole as an octagon.

// Lower the number for faster rendering, raise the number for smoother rendering.

//

////////////////////////////////////////////

//

// Make the part:

//

////////////////////////////////////////////

// Mount

// Bezel/mount plate minus screw holes and center hole

difference() {

translate ([0, 0, ThreadedRodHeight + (PlateThick/2)])

cylinder (PlateThick, d1=BezelBottomDia, d2=BezelTopDia,center=true); // Bezel/mount plate

translate ([0, 0, ThreadedRodHeight + (PlateThick/2)])

rotate ([0, 0, 0])

translate ([ScrewDistance, 0, 0])

cylinder (PlateThick + 0.01, d1=ScrewHoleBottom, d2=ScrewHoleTop,center=true); // Screw hole 1

translate ([0, 0, ThreadedRodHeight + (PlateThick/2)])

rotate ([0, 0, 120])

translate ([ScrewDistance, 0, 0])

cylinder (PlateThick + 0.01, d1=ScrewHoleBottom, d2=ScrewHoleTop,center=true); // Screw hole 2

translate ([0, 0, ThreadedRodHeight + (PlateThick/2)])

rotate ([0, 0, 240])

translate ([ScrewDistance, 0, 0])

cylinder (PlateThick + 0.01, d1=ScrewHoleBottom, d2=ScrewHoleTop,center=true); // Screw hole 3

translate ([0, 0, ThreadedRodHeight + (PlateThick/2)])

cylinder (PlateThick + 0.1, d=BezelCenterHole,center=true); // Center hole

} // End bezel/mount plate minus screw holes and center hole

//

// Threaded rod minus center cylinder and trim top

difference() {

translate ([0, 0, ThreadPitch/2])

thread(ThreadPitch, ThreadMajorDiameter, ThreadedRodHeight, ThreadStep); // Threaded rod

translate ([0, 0, ThreadedRodHeight/2])

cylinder (ThreadedRodHeight + 20, d=CenterCylinder,center=true); // Center cylinder

translate ([0, 0, (ThreadedRodHeight * 1.5) + 0.01])

cube([ThreadMajorDiameter + 20, ThreadMajorDiameter + 20, ThreadedRodHeight], center=true); // Trim top

} // End threaded rod minus center cylinder and trim top

//

// Nut

difference() { // Nut body minus threaded rod

hull() { // Nut Body

translate ([NutOffsetX, 0, NutThickness/2])

rotate ([0, 0, 0])

translate ([NutDiameter/2, 0, 0])

cylinder (NutThickness, d = 0.01, center=true);

translate ([NutOffsetX, 0, NutThickness/2])

rotate ([0, 0, 60])

translate ([NutDiameter/2, 0, 0])

cylinder (NutThickness, d = 0.01, center=true);

translate ([NutOffsetX, 0, NutThickness/2])

rotate ([0, 0, 120])

translate ([NutDiameter/2, 0, 0])

cylinder (NutThickness, d = 0.01, center=true);

translate ([NutOffsetX, 0, NutThickness/2])

rotate ([0, 0, 180])

translate ([NutDiameter/2, 0, 0])

cylinder (NutThickness, d = 0.01, center=true);

translate ([NutOffsetX, 0, NutThickness/2])

rotate ([0, 0, 240])

translate ([NutDiameter/2, 0, 0])

cylinder (NutThickness, d = 0.01, center=true);

translate ([NutOffsetX, 0, NutThickness/2])

rotate ([0, 0, 300])

translate ([NutDiameter/2, 0, 0])

cylinder (NutThickness, d = 0.01, center=true);

} // End nut body

//

translate ([NutOffsetX, 0, - ThreadPitch])

scale([WiggleRoom, WiggleRoom, 1])

thread(ThreadPitch, ThreadMajorDiameter, ThreadedRodHeight, ThreadStep); // Threaded rod

//

} // End nut body minus threaded rod

//

The second one has a rounded bezel.

- The OpenSCAD code generates a model with both the nut and the mount.

- The .zip files linked below reorient the mount so it is print-ready. (i.e. face down)

- Be sure to download the .zip files for both the desired mount

**and** the nut. The mount .zip files

*do not* include the nut.

`// Rotary encoder mount and nut created using thread library found at https://www.thingiverse.com/thing:31363`

// Metric Screw Thread Library

// by Maximilian Karl <karlma@in.tum.de> (2012)

//

//

// only use module thread(P,D,h,step)

// with the parameters:

// P - screw thread pitch

// D - screw thread major diameter

// h - screw thread height

// step - step size in degree

//

module screwthread_triangle(P) {

difference() {

translate([-sqrt(3)/3*P+sqrt(3)/2*P/8,0,0])

rotate([90,0,0])

cylinder(r=sqrt(3)/3*P,h=0.00001,$fn=3,center=true);

translate([0,-P/2,-P/2])

cube([P,P,P]);

}

}

module screwthread_onerotation(P,D_maj,step) {

H = sqrt(3)/2*P;

D_min = D_maj - 5*sqrt(3)/8*P;

for(i=[0:step:360-step])

hull()

for(j = [0,step])

rotate([0,0,(i+j)])

translate([D_maj/2,0,(i+j)/360*P])

screwthread_triangle(P);

translate([0,0,P/2])

cylinder(r=D_min/2,h=2*P,$fn=360/step,center=true);

}

module thread(P,D,h,step) {

for(i=[0:h/P])

translate([0,0,i*P])

screwthread_onerotation(P,D,step);

}

//

////////////////////////////////////////////

//

// Variables:

//

////////////////////////////////////////////

ThreadPitch = 1; // Screw thread pitch

ThreadMajorDiameter = 49; // Screw thread major diameter

ThreadedRodHeight = 23.8; // Threaded rod height

ThreadStep = 2; // Thread step size in degrees

PlateThick = 2.4; // Mount plate/bezel thickness

Roundover = 2.2; // Bezel roundover, must be less than PlateThick

BezelDia = 55; // Bezel diameter

BezelCenterHole = 21; // Bezel center hole

ScrewHoleBottom = 3.45; // Bottom of screw hole diameter

ScrewHoleTop = 3.45; // Top of screw hole diameter, for non-countersunk screws use same value as ScrewHoleBottom

ScrewDistance = 15; // Distance from center of shaft to center of screw hole, usually 14 or 15

CenterCylinder = 40; // Center cylinder diameter

NutDiameter = 64; // Nut diameter (point-to-point)

NutThickness = 4; // Nut thickness

WiggleRoom = 1.02; // Scale multiplier for threaded rod X-axis and Y-axis that allows nut to turn easier

NutOffsetX = 70; // X-axis offset distance of nut

//

// Number of fragments (polygon sides) used to render a full circle.

$fn = 180; // Default = 180 Typical range = 6 - 360

// 6 will render a circular hole as a hexagon, 8 will render a circular hole as an octagon.

// Lower the number for faster rendering, raise the number for smoother rendering.

//

////////////////////////////////////////////

//

// Make the part:

//

////////////////////////////////////////////

// Mount

// Bezel/mount plate minus screw holes and center hole

difference() {

minkowski() // Apply roundover to cylinder

{

translate ([0, 0, ThreadedRodHeight])

cylinder(d=(BezelDia)-(Roundover*2),h=(PlateThick) - Roundover); // Bezel/mount plate body

sphere(r=Roundover); // Roundover

}

translate ([0, 0, ThreadedRodHeight/2])

cube([BezelDia + 20, BezelDia + 20, ThreadedRodHeight], center=true); // Trim bottom of bezel/mount plate body

translate ([0, 0, ThreadedRodHeight + (PlateThick/2)])

rotate ([0, 0, 0])

translate ([ScrewDistance, 0, 0])

cylinder (PlateThick + 0.01, d1=ScrewHoleBottom, d2=ScrewHoleTop,center=true); // Screw hole 1

translate ([0, 0, ThreadedRodHeight + (PlateThick/2)])

rotate ([0, 0, 120])

translate ([ScrewDistance, 0, 0])

cylinder (PlateThick + 0.01, d1=ScrewHoleBottom, d2=ScrewHoleTop,center=true); // Screw hole 2

translate ([0, 0, ThreadedRodHeight + (PlateThick/2)])

rotate ([0, 0, 240])

translate ([ScrewDistance, 0, 0])

cylinder (PlateThick + 0.01, d1=ScrewHoleBottom, d2=ScrewHoleTop,center=true); // Screw hole 3

translate ([0, 0, ThreadedRodHeight + (PlateThick/2)])

cylinder (PlateThick + 0.1, d=BezelCenterHole,center=true); // Center hole

} // End bezel/mount plate minus screw holes and center hole

//

// Threaded rod minus center cylinder and trim top

difference() {

translate ([0, 0, ThreadPitch/2])

thread(ThreadPitch, ThreadMajorDiameter, ThreadedRodHeight, ThreadStep); // Threaded rod

translate ([0, 0, ThreadedRodHeight/2])

cylinder (ThreadedRodHeight + 20, d=CenterCylinder,center=true); // Center cylinder

translate ([0, 0, (ThreadedRodHeight * 1.5) + 0.01])

cube([ThreadMajorDiameter + 20, ThreadMajorDiameter + 20, ThreadedRodHeight], center=true); // Trim top

} // End threaded rod minus center cylinder and trim top

//

// Nut

difference() { // Nut body minus threaded rod

hull() { // Nut Body

translate ([NutOffsetX, 0, NutThickness/2])

rotate ([0, 0, 0])

translate ([NutDiameter/2, 0, 0])

cylinder (NutThickness, d = 0.01, center=true);

translate ([NutOffsetX, 0, NutThickness/2])

rotate ([0, 0, 60])

translate ([NutDiameter/2, 0, 0])

cylinder (NutThickness, d = 0.01, center=true);

translate ([NutOffsetX, 0, NutThickness/2])

rotate ([0, 0, 120])

translate ([NutDiameter/2, 0, 0])

cylinder (NutThickness, d = 0.01, center=true);

translate ([NutOffsetX, 0, NutThickness/2])

rotate ([0, 0, 180])

translate ([NutDiameter/2, 0, 0])

cylinder (NutThickness, d = 0.01, center=true);

translate ([NutOffsetX, 0, NutThickness/2])

rotate ([0, 0, 240])

translate ([NutDiameter/2, 0, 0])

cylinder (NutThickness, d = 0.01, center=true);

translate ([NutOffsetX, 0, NutThickness/2])

rotate ([0, 0, 300])

translate ([NutDiameter/2, 0, 0])

cylinder (NutThickness, d = 0.01, center=true);

} // End nut body

//

translate ([NutOffsetX, 0, - ThreadPitch])

scale([WiggleRoom, WiggleRoom, 1])

thread(ThreadPitch, ThreadMajorDiameter, ThreadedRodHeight, ThreadStep); // Threaded rod

//

} // End nut body minus threaded rod

//

**Installation instructions:**1. Drill a 2"/50mm hole in your 3/4" thick (or less) control panel.

2. Fasten the mount to the CP using the nut.

- Keep in mind that it is very easy to cross-thread if the nut isn't kept level.

- Use the "turn the nut backward until you hear a click then turn it forward" trick to avoid cross-threading.

3. Fasten the encoder to the mount using M3-0.5 x 8mm screws.

4. Install the knob.

---------------------------------------------

Links to .ZIPped, ready-to-print .STL files made using the OpenSCAD code above:

Chamfered mount -

http://forum.arcadecontrols.com/index.php?action=dlattach;topic=164992.0;attach=387887 Nut -

http://forum.arcadecontrols.com/index.php?action=dlattach;topic=164992.0;attach=387888 Roundover mount -

http://forum.arcadecontrols.com/index.php?action=dlattach;topic=164992.0;attach=387889*** Be sure to download both the desired mount

**and** the nut. (the mount .zip files

*do not* include the nut) ***

Scott