discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Nut needed for nutless pot

T
Terry
Wed, Jun 14, 2023 2:09 PM

It's a very long time since I used OpenSCAD and my printer, so 'rusty'
would be a gross understatement ;-) But to finish my current (hobby
electronics) project I need a nut to fit a '10 mm' pot.

Embedded images made my earlier post attempt too large so have used
links instead.

https://www.dropbox.com/s/84qorbyh9ueskzf/Dimensions.jpg?raw=1

I have a dozen or so pots, probably none under 40 years old, which are
without their nuts. I tried the hundred or so of my 'spare' nuts in vain

https://www.dropbox.com/s/eutnqjdw869s955/PotNutFails.jpg?raw=1

Strangely, the only thing that worked was this enormous nut, 6.45 mm
thick, with only 3 threads in that length. (That's approx,as I'm unclear
about the start and end points for measuring pitch.) And obviously far
too bulky to use.

https://www.dropbox.com/s/gw2hfkp1pp2bizd/LargeNut.jpg?raw=1

I could order an appropriate pot with accompanying nut, but I hate to
waste stuff. Once I have a nut for today's job I'll make a bunch of
them.

I downloaded Nut_job.scad from this promising page:
https://www.thingiverse.com/thing:193647/files

And then tentatively customised it to get the code below, which I'll
paste in full at the end.

https://www.dropbox.com/s/8i4hwzc689rjgfm/NutJob-1.jpg?raw=1

But before I re-learn the little OpenSCAD I once knew, dust off my Ender
3 V2 etc, could I please get advice on the appropriateness or otherwise
of that code. Or even a 'starter example' based on one of the libraries,
such as NopHead's NopSCADlib or BOSL2.

In a nutshell (sorry), I'm frankly looking for a quick practical
solution, postponing study until later.

The code:

/* 'Nut Job' nut, bolt, washer and threaded rod factory by Mike Thompson
1/12/2013, Thingiverse: mike_linus
*

  • Licensing: This work is licensed under a Creative Commons
    Attribution-NonCommercial-ShareAlike 3.0 Australia License.
  • Further information is available here -
    http://creativecommons.org/licenses/by-nc-sa/3.0/au/deed.en_GB
  • v2 8/12/2013 - added socket head types
  • v3 2/11/2014 - adjusted wing nut algorithm for better behaviour with
    unusual nut sizes and added ISO262 metric references
  • v4 31/12/2014 - added optional texture to socket heads, added ability
    to change the number of facets for a hex head
  • and adjusted wingnut base level on certain nut sizes
  • v5 11/1/2015 - added phillips and slot drive types and improved
    texture handling
  • v6 21/2/2015 - added wing ratio to wingnuts
  • v7 6/3/2016 - added extended options to control number of facets on
    nuts, square sockets (or any number of facets) and socket depth control
  • v8 1/1/2017 - modified library code to remove dependence on
    deprecated 'assign' statement
  • This script generates nuts, bolts, washers and threaded rod using the
    library
  • script: polyScrewThead.scad (modified/updated version
    polyScrewThread_r1.scad)
  • http://www.thingiverse.com/thing:8796, CC Public Domain
  • Defaults are for a 8mm diameter bolts, rod, matching nuts and wing
    nuts that work well together
  • without cleanup or modification. Some default parameters such as the
    nut outer diameter are deliberately
  • altered to produce a snug fit that can still be hand tightened. This
    may need to be altered
  • depending on individual printer variances, slicing tools, filament
    etc. Suggest printing a matching
  • bolt and nut and adjusting as necessary.  Note: slow print speeds,
    low temperatures and solid
  • fill are recommended for best results.
    */

/* [Component Type] */

type     = "bolt";//[nut,bolt,rod,washer]

/* [Bolt and Rod Options] */

//Head type - Hex, Socket Cap, Button Socket Cap or Countersunk Socket
Cap (ignored for Rod)
head_type              =
"hex";//[hex,socket,button,countersunk]
//Drive type - Socket, Phillips, Slot (ignored for Hex head type and
Rod)
drive_type              = "socket";//[socket,phillips,slot]
//Distance between flats for the hex head or diameter for socket or
button head (ignored for Rod)
head_diameter    = 12;
//Height of the head (ignored for Rod)
head_height  = 5;
//Diameter of drive type (ignored for Hex head and Rod)
drive_diameter = 5;
//Width of slot aperture for phillips or slot drive types
slot_width     = 1;
//Depth of slot aperture for slot drive type
slot_depth     = 2;
//Surface texture (socket head only)
texture                        = "exclude";//[include,exclude]
//Outer diameter of the thread
thread_outer_diameter          = 8;
//Thread step or Pitch (2mm works well for most applications ref.
ISO262: M3=0.5,M4=0.7,M5=0.8,M6=1,M8=1.25,M10=1.5)
thread_step    = 2;
//Step shape degrees (45 degrees is optimised for most printers ref.
ISO262: 30 degrees)
step_shape_degrees = 45;
//Length of the threaded section
thread_length  = 25;
//Countersink in both ends
countersink  = 2;
//Length of the non-threaded section
non_thread_length = 0;
//Diameter for the non-threaded section (-1: Same as inner diameter of
the thread, 0: Same as outer diameter of the thread, value: The given
value)
non_thread_diameter = 0;

/* [Nut Options] */

//Type: Normal or WingNut
nut_type                     = "normal";//[normal,wingnut]
//Distance between flats for the hex nut
nut_diameter    = 12;
//Height of the nut
nut_height       = 6;
//Outer diameter of the bolt thread to match (usually set about 1mm
larger than bolt diameter to allow easy fit - adjust to personal
preferences)
nut_thread_outer_diameter    = 9;
//Thread step or Pitch (2mm works well for most applications ref.
ISO262: M3=0.5,M4=0.7,M5=0.8,M6=1,M8=1.25,M10=1.5)
nut_thread_step    = 2;
//Step shape degrees (45 degrees is optimised for most printers ref.
ISO262: 30 degrees)
nut_step_shape_degrees = 45;
//Wing radius ratio.  The proportional radius of the wing on the wing
nut compared to the nut height value (default = 1)
wing_ratio                      = 1;
wing_radius=wing_ratio * nut_height;

/* [Washer Options] */

//Inner Diameter (suggest making diameter slightly larger than bolt
diameter)
inner_diameter = 8;
//Outer Diameter
outer_diameter = 14;
//Thickness
thickness     = 2;

/* [Extended Options] */

//Number of facets for hex head type or nut. Default is 6 for standard
hex head and nut
facets                          = 6;
//Number of facets for hole in socket head. Default is 6 for standard
hex socket
socket_facets                  = 6;
//Depth of hole in socket head. Default is 3.5
socket_depth                    = 3.5;
//Resolution (lower values for higher resolution, but may slow
rendering)
resolution    = 0.5;
nut_resolution    = resolution;

//Hex Bolt
if (type=="bolt" && head_type=="hex")
{

hex_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,head_height,non_thread_length,non_thread_diameter);
}

//Rod
if (type=="rod")
{

hex_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,0,non_thread_length,non_thread_diameter);
}

//Hex Nut (normally slightly larger outer diameter to fit on bolt
correctly)
if (type=="nut" && nut_type=="normal")
{

hex_nut(nut_diameter,nut_height,nut_thread_step,nut_step_shape_degrees,nut_thread_outer_diameter,nut_resolution);
}

//Wing Nut variation of hex nut. Cylinders added to each side of nut for
easy turning - ideal for quick release applications
if (type=="nut" && nut_type=="wingnut")
{

rotate([0,0,30])hex_nut(nut_diameter,nut_height,nut_thread_step,nut_step_shape_degrees,nut_thread_outer_diameter,nut_resolution);
//nut

translate([(nut_diameter/2)+wing_radius-1,1.5,wing_radius/2+1])rotate([90,0,0])wing();
//attach wing

mirror(1,0,0)translate([(nut_diameter/2)+wing_radius-1,1.5,wing_radius/2+1])rotate([90,0,0])wing();
//attach wing
}

module wing()
{
difference()
{
cylinder(r=wing_radius,h=3,$fn=64); //cylinder
union()
{

translate([-wing_radius,-wing_radius-1,-0.5])cube([wing_radius2,wing_radius/2,wing_radius2]);
//remove overhang so flush with base of nut

rotate([0,0,90])translate([-wing_radius,wing_radius-1,-0.5])cube([wing_radius2,wing_radius/2,wing_radius2]);
//remove overhangs so flush with side of nut
}
}
}

//Washer
if (type=="washer")
{
difference()
{
cylinder(r=outer_diameter/2,h=thickness,$fn=100);

translate([0,0,-0.1])cylinder(r=inner_diameter/2,h=thickness+0.2,$fn=100);
}
}

//Socket Head Bolt
if (type=="bolt" && head_type!="hex")
{

socket_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,head_height,non_thread_length,non_thread_diameter);
}

module phillips_base()
{

linear_extrude(slot_width)polygon(points=[[0,0],[(drive_diameter-slot_width)/2,9/5*(drive_diameter-slot_width)/2],[(drive_diameter+slot_width)/2,9/5*(drive_diameter-slot_width)/2],[drive_diameter,0]]);

translate([(drive_diameter-slot_width)/2,0,(drive_diameter+slot_width)/2])rotate([0,90,0])linear_extrude(slot_width)polygon(points=[[0,0],[(drive_diameter-slot_width)/2,9/5*(drive_diameter-slot_width)/2],[(drive_diameter+slot_width)/2,9/5*(drive_diameter-slot_width)/2],[drive_diameter,0]]);
}

module phillips_fillet()
{
union()
{

translate([-(drive_diameter-slot_width)/2-(slot_width/2),slot_width/2,0])rotate([90,0,0])phillips_base();
translate([0,0,9/5*(drive_diameter-slot_width)/2])union()
{
inner_curve();
rotate([0,0,90])inner_curve();
rotate([0,0,180])inner_curve();
rotate([0,0,270])inner_curve();
}
}
}

module inner_curve()
{

translate([slot_width/2,-slot_width/2,0])rotate([0,90,0])linear_fillet(9/5*(drive_diameter-slot_width)/2,drive_diameter/10);
}

//basic 2d profile used for fillet shape
module profile(radius)
{
difference()
{
square(radius);
circle(r=radius);
}
}

//linear fillet for use along straight edges
module linear_fillet(length,profile_radius)
{

translate([0,-profile_radius,profile_radius])rotate([0,90,0])linear_extrude(height=length,convexity=10)profile(profile_radius);
}

module phillips_drive()
{
intersection()
{
phillips_fillet();

cylinder(9/5*(drive_diameter-slot_width)/2,drive_diameter/2+(slot_width/2),slot_width/2);
}
}

module socket_screw(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd)
{
ntr=od/2-(st/2)*cos(lf0)/sin(lf0);
$fn=60;

difference()
{
		union()
		{
    		if (head_type=="socket")
			{
				socket_head(hg,df);
			}
		
    		if (head_type=="button")
			{
				button_head(hg,df);				
			}

    		if (head_type=="countersunk")
			{
				countersunk_head(hg,df);				
			}

    		translate([0,0,hg])
    		if ( ntl == 0 )
    		{
      		cylinder(h=0.01, r=ntr, center=true);
    		}
    		else
    		{
        		if ( ntd == -1 )
        		{
            		cylinder(h=ntl+0.01, r=ntr,

$fn=floor(odPI/rs), center=false);
}
else if ( ntd == 0 )
{
union()
{
cylinder(h=ntl-st/2,r=od/2,
$fn=floor(od
PI/rs), center=false);
translate([0,0,ntl-st/2])
cylinder(h=st/2,
r1=od/2, r2=ntr,
$fn=floor(odPI/rs), center=false);
}
}
else
{
cylinder(h=ntl, r=ntd/2, $fn=ntd
PI/rs,
center=false);
}
}
translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs);
}
//create opening for specific drive type
if (drive_type=="socket")
{
cylinder(r=drive_diameter/2,h=socket_depth,$fn=socket_facets); //socket

#translate([0,0,socket_depth])cylinder(r1=drive_diameter/2,r2=0,h=drive_diameter/3,$fn=socket_facets);
//socket tapers at base to allow printing without bridging and improve
socket grip
}
else
{
if (drive_type=="phillips")
{
translate([0,0,-0.001])phillips_drive();
}
else //slot
{

translate([-(drive_diameter)/2,slot_width/2,-0.001])rotate([90,0,0])cube([drive_diameter,slot_depth,slot_width]);
}
}
}
}

module socket_head(hg,df)
{
texture_points=2PI(head_diameter/2);
texture_offset=head_diameter/18;
texture_radius=head_diameter/24;

rd0=df/2/sin(60);
x0=0;	x1=df/2;	x2=x1+hg/2;
y0=0;	y1=hg/2;	y2=hg;

intersection()
{
   	cylinder(h=hg, r=rd0, $fn=60, center=false);
	rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
	polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
}

if (texture=="include") //add texture to socket head. Adjust

texture density and size using texture variables above
{
for (i= [1:texture_points])
{
translate([cos(360/texture_pointsi)(head_diameter/2+texture_offset),
sin(360/texture_pointsi)(head_diameter/2+texture_offset), 1 ])

rotate([0,0,360/texture_pointsi])cylinder(r=texture_radius,h=head_height0.6,$fn=3);
}
}

}

module button_head(hg,df)
{
rd0=df/2/sin(60);
x0=0; x1=df/2; x2=x1+hg/2;
y0=0; y1=hg/2; y2=hg;

intersection()
{
   	cylinder(h=hg, r1=drive_diameter/2 + 1, r2=rd0, $fn=60,

center=false);
rotate_extrude(convexity=10, $fn=6round(dfPI/6/0.5))
polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
}
}

module countersunk_head(hg,df)
{
rd0=df/2/sin(60);
x0=0; x1=df/2; x2=x1+hg/2;
y0=0; y1=hg/2; y2=hg;

intersection()
{
   cylinder(h=hg, r1=rd0, r2=thread_outer_diameter/2-0.5, $fn=60,

center=false);

	rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
	polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
}

}

/* Library included below to allow customizer functionality
*

  • polyScrewThread_r1.scad    by aubenc @ Thingiverse
  • Modified by mike_mattala @ Thingiverse 1/1/2017 to remove deprecated
    assign
  • This script contains the library modules that can be used to generate
  • threaded rods, screws and nuts.
  • http://www.thingiverse.com/thing:8796
  • CC Public Domain
    */

module screw_thread(od,st,lf0,lt,rs,cs)
{
or=od/2;
ir=or-st/2cos(lf0)/sin(lf0);
pf=2
PI*or;
sn=floor(pf/rs);
lfxy=360/sn;
ttn=round(lt/st+1);
zt=st/sn;

intersection()
{
    if (cs >= -1)
    {
       thread_shape(cs,lt,or,ir,sn,st);
    }

    full_thread(ttn,st,sn,zt,lfxy,or,ir);
}

}

module hex_nut(df,hg,sth,clf,cod,crs)
{

difference()
{
    hex_head(hg,df);

    hex_countersink_ends(sth/2,cod,clf,crs,hg);

    screw_thread(cod,sth,clf,hg,crs,-2);
}

}

module hex_screw(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd)
{
ntr=od/2-(st/2)*cos(lf0)/sin(lf0);

union()
{
    hex_head(hg,df);

    translate([0,0,hg])
    if ( ntl == 0 )
    {
        cylinder(h=0.01, r=ntr, center=true);
    }
    else
    {
        if ( ntd == -1 )
        {
            cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs),

center=false);
}
else if ( ntd == 0 )
{
union()
{
cylinder(h=ntl-st/2,
r=od/2, $fn=floor(od*PI/rs), center=false);

                translate([0,0,ntl-st/2])
                cylinder(h=st/2,
                         r1=od/2, r2=ntr, 
                         $fn=floor(od*PI/rs), center=false);
            }
        }
        else
        {
            cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false);
        }
    }

    translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs);
}

}

module hex_screw_0(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd)
{
ntr=od/2-(st/2)*cos(lf0)/sin(lf0);

union()
{
    hex_head_0(hg,df);

    translate([0,0,hg])
    if ( ntl == 0 )
    {
        cylinder(h=0.01, r=ntr, center=true);
    }
    else
    {
        if ( ntd == -1 )
        {
            cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs),

center=false);
}
else if ( ntd == 0 )
{
union()
{
cylinder(h=ntl-st/2,
r=od/2, $fn=floor(od*PI/rs), center=false);

                translate([0,0,ntl-st/2])
                cylinder(h=st/2,
                         r1=od/2, r2=ntr, 
                         $fn=floor(od*PI/rs), center=false);
            }
        }
        else
        {
            cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false);
        }
    }

    translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs);
}

}

module thread_shape(cs,lt,or,ir,sn,st)
{
if ( cs == 0 )
{
cylinder(h=lt, r=or, $fn=sn, center=false);
}
else
{
union()
{
translate([0,0,st/2])
cylinder(h=lt-st+0.005, r=or, $fn=sn, center=false);

        if ( cs == -1 || cs == 2 )
        {
            cylinder(h=st/2, r1=ir, r2=or, $fn=sn, center=false);
        }
        else
        {
            cylinder(h=st/2, r=or, $fn=sn, center=false);
        }

        translate([0,0,lt-st/2])
        if ( cs == 1 || cs == 2 )
        {
              cylinder(h=st/2, r1=or, r2=ir, $fn=sn, center=false);
        }
        else
        {
            cylinder(h=st/2, r=or, $fn=sn, center=false);
        }
    }
}

}

module full_thread(ttn,st,sn,zt,lfxy,or,ir)
{
if(ir >= 0.2)
{
for(i=[0:ttn-1])
{
for(j=[0:sn-1])
{
pt = [[0,0,ist-st],
[ir
cos(jlfxy),    irsin(jlfxy),    ist+jzt-st
],
[ir
cos((j+1)lfxy), irsin((j+1)lfxy),
i
st+(j+1)zt-st  ],
[0,0,i
st],
[orcos(jlfxy),    orsin(jlfxy),    ist+jzt-st/2
],
[orcos((j+1)lfxy), orsin((j+1)lfxy),
i
st+(j+1)zt-st/2 ],
[ir
cos(j
lfxy),    irsin(jlfxy),    ist+jzt ],
[ir*cos((j+1)lfxy), irsin((j+1)lfxy), ist+(j+1)zt
],
[0,0,i
st+st]];

        polyhedron(points=pt,faces=[[1,0,3],[1,3,6],[6,3,8],[1,6,4],

//changed triangles to faces (to be deprecated)
[0,1,2],[1,4,2],[2,4,5],[5,4,6],[5,6,7],[7,6,8],
[7,8,3],[0,2,3],[3,2,7],[7,2,5] ]);
}
}
}
else
{
echo("Step Degrees too agresive, the thread will not be made!!");
echo("Try to increase de value for the degrees and/or...");
echo(" decrease the pitch value and/or...");
echo(" increase the outer diameter value.");
}
}

module hex_head(hg,df)
{
rd0=df/2/sin(60);
x0=0; x1=df/2; x2=x1+hg/2;
y0=0; y1=hg/2; y2=hg;

intersection()
{
   cylinder(h=hg, r=rd0, $fn=facets, center=false);

	rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
	polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
}

}

module hex_head_0(hg,df)
{
cylinder(h=hg, r=df/2/sin(60), $fn=6, center=false);
}

module hex_countersink_ends(chg,cod,clf,crs,hg)
{
translate([0,0,-0.1])
cylinder(h=chg+0.01,
r1=cod/2,
r2=cod/2-(chg+0.1)cos(clf)/sin(clf),
$fn=floor(cod
PI/crs), center=false);

translate([0,0,hg-chg+0.1])
cylinder(h=chg+0.01, 
         r1=cod/2-(chg+0.1)*cos(clf)/sin(clf),
         r2=cod/2, 
         $fn=floor(cod*PI/crs), center=false);

}

It's a very long time since I used OpenSCAD and my printer, so 'rusty' would be a gross understatement ;-) But to finish my current (hobby electronics) project I need a nut to fit a '10 mm' pot. Embedded images made my earlier post attempt too large so have used links instead. https://www.dropbox.com/s/84qorbyh9ueskzf/Dimensions.jpg?raw=1 I have a dozen or so pots, probably none under 40 years old, which are without their nuts. I tried the hundred or so of my 'spare' nuts in vain https://www.dropbox.com/s/eutnqjdw869s955/PotNutFails.jpg?raw=1 Strangely, the only thing that worked was this enormous nut, 6.45 mm thick, with only 3 threads in that length. (That's approx,as I'm unclear about the start and end points for measuring pitch.) And obviously far too bulky to use. https://www.dropbox.com/s/gw2hfkp1pp2bizd/LargeNut.jpg?raw=1 I could order an appropriate pot with accompanying nut, but I hate to waste stuff. Once I have a nut for today's job I'll make a bunch of them. I downloaded Nut_job.scad from this promising page: https://www.thingiverse.com/thing:193647/files And then tentatively customised it to get the code below, which I'll paste in full at the end. https://www.dropbox.com/s/8i4hwzc689rjgfm/NutJob-1.jpg?raw=1 But before I re-learn the little OpenSCAD I once knew, dust off my Ender 3 V2 etc, could I please get advice on the appropriateness or otherwise of that code. Or even a 'starter example' based on one of the libraries, such as NopHead's NopSCADlib or BOSL2. In a nutshell (sorry), I'm frankly looking for a quick practical solution, postponing study until later. The code: /* 'Nut Job' nut, bolt, washer and threaded rod factory by Mike Thompson 1/12/2013, Thingiverse: mike_linus * * Licensing: This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Australia License. * Further information is available here - http://creativecommons.org/licenses/by-nc-sa/3.0/au/deed.en_GB * * v2 8/12/2013 - added socket head types * v3 2/11/2014 - adjusted wing nut algorithm for better behaviour with unusual nut sizes and added ISO262 metric references * v4 31/12/2014 - added optional texture to socket heads, added ability to change the number of facets for a hex head * and adjusted wingnut base level on certain nut sizes * v5 11/1/2015 - added phillips and slot drive types and improved texture handling * v6 21/2/2015 - added wing ratio to wingnuts * v7 6/3/2016 - added extended options to control number of facets on nuts, square sockets (or any number of facets) and socket depth control * v8 1/1/2017 - modified library code to remove dependence on deprecated 'assign' statement * * This script generates nuts, bolts, washers and threaded rod using the library * script: polyScrewThead.scad (modified/updated version polyScrewThread_r1.scad) * http://www.thingiverse.com/thing:8796, CC Public Domain * * Defaults are for a 8mm diameter bolts, rod, matching nuts and wing nuts that work well together * without cleanup or modification. Some default parameters such as the nut outer diameter are deliberately * altered to produce a snug fit that can still be hand tightened. This may need to be altered * depending on individual printer variances, slicing tools, filament etc. Suggest printing a matching * bolt and nut and adjusting as necessary. Note: slow print speeds, low temperatures and solid * fill are recommended for best results. */ /* [Component Type] */ type = "bolt";//[nut,bolt,rod,washer] /* [Bolt and Rod Options] */ //Head type - Hex, Socket Cap, Button Socket Cap or Countersunk Socket Cap (ignored for Rod) head_type = "hex";//[hex,socket,button,countersunk] //Drive type - Socket, Phillips, Slot (ignored for Hex head type and Rod) drive_type = "socket";//[socket,phillips,slot] //Distance between flats for the hex head or diameter for socket or button head (ignored for Rod) head_diameter = 12; //Height of the head (ignored for Rod) head_height = 5; //Diameter of drive type (ignored for Hex head and Rod) drive_diameter = 5; //Width of slot aperture for phillips or slot drive types slot_width = 1; //Depth of slot aperture for slot drive type slot_depth = 2; //Surface texture (socket head only) texture = "exclude";//[include,exclude] //Outer diameter of the thread thread_outer_diameter = 8; //Thread step or Pitch (2mm works well for most applications ref. ISO262: M3=0.5,M4=0.7,M5=0.8,M6=1,M8=1.25,M10=1.5) thread_step = 2; //Step shape degrees (45 degrees is optimised for most printers ref. ISO262: 30 degrees) step_shape_degrees = 45; //Length of the threaded section thread_length = 25; //Countersink in both ends countersink = 2; //Length of the non-threaded section non_thread_length = 0; //Diameter for the non-threaded section (-1: Same as inner diameter of the thread, 0: Same as outer diameter of the thread, value: The given value) non_thread_diameter = 0; /* [Nut Options] */ //Type: Normal or WingNut nut_type = "normal";//[normal,wingnut] //Distance between flats for the hex nut nut_diameter = 12; //Height of the nut nut_height = 6; //Outer diameter of the bolt thread to match (usually set about 1mm larger than bolt diameter to allow easy fit - adjust to personal preferences) nut_thread_outer_diameter = 9; //Thread step or Pitch (2mm works well for most applications ref. ISO262: M3=0.5,M4=0.7,M5=0.8,M6=1,M8=1.25,M10=1.5) nut_thread_step = 2; //Step shape degrees (45 degrees is optimised for most printers ref. ISO262: 30 degrees) nut_step_shape_degrees = 45; //Wing radius ratio. The proportional radius of the wing on the wing nut compared to the nut height value (default = 1) wing_ratio = 1; wing_radius=wing_ratio * nut_height; /* [Washer Options] */ //Inner Diameter (suggest making diameter slightly larger than bolt diameter) inner_diameter = 8; //Outer Diameter outer_diameter = 14; //Thickness thickness = 2; /* [Extended Options] */ //Number of facets for hex head type or nut. Default is 6 for standard hex head and nut facets = 6; //Number of facets for hole in socket head. Default is 6 for standard hex socket socket_facets = 6; //Depth of hole in socket head. Default is 3.5 socket_depth = 3.5; //Resolution (lower values for higher resolution, but may slow rendering) resolution = 0.5; nut_resolution = resolution; //Hex Bolt if (type=="bolt" && head_type=="hex") { hex_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,head_height,non_thread_length,non_thread_diameter); } //Rod if (type=="rod") { hex_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,0,non_thread_length,non_thread_diameter); } //Hex Nut (normally slightly larger outer diameter to fit on bolt correctly) if (type=="nut" && nut_type=="normal") { hex_nut(nut_diameter,nut_height,nut_thread_step,nut_step_shape_degrees,nut_thread_outer_diameter,nut_resolution); } //Wing Nut variation of hex nut. Cylinders added to each side of nut for easy turning - ideal for quick release applications if (type=="nut" && nut_type=="wingnut") { rotate([0,0,30])hex_nut(nut_diameter,nut_height,nut_thread_step,nut_step_shape_degrees,nut_thread_outer_diameter,nut_resolution); //nut translate([(nut_diameter/2)+wing_radius-1,1.5,wing_radius/2+1])rotate([90,0,0])wing(); //attach wing mirror(1,0,0)translate([(nut_diameter/2)+wing_radius-1,1.5,wing_radius/2+1])rotate([90,0,0])wing(); //attach wing } module wing() { difference() { cylinder(r=wing_radius,h=3,$fn=64); //cylinder union() { translate([-wing_radius,-wing_radius-1,-0.5])cube([wing_radius*2,wing_radius/2,wing_radius*2]); //remove overhang so flush with base of nut rotate([0,0,90])translate([-wing_radius,wing_radius-1,-0.5])cube([wing_radius*2,wing_radius/2,wing_radius*2]); //remove overhangs so flush with side of nut } } } //Washer if (type=="washer") { difference() { cylinder(r=outer_diameter/2,h=thickness,$fn=100); translate([0,0,-0.1])cylinder(r=inner_diameter/2,h=thickness+0.2,$fn=100); } } //Socket Head Bolt if (type=="bolt" && head_type!="hex") { socket_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,head_height,non_thread_length,non_thread_diameter); } module phillips_base() { linear_extrude(slot_width)polygon(points=[[0,0],[(drive_diameter-slot_width)/2,9/5*(drive_diameter-slot_width)/2],[(drive_diameter+slot_width)/2,9/5*(drive_diameter-slot_width)/2],[drive_diameter,0]]); translate([(drive_diameter-slot_width)/2,0,(drive_diameter+slot_width)/2])rotate([0,90,0])linear_extrude(slot_width)polygon(points=[[0,0],[(drive_diameter-slot_width)/2,9/5*(drive_diameter-slot_width)/2],[(drive_diameter+slot_width)/2,9/5*(drive_diameter-slot_width)/2],[drive_diameter,0]]); } module phillips_fillet() { union() { translate([-(drive_diameter-slot_width)/2-(slot_width/2),slot_width/2,0])rotate([90,0,0])phillips_base(); translate([0,0,9/5*(drive_diameter-slot_width)/2])union() { inner_curve(); rotate([0,0,90])inner_curve(); rotate([0,0,180])inner_curve(); rotate([0,0,270])inner_curve(); } } } module inner_curve() { translate([slot_width/2,-slot_width/2,0])rotate([0,90,0])linear_fillet(9/5*(drive_diameter-slot_width)/2,drive_diameter/10); } //basic 2d profile used for fillet shape module profile(radius) { difference() { square(radius); circle(r=radius); } } //linear fillet for use along straight edges module linear_fillet(length,profile_radius) { translate([0,-profile_radius,profile_radius])rotate([0,90,0])linear_extrude(height=length,convexity=10)profile(profile_radius); } module phillips_drive() { intersection() { phillips_fillet(); cylinder(9/5*(drive_diameter-slot_width)/2,drive_diameter/2+(slot_width/2),slot_width/2); } } module socket_screw(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd) { ntr=od/2-(st/2)*cos(lf0)/sin(lf0); $fn=60; difference() { union() { if (head_type=="socket") { socket_head(hg,df); } if (head_type=="button") { button_head(hg,df); } if (head_type=="countersunk") { countersunk_head(hg,df); } translate([0,0,hg]) if ( ntl == 0 ) { cylinder(h=0.01, r=ntr, center=true); } else { if ( ntd == -1 ) { cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs), center=false); } else if ( ntd == 0 ) { union() { cylinder(h=ntl-st/2,r=od/2, $fn=floor(od*PI/rs), center=false); translate([0,0,ntl-st/2]) cylinder(h=st/2, r1=od/2, r2=ntr, $fn=floor(od*PI/rs), center=false); } } else { cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false); } } translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs); } //create opening for specific drive type if (drive_type=="socket") { cylinder(r=drive_diameter/2,h=socket_depth,$fn=socket_facets); //socket #translate([0,0,socket_depth])cylinder(r1=drive_diameter/2,r2=0,h=drive_diameter/3,$fn=socket_facets); //socket tapers at base to allow printing without bridging and improve socket grip } else { if (drive_type=="phillips") { translate([0,0,-0.001])phillips_drive(); } else //slot { translate([-(drive_diameter)/2,slot_width/2,-0.001])rotate([90,0,0])cube([drive_diameter,slot_depth,slot_width]); } } } } module socket_head(hg,df) { texture_points=2*PI*(head_diameter/2); texture_offset=head_diameter/18; texture_radius=head_diameter/24; rd0=df/2/sin(60); x0=0; x1=df/2; x2=x1+hg/2; y0=0; y1=hg/2; y2=hg; intersection() { cylinder(h=hg, r=rd0, $fn=60, center=false); rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5)) polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]); } if (texture=="include") //add texture to socket head. Adjust texture density and size using texture variables above { for (i= [1:texture_points]) { translate([cos(360/texture_points*i)*(head_diameter/2+texture_offset), sin(360/texture_points*i)*(head_diameter/2+texture_offset), 1 ]) rotate([0,0,360/texture_points*i])cylinder(r=texture_radius,h=head_height*0.6,$fn=3); } } } module button_head(hg,df) { rd0=df/2/sin(60); x0=0; x1=df/2; x2=x1+hg/2; y0=0; y1=hg/2; y2=hg; intersection() { cylinder(h=hg, r1=drive_diameter/2 + 1, r2=rd0, $fn=60, center=false); rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5)) polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]); } } module countersunk_head(hg,df) { rd0=df/2/sin(60); x0=0; x1=df/2; x2=x1+hg/2; y0=0; y1=hg/2; y2=hg; intersection() { cylinder(h=hg, r1=rd0, r2=thread_outer_diameter/2-0.5, $fn=60, center=false); rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5)) polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]); } } /* Library included below to allow customizer functionality * * polyScrewThread_r1.scad by aubenc @ Thingiverse * * Modified by mike_mattala @ Thingiverse 1/1/2017 to remove deprecated assign * * This script contains the library modules that can be used to generate * threaded rods, screws and nuts. * * http://www.thingiverse.com/thing:8796 * * CC Public Domain */ module screw_thread(od,st,lf0,lt,rs,cs) { or=od/2; ir=or-st/2*cos(lf0)/sin(lf0); pf=2*PI*or; sn=floor(pf/rs); lfxy=360/sn; ttn=round(lt/st+1); zt=st/sn; intersection() { if (cs >= -1) { thread_shape(cs,lt,or,ir,sn,st); } full_thread(ttn,st,sn,zt,lfxy,or,ir); } } module hex_nut(df,hg,sth,clf,cod,crs) { difference() { hex_head(hg,df); hex_countersink_ends(sth/2,cod,clf,crs,hg); screw_thread(cod,sth,clf,hg,crs,-2); } } module hex_screw(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd) { ntr=od/2-(st/2)*cos(lf0)/sin(lf0); union() { hex_head(hg,df); translate([0,0,hg]) if ( ntl == 0 ) { cylinder(h=0.01, r=ntr, center=true); } else { if ( ntd == -1 ) { cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs), center=false); } else if ( ntd == 0 ) { union() { cylinder(h=ntl-st/2, r=od/2, $fn=floor(od*PI/rs), center=false); translate([0,0,ntl-st/2]) cylinder(h=st/2, r1=od/2, r2=ntr, $fn=floor(od*PI/rs), center=false); } } else { cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false); } } translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs); } } module hex_screw_0(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd) { ntr=od/2-(st/2)*cos(lf0)/sin(lf0); union() { hex_head_0(hg,df); translate([0,0,hg]) if ( ntl == 0 ) { cylinder(h=0.01, r=ntr, center=true); } else { if ( ntd == -1 ) { cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs), center=false); } else if ( ntd == 0 ) { union() { cylinder(h=ntl-st/2, r=od/2, $fn=floor(od*PI/rs), center=false); translate([0,0,ntl-st/2]) cylinder(h=st/2, r1=od/2, r2=ntr, $fn=floor(od*PI/rs), center=false); } } else { cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false); } } translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs); } } module thread_shape(cs,lt,or,ir,sn,st) { if ( cs == 0 ) { cylinder(h=lt, r=or, $fn=sn, center=false); } else { union() { translate([0,0,st/2]) cylinder(h=lt-st+0.005, r=or, $fn=sn, center=false); if ( cs == -1 || cs == 2 ) { cylinder(h=st/2, r1=ir, r2=or, $fn=sn, center=false); } else { cylinder(h=st/2, r=or, $fn=sn, center=false); } translate([0,0,lt-st/2]) if ( cs == 1 || cs == 2 ) { cylinder(h=st/2, r1=or, r2=ir, $fn=sn, center=false); } else { cylinder(h=st/2, r=or, $fn=sn, center=false); } } } } module full_thread(ttn,st,sn,zt,lfxy,or,ir) { if(ir >= 0.2) { for(i=[0:ttn-1]) { for(j=[0:sn-1]) { pt = [[0,0,i*st-st], [ir*cos(j*lfxy), ir*sin(j*lfxy), i*st+j*zt-st ], [ir*cos((j+1)*lfxy), ir*sin((j+1)*lfxy), i*st+(j+1)*zt-st ], [0,0,i*st], [or*cos(j*lfxy), or*sin(j*lfxy), i*st+j*zt-st/2 ], [or*cos((j+1)*lfxy), or*sin((j+1)*lfxy), i*st+(j+1)*zt-st/2 ], [ir*cos(j*lfxy), ir*sin(j*lfxy), i*st+j*zt ], [ir*cos((j+1)*lfxy), ir*sin((j+1)*lfxy), i*st+(j+1)*zt ], [0,0,i*st+st]]; polyhedron(points=pt,faces=[[1,0,3],[1,3,6],[6,3,8],[1,6,4], //changed triangles to faces (to be deprecated) [0,1,2],[1,4,2],[2,4,5],[5,4,6],[5,6,7],[7,6,8], [7,8,3],[0,2,3],[3,2,7],[7,2,5] ]); } } } else { echo("Step Degrees too agresive, the thread will not be made!!"); echo("Try to increase de value for the degrees and/or..."); echo(" decrease the pitch value and/or..."); echo(" increase the outer diameter value."); } } module hex_head(hg,df) { rd0=df/2/sin(60); x0=0; x1=df/2; x2=x1+hg/2; y0=0; y1=hg/2; y2=hg; intersection() { cylinder(h=hg, r=rd0, $fn=facets, center=false); rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5)) polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]); } } module hex_head_0(hg,df) { cylinder(h=hg, r=df/2/sin(60), $fn=6, center=false); } module hex_countersink_ends(chg,cod,clf,crs,hg) { translate([0,0,-0.1]) cylinder(h=chg+0.01, r1=cod/2, r2=cod/2-(chg+0.1)*cos(clf)/sin(clf), $fn=floor(cod*PI/crs), center=false); translate([0,0,hg-chg+0.1]) cylinder(h=chg+0.01, r1=cod/2-(chg+0.1)*cos(clf)/sin(clf), r2=cod/2, $fn=floor(cod*PI/crs), center=false); }
NH
nop head
Wed, Jun 14, 2023 2:32 PM

I think imperial pots have 3/8" 32 tpi threads. The picture looks like a
metric pot and they have M10 nuts with 0.75mm pitch, which is much finer
than a normal M10 fine thread.

There is a potentiometer model in NopSCADlib and there is even a pot_nut()
module to draw the nuts for them with the correct thread but I have never
tried printing one.

On Wed, 14 Jun 2023 at 15:11, Terry terrypingm@gmail.com wrote:

It's a very long time since I used OpenSCAD and my printer, so 'rusty'
would be a gross understatement ;-) But to finish my current (hobby
electronics) project I need a nut to fit a '10 mm' pot.

Embedded images made my earlier post attempt too large so have used
links instead.

https://www.dropbox.com/s/84qorbyh9ueskzf/Dimensions.jpg?raw=1

I have a dozen or so pots, probably none under 40 years old, which are
without their nuts. I tried the hundred or so of my 'spare' nuts in vain

https://www.dropbox.com/s/eutnqjdw869s955/PotNutFails.jpg?raw=1

Strangely, the only thing that worked was this enormous nut, 6.45 mm
thick, with only 3 threads in that length. (That's approx,as I'm unclear
about the start and end points for measuring pitch.) And obviously far
too bulky to use.

https://www.dropbox.com/s/gw2hfkp1pp2bizd/LargeNut.jpg?raw=1

I could order an appropriate pot with accompanying nut, but I hate to
waste stuff. Once I have a nut for today's job I'll make a bunch of
them.

I downloaded Nut_job.scad from this promising page:
https://www.thingiverse.com/thing:193647/files

And then tentatively customised it to get the code below, which I'll
paste in full at the end.

https://www.dropbox.com/s/8i4hwzc689rjgfm/NutJob-1.jpg?raw=1

But before I re-learn the little OpenSCAD I once knew, dust off my Ender
3 V2 etc, could I please get advice on the appropriateness or otherwise
of that code. Or even a 'starter example' based on one of the libraries,
such as NopHead's NopSCADlib or BOSL2.

In a nutshell (sorry), I'm frankly looking for a quick practical
solution, postponing study until later.

The code:

/* 'Nut Job' nut, bolt, washer and threaded rod factory by Mike Thompson
1/12/2013, Thingiverse: mike_linus
*

  • Licensing: This work is licensed under a Creative Commons
    Attribution-NonCommercial-ShareAlike 3.0 Australia License.
  • Further information is available here -
    http://creativecommons.org/licenses/by-nc-sa/3.0/au/deed.en_GB
  • v2 8/12/2013 - added socket head types
  • v3 2/11/2014 - adjusted wing nut algorithm for better behaviour with
    unusual nut sizes and added ISO262 metric references
  • v4 31/12/2014 - added optional texture to socket heads, added ability
    to change the number of facets for a hex head
  • and adjusted wingnut base level on certain nut sizes
  • v5 11/1/2015 - added phillips and slot drive types and improved
    texture handling
  • v6 21/2/2015 - added wing ratio to wingnuts
  • v7 6/3/2016 - added extended options to control number of facets on
    nuts, square sockets (or any number of facets) and socket depth control
  • v8 1/1/2017 - modified library code to remove dependence on
    deprecated 'assign' statement
  • This script generates nuts, bolts, washers and threaded rod using the
    library
  • script: polyScrewThead.scad (modified/updated version
    polyScrewThread_r1.scad)
  • http://www.thingiverse.com/thing:8796, CC Public Domain
  • Defaults are for a 8mm diameter bolts, rod, matching nuts and wing
    nuts that work well together
  • without cleanup or modification. Some default parameters such as the
    nut outer diameter are deliberately
  • altered to produce a snug fit that can still be hand tightened. This
    may need to be altered
  • depending on individual printer variances, slicing tools, filament
    etc. Suggest printing a matching
  • bolt and nut and adjusting as necessary.  Note: slow print speeds,
    low temperatures and solid
  • fill are recommended for best results.
    */

/* [Component Type] */

type                                                =
"bolt";//[nut,bolt,rod,washer]

/* [Bolt and Rod Options] */

//Head type - Hex, Socket Cap, Button Socket Cap or Countersunk Socket
Cap (ignored for Rod)
head_type                              =
"hex";//[hex,socket,button,countersunk]
//Drive type - Socket, Phillips, Slot (ignored for Hex head type and
Rod)
drive_type                              = "socket";//[socket,phillips,slot]
//Distance between flats for the hex head or diameter for socket or
button head (ignored for Rod)
head_diameter                                  = 12;
//Height of the head (ignored for Rod)
head_height                                    = 5;
//Diameter of drive type (ignored for Hex head and Rod)
drive_diameter                                  = 5;
//Width of slot aperture for phillips or slot drive types
slot_width                                          = 1;
//Depth of slot aperture for slot drive type
slot_depth                                          = 2;
//Surface texture (socket head only)
texture                        = "exclude";//[include,exclude]
//Outer diameter of the thread
thread_outer_diameter          = 8;
//Thread step or Pitch (2mm works well for most applications ref.
ISO262: M3=0.5,M4=0.7,M5=0.8,M6=1,M8=1.25,M10=1.5)
thread_step                                    = 2;
//Step shape degrees (45 degrees is optimised for most printers ref.
ISO262: 30 degrees)
step_shape_degrees                              = 45;
//Length of the threaded section
thread_length                                  = 25;
//Countersink in both ends
countersink                                    = 2;
//Length of the non-threaded section
non_thread_length                              = 0;
//Diameter for the non-threaded section (-1: Same as inner diameter of
the thread, 0: Same as outer diameter of the thread, value: The given
value)
non_thread_diameter                            = 0;

/* [Nut Options] */

//Type: Normal or WingNut
nut_type                            = "normal";//[normal,wingnut]
//Distance between flats for the hex nut
nut_diameter                                    = 12;
//Height of the nut
nut_height                                          = 6;
//Outer diameter of the bolt thread to match (usually set about 1mm
larger than bolt diameter to allow easy fit - adjust to personal
preferences)
nut_thread_outer_diameter      = 9;
//Thread step or Pitch (2mm works well for most applications ref.
ISO262: M3=0.5,M4=0.7,M5=0.8,M6=1,M8=1.25,M10=1.5)
nut_thread_step                                = 2;
//Step shape degrees (45 degrees is optimised for most printers ref.
ISO262: 30 degrees)
nut_step_shape_degrees                  = 45;
//Wing radius ratio.  The proportional radius of the wing on the wing
nut compared to the nut height value (default = 1)
wing_ratio                      = 1;
wing_radius=wing_ratio * nut_height;

/* [Washer Options] */

//Inner Diameter (suggest making diameter slightly larger than bolt
diameter)
inner_diameter                                  = 8;
//Outer Diameter
outer_diameter                                  = 14;
//Thickness
thickness                                          = 2;

/* [Extended Options] */

//Number of facets for hex head type or nut. Default is 6 for standard
hex head and nut
facets                          = 6;
//Number of facets for hole in socket head. Default is 6 for standard
hex socket
socket_facets                  = 6;
//Depth of hole in socket head. Default is 3.5
socket_depth                    = 3.5;
//Resolution (lower values for higher resolution, but may slow
rendering)
resolution                                      = 0.5;
nut_resolution                                  = resolution;

//Hex Bolt
if (type=="bolt" && head_type=="hex")
{

hex_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,head_height,non_thread_length,non_thread_diameter);
}

//Rod
if (type=="rod")
{

hex_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,0,non_thread_length,non_thread_diameter);
}

//Hex Nut (normally slightly larger outer diameter to fit on bolt
correctly)
if (type=="nut" && nut_type=="normal")
{

hex_nut(nut_diameter,nut_height,nut_thread_step,nut_step_shape_degrees,nut_thread_outer_diameter,nut_resolution);
}

//Wing Nut variation of hex nut. Cylinders added to each side of nut for
easy turning - ideal for quick release applications
if (type=="nut" && nut_type=="wingnut")
{

rotate([0,0,30])hex_nut(nut_diameter,nut_height,nut_thread_step,nut_step_shape_degrees,nut_thread_outer_diameter,nut_resolution);
//nut

translate([(nut_diameter/2)+wing_radius-1,1.5,wing_radius/2+1])rotate([90,0,0])wing();
//attach wing

mirror(1,0,0)translate([(nut_diameter/2)+wing_radius-1,1.5,wing_radius/2+1])rotate([90,0,0])wing();
//attach wing
}

module wing()
{
difference()
{
cylinder(r=wing_radius,h=3,$fn=64); //cylinder
union()
{

translate([-wing_radius,-wing_radius-1,-0.5])cube([wing_radius2,wing_radius/2,wing_radius2]);
//remove overhang so flush with base of nut

rotate([0,0,90])translate([-wing_radius,wing_radius-1,-0.5])cube([wing_radius2,wing_radius/2,wing_radius2]);
//remove overhangs so flush with side of nut
}
}
}

//Washer
if (type=="washer")
{
difference()
{
cylinder(r=outer_diameter/2,h=thickness,$fn=100);

translate([0,0,-0.1])cylinder(r=inner_diameter/2,h=thickness+0.2,$fn=100);
}
}

//Socket Head Bolt
if (type=="bolt" && head_type!="hex")
{

socket_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,head_height,non_thread_length,non_thread_diameter);
}

module phillips_base()
{

linear_extrude(slot_width)polygon(points=[[0,0],[(drive_diameter-slot_width)/2,9/5*(drive_diameter-slot_width)/2],[(drive_diameter+slot_width)/2,9/5*(drive_diameter-slot_width)/2],[drive_diameter,0]]);

translate([(drive_diameter-slot_width)/2,0,(drive_diameter+slot_width)/2])rotate([0,90,0])linear_extrude(slot_width)polygon(points=[[0,0],[(drive_diameter-slot_width)/2,9/5*(drive_diameter-slot_width)/2],[(drive_diameter+slot_width)/2,9/5*(drive_diameter-slot_width)/2],[drive_diameter,0]]);
}

module phillips_fillet()
{
union()
{

translate([-(drive_diameter-slot_width)/2-(slot_width/2),slot_width/2,0])rotate([90,0,0])phillips_base();
translate([0,0,9/5*(drive_diameter-slot_width)/2])union()
{
inner_curve();
rotate([0,0,90])inner_curve();
rotate([0,0,180])inner_curve();
rotate([0,0,270])inner_curve();
}
}
}

module inner_curve()
{

translate([slot_width/2,-slot_width/2,0])rotate([0,90,0])linear_fillet(9/5*(drive_diameter-slot_width)/2,drive_diameter/10);
}

//basic 2d profile used for fillet shape
module profile(radius)
{
difference()
{
square(radius);
circle(r=radius);
}
}

//linear fillet for use along straight edges
module linear_fillet(length,profile_radius)
{

translate([0,-profile_radius,profile_radius])rotate([0,90,0])linear_extrude(height=length,convexity=10)profile(profile_radius);
}

module phillips_drive()
{
intersection()
{
phillips_fillet();

cylinder(9/5*(drive_diameter-slot_width)/2,drive_diameter/2+(slot_width/2),slot_width/2);
}
}

module socket_screw(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd)
{
ntr=od/2-(st/2)*cos(lf0)/sin(lf0);
$fn=60;

     difference()
     {
             union()
             {
                     if (head_type=="socket")
                             {
                                     socket_head(hg,df);
                             }

                     if (head_type=="button")
                             {
                                     button_head(hg,df);

                             }

                     if (head_type=="countersunk")
                             {
                                     countersunk_head(hg,df);

                             }

                     translate([0,0,hg])
                     if ( ntl == 0 )
                     {
                     cylinder(h=0.01, r=ntr, center=true);
                     }
                     else
                     {
                     if ( ntd == -1 )
                     {
                             cylinder(h=ntl+0.01, r=ntr,

$fn=floor(odPI/rs), center=false);
}
else if ( ntd == 0 )
{
union()
{
cylinder(h=ntl-st/2,r=od/2,
$fn=floor(od
PI/rs), center=false);
translate([0,0,ntl-st/2])
cylinder(h=st/2,
r1=od/2, r2=ntr,
$fn=floor(odPI/rs), center=false);
}
}
else
{
cylinder(h=ntl, r=ntd/2, $fn=ntd
PI/rs,
center=false);
}
}
translate([0,0,ntl+hg])
screw_thread(od,st,lf0,lt,rs,cs);
}
//create opening for specific drive type
if (drive_type=="socket")
{
cylinder(r=drive_diameter/2,h=socket_depth,$fn=socket_facets); //socket

#translate([0,0,socket_depth])cylinder(r1=drive_diameter/2,r2=0,h=drive_diameter/3,$fn=socket_facets);
//socket tapers at base to allow printing without bridging and improve
socket grip
}
else
{
if (drive_type=="phillips")
{
translate([0,0,-0.001])phillips_drive();
}
else //slot
{

translate([-(drive_diameter)/2,slot_width/2,-0.001])rotate([90,0,0])cube([drive_diameter,slot_depth,slot_width]);
}
}
}
}

module socket_head(hg,df)
{
texture_points=2PI(head_diameter/2);
texture_offset=head_diameter/18;
texture_radius=head_diameter/24;

     rd0=df/2/sin(60);
     x0=0;   x1=df/2;        x2=x1+hg/2;
     y0=0;   y1=hg/2;        y2=hg;

     intersection()
     {
             cylinder(h=hg, r=rd0, $fn=60, center=false);
             rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
             polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
     }

     if (texture=="include") //add texture to socket head. Adjust

texture density and size using texture variables above
{
for (i= [1:texture_points])
{
translate([cos(360/texture_pointsi)(head_diameter/2+texture_offset),
sin(360/texture_pointsi)(head_diameter/2+texture_offset), 1 ])

rotate([0,0,360/texture_pointsi])cylinder(r=texture_radius,h=head_height0.6,$fn=3);
}
}

}

module button_head(hg,df)
{
rd0=df/2/sin(60);
x0=0;  x1=df/2;        x2=x1+hg/2;
y0=0;  y1=hg/2;        y2=hg;

     intersection()
     {
             cylinder(h=hg, r1=drive_diameter/2 + 1, r2=rd0, $fn=60,

center=false);
rotate_extrude(convexity=10, $fn=6round(dfPI/6/0.5))
polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
}
}

module countersunk_head(hg,df)
{
rd0=df/2/sin(60);
x0=0;  x1=df/2;        x2=x1+hg/2;
y0=0;  y1=hg/2;        y2=hg;

     intersection()
     {
        cylinder(h=hg, r1=rd0, r2=thread_outer_diameter/2-0.5, $fn=60,

center=false);

             rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
             polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
     }

}

/* Library included below to allow customizer functionality
*

  • polyScrewThread_r1.scad    by aubenc @ Thingiverse
  • Modified by mike_mattala @ Thingiverse 1/1/2017 to remove deprecated
    assign
  • This script contains the library modules that can be used to generate
  • threaded rods, screws and nuts.
  • http://www.thingiverse.com/thing:8796
  • CC Public Domain
    */

module screw_thread(od,st,lf0,lt,rs,cs)
{
or=od/2;
ir=or-st/2cos(lf0)/sin(lf0);
pf=2
PI*or;
sn=floor(pf/rs);
lfxy=360/sn;
ttn=round(lt/st+1);
zt=st/sn;

 intersection()
 {
     if (cs >= -1)
     {
        thread_shape(cs,lt,or,ir,sn,st);
     }

     full_thread(ttn,st,sn,zt,lfxy,or,ir);
 }

}

module hex_nut(df,hg,sth,clf,cod,crs)
{

 difference()
 {
     hex_head(hg,df);

     hex_countersink_ends(sth/2,cod,clf,crs,hg);

     screw_thread(cod,sth,clf,hg,crs,-2);
 }

}

module hex_screw(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd)
{
ntr=od/2-(st/2)*cos(lf0)/sin(lf0);

 union()
 {
     hex_head(hg,df);

     translate([0,0,hg])
     if ( ntl == 0 )
     {
         cylinder(h=0.01, r=ntr, center=true);
     }
     else
     {
         if ( ntd == -1 )
         {
             cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs),

center=false);
}
else if ( ntd == 0 )
{
union()
{
cylinder(h=ntl-st/2,
r=od/2, $fn=floor(od*PI/rs), center=false);

                 translate([0,0,ntl-st/2])
                 cylinder(h=st/2,
                          r1=od/2, r2=ntr,
                          $fn=floor(od*PI/rs), center=false);
             }
         }
         else
         {
             cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false);
         }
     }

     translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs);
 }

}

module hex_screw_0(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd)
{
ntr=od/2-(st/2)*cos(lf0)/sin(lf0);

 union()
 {
     hex_head_0(hg,df);

     translate([0,0,hg])
     if ( ntl == 0 )
     {
         cylinder(h=0.01, r=ntr, center=true);
     }
     else
     {
         if ( ntd == -1 )
         {
             cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs),

center=false);
}
else if ( ntd == 0 )
{
union()
{
cylinder(h=ntl-st/2,
r=od/2, $fn=floor(od*PI/rs), center=false);

                 translate([0,0,ntl-st/2])
                 cylinder(h=st/2,
                          r1=od/2, r2=ntr,
                          $fn=floor(od*PI/rs), center=false);
             }
         }
         else
         {
             cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false);
         }
     }

     translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs);
 }

}

module thread_shape(cs,lt,or,ir,sn,st)
{
if ( cs == 0 )
{
cylinder(h=lt, r=or, $fn=sn, center=false);
}
else
{
union()
{
translate([0,0,st/2])
cylinder(h=lt-st+0.005, r=or, $fn=sn, center=false);

         if ( cs == -1 || cs == 2 )
         {
             cylinder(h=st/2, r1=ir, r2=or, $fn=sn, center=false);
         }
         else
         {
             cylinder(h=st/2, r=or, $fn=sn, center=false);
         }

         translate([0,0,lt-st/2])
         if ( cs == 1 || cs == 2 )
         {
               cylinder(h=st/2, r1=or, r2=ir, $fn=sn, center=false);
         }
         else
         {
             cylinder(h=st/2, r=or, $fn=sn, center=false);
         }
     }
 }

}

module full_thread(ttn,st,sn,zt,lfxy,or,ir)
{
if(ir >= 0.2)
{
for(i=[0:ttn-1])
{
for(j=[0:sn-1])
{
pt = [[0,0,ist-st],
[ir
cos(jlfxy),    irsin(jlfxy),    ist+jzt-st
],
[ir
cos((j+1)lfxy), irsin((j+1)lfxy),
i
st+(j+1)zt-st  ],
[0,0,i
st],
[orcos(jlfxy),    orsin(jlfxy),    ist+jzt-st/2
],
[orcos((j+1)lfxy), orsin((j+1)lfxy),
i
st+(j+1)zt-st/2 ],
[ir
cos(j
lfxy),    irsin(jlfxy),    ist+jzt ],
[ir*cos((j+1)lfxy), irsin((j+1)lfxy), ist+(j+1)zt
],
[0,0,i
st+st]];

         polyhedron(points=pt,faces=[[1,0,3],[1,3,6],[6,3,8],[1,6,4],

//changed triangles to faces (to be deprecated)
[0,1,2],[1,4,2],[2,4,5],[5,4,6],[5,6,7],[7,6,8],
[7,8,3],[0,2,3],[3,2,7],[7,2,5]        ]);
}
}
}
else
{
echo("Step Degrees too agresive, the thread will not be made!!");
echo("Try to increase de value for the degrees and/or...");
echo(" decrease the pitch value and/or...");
echo(" increase the outer diameter value.");
}
}

module hex_head(hg,df)
{
rd0=df/2/sin(60);
x0=0;  x1=df/2;        x2=x1+hg/2;
y0=0;  y1=hg/2;        y2=hg;

     intersection()
     {
        cylinder(h=hg, r=rd0, $fn=facets, center=false);

             rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
             polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
     }

}

module hex_head_0(hg,df)
{
cylinder(h=hg, r=df/2/sin(60), $fn=6, center=false);
}

module hex_countersink_ends(chg,cod,clf,crs,hg)
{
translate([0,0,-0.1])
cylinder(h=chg+0.01,
r1=cod/2,
r2=cod/2-(chg+0.1)cos(clf)/sin(clf),
$fn=floor(cod
PI/crs), center=false);

 translate([0,0,hg-chg+0.1])
 cylinder(h=chg+0.01,
          r1=cod/2-(chg+0.1)*cos(clf)/sin(clf),
          r2=cod/2,
          $fn=floor(cod*PI/crs), center=false);

}


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I think imperial pots have 3/8" 32 tpi threads. The picture looks like a metric pot and they have M10 nuts with 0.75mm pitch, which is much finer than a normal M10 fine thread. There is a potentiometer model in NopSCADlib and there is even a pot_nut() module to draw the nuts for them with the correct thread but I have never tried printing one. On Wed, 14 Jun 2023 at 15:11, Terry <terrypingm@gmail.com> wrote: > It's a very long time since I used OpenSCAD and my printer, so 'rusty' > would be a gross understatement ;-) But to finish my current (hobby > electronics) project I need a nut to fit a '10 mm' pot. > > Embedded images made my earlier post attempt too large so have used > links instead. > > https://www.dropbox.com/s/84qorbyh9ueskzf/Dimensions.jpg?raw=1 > > I have a dozen or so pots, probably none under 40 years old, which are > without their nuts. I tried the hundred or so of my 'spare' nuts in vain > > https://www.dropbox.com/s/eutnqjdw869s955/PotNutFails.jpg?raw=1 > > Strangely, the only thing that worked was this enormous nut, 6.45 mm > thick, with only 3 threads in that length. (That's approx,as I'm unclear > about the start and end points for measuring pitch.) And obviously far > too bulky to use. > > https://www.dropbox.com/s/gw2hfkp1pp2bizd/LargeNut.jpg?raw=1 > > I could order an appropriate pot with accompanying nut, but I hate to > waste stuff. Once I have a nut for today's job I'll make a bunch of > them. > > I downloaded Nut_job.scad from this promising page: > https://www.thingiverse.com/thing:193647/files > > And then tentatively customised it to get the code below, which I'll > paste in full at the end. > > https://www.dropbox.com/s/8i4hwzc689rjgfm/NutJob-1.jpg?raw=1 > > But before I re-learn the little OpenSCAD I once knew, dust off my Ender > 3 V2 etc, could I please get advice on the appropriateness or otherwise > of that code. Or even a 'starter example' based on one of the libraries, > such as NopHead's NopSCADlib or BOSL2. > > In a nutshell (sorry), I'm frankly looking for a quick practical > solution, postponing study until later. > > The code: > > /* 'Nut Job' nut, bolt, washer and threaded rod factory by Mike Thompson > 1/12/2013, Thingiverse: mike_linus > * > * Licensing: This work is licensed under a Creative Commons > Attribution-NonCommercial-ShareAlike 3.0 Australia License. > * Further information is available here - > http://creativecommons.org/licenses/by-nc-sa/3.0/au/deed.en_GB > * > * v2 8/12/2013 - added socket head types > * v3 2/11/2014 - adjusted wing nut algorithm for better behaviour with > unusual nut sizes and added ISO262 metric references > * v4 31/12/2014 - added optional texture to socket heads, added ability > to change the number of facets for a hex head > * and adjusted wingnut base level on certain nut sizes > * v5 11/1/2015 - added phillips and slot drive types and improved > texture handling > * v6 21/2/2015 - added wing ratio to wingnuts > * v7 6/3/2016 - added extended options to control number of facets on > nuts, square sockets (or any number of facets) and socket depth control > * v8 1/1/2017 - modified library code to remove dependence on > deprecated 'assign' statement > * > * This script generates nuts, bolts, washers and threaded rod using the > library > * script: polyScrewThead.scad (modified/updated version > polyScrewThread_r1.scad) > * http://www.thingiverse.com/thing:8796, CC Public Domain > * > * Defaults are for a 8mm diameter bolts, rod, matching nuts and wing > nuts that work well together > * without cleanup or modification. Some default parameters such as the > nut outer diameter are deliberately > * altered to produce a snug fit that can still be hand tightened. This > may need to be altered > * depending on individual printer variances, slicing tools, filament > etc. Suggest printing a matching > * bolt and nut and adjusting as necessary. Note: slow print speeds, > low temperatures and solid > * fill are recommended for best results. > */ > > /* [Component Type] */ > > type = > "bolt";//[nut,bolt,rod,washer] > > /* [Bolt and Rod Options] */ > > //Head type - Hex, Socket Cap, Button Socket Cap or Countersunk Socket > Cap (ignored for Rod) > head_type = > "hex";//[hex,socket,button,countersunk] > //Drive type - Socket, Phillips, Slot (ignored for Hex head type and > Rod) > drive_type = "socket";//[socket,phillips,slot] > //Distance between flats for the hex head or diameter for socket or > button head (ignored for Rod) > head_diameter = 12; > //Height of the head (ignored for Rod) > head_height = 5; > //Diameter of drive type (ignored for Hex head and Rod) > drive_diameter = 5; > //Width of slot aperture for phillips or slot drive types > slot_width = 1; > //Depth of slot aperture for slot drive type > slot_depth = 2; > //Surface texture (socket head only) > texture = "exclude";//[include,exclude] > //Outer diameter of the thread > thread_outer_diameter = 8; > //Thread step or Pitch (2mm works well for most applications ref. > ISO262: M3=0.5,M4=0.7,M5=0.8,M6=1,M8=1.25,M10=1.5) > thread_step = 2; > //Step shape degrees (45 degrees is optimised for most printers ref. > ISO262: 30 degrees) > step_shape_degrees = 45; > //Length of the threaded section > thread_length = 25; > //Countersink in both ends > countersink = 2; > //Length of the non-threaded section > non_thread_length = 0; > //Diameter for the non-threaded section (-1: Same as inner diameter of > the thread, 0: Same as outer diameter of the thread, value: The given > value) > non_thread_diameter = 0; > > /* [Nut Options] */ > > //Type: Normal or WingNut > nut_type = "normal";//[normal,wingnut] > //Distance between flats for the hex nut > nut_diameter = 12; > //Height of the nut > nut_height = 6; > //Outer diameter of the bolt thread to match (usually set about 1mm > larger than bolt diameter to allow easy fit - adjust to personal > preferences) > nut_thread_outer_diameter = 9; > //Thread step or Pitch (2mm works well for most applications ref. > ISO262: M3=0.5,M4=0.7,M5=0.8,M6=1,M8=1.25,M10=1.5) > nut_thread_step = 2; > //Step shape degrees (45 degrees is optimised for most printers ref. > ISO262: 30 degrees) > nut_step_shape_degrees = 45; > //Wing radius ratio. The proportional radius of the wing on the wing > nut compared to the nut height value (default = 1) > wing_ratio = 1; > wing_radius=wing_ratio * nut_height; > > /* [Washer Options] */ > > //Inner Diameter (suggest making diameter slightly larger than bolt > diameter) > inner_diameter = 8; > //Outer Diameter > outer_diameter = 14; > //Thickness > thickness = 2; > > /* [Extended Options] */ > > //Number of facets for hex head type or nut. Default is 6 for standard > hex head and nut > facets = 6; > //Number of facets for hole in socket head. Default is 6 for standard > hex socket > socket_facets = 6; > //Depth of hole in socket head. Default is 3.5 > socket_depth = 3.5; > //Resolution (lower values for higher resolution, but may slow > rendering) > resolution = 0.5; > nut_resolution = resolution; > > //Hex Bolt > if (type=="bolt" && head_type=="hex") > { > > > hex_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,head_height,non_thread_length,non_thread_diameter); > } > > //Rod > if (type=="rod") > { > > > hex_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,0,non_thread_length,non_thread_diameter); > } > > //Hex Nut (normally slightly larger outer diameter to fit on bolt > correctly) > if (type=="nut" && nut_type=="normal") > { > > > hex_nut(nut_diameter,nut_height,nut_thread_step,nut_step_shape_degrees,nut_thread_outer_diameter,nut_resolution); > } > > //Wing Nut variation of hex nut. Cylinders added to each side of nut for > easy turning - ideal for quick release applications > if (type=="nut" && nut_type=="wingnut") > { > > > rotate([0,0,30])hex_nut(nut_diameter,nut_height,nut_thread_step,nut_step_shape_degrees,nut_thread_outer_diameter,nut_resolution); > //nut > > > translate([(nut_diameter/2)+wing_radius-1,1.5,wing_radius/2+1])rotate([90,0,0])wing(); > //attach wing > > > mirror(1,0,0)translate([(nut_diameter/2)+wing_radius-1,1.5,wing_radius/2+1])rotate([90,0,0])wing(); > //attach wing > } > > module wing() > { > difference() > { > cylinder(r=wing_radius,h=3,$fn=64); //cylinder > union() > { > > > translate([-wing_radius,-wing_radius-1,-0.5])cube([wing_radius*2,wing_radius/2,wing_radius*2]); > //remove overhang so flush with base of nut > > > rotate([0,0,90])translate([-wing_radius,wing_radius-1,-0.5])cube([wing_radius*2,wing_radius/2,wing_radius*2]); > //remove overhangs so flush with side of nut > } > } > } > > //Washer > if (type=="washer") > { > difference() > { > cylinder(r=outer_diameter/2,h=thickness,$fn=100); > > translate([0,0,-0.1])cylinder(r=inner_diameter/2,h=thickness+0.2,$fn=100); > } > } > > //Socket Head Bolt > if (type=="bolt" && head_type!="hex") > { > > > socket_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,head_height,non_thread_length,non_thread_diameter); > } > > module phillips_base() > { > > > linear_extrude(slot_width)polygon(points=[[0,0],[(drive_diameter-slot_width)/2,9/5*(drive_diameter-slot_width)/2],[(drive_diameter+slot_width)/2,9/5*(drive_diameter-slot_width)/2],[drive_diameter,0]]); > > > translate([(drive_diameter-slot_width)/2,0,(drive_diameter+slot_width)/2])rotate([0,90,0])linear_extrude(slot_width)polygon(points=[[0,0],[(drive_diameter-slot_width)/2,9/5*(drive_diameter-slot_width)/2],[(drive_diameter+slot_width)/2,9/5*(drive_diameter-slot_width)/2],[drive_diameter,0]]); > } > > module phillips_fillet() > { > union() > { > > > translate([-(drive_diameter-slot_width)/2-(slot_width/2),slot_width/2,0])rotate([90,0,0])phillips_base(); > translate([0,0,9/5*(drive_diameter-slot_width)/2])union() > { > inner_curve(); > rotate([0,0,90])inner_curve(); > rotate([0,0,180])inner_curve(); > rotate([0,0,270])inner_curve(); > } > } > } > > module inner_curve() > { > > > translate([slot_width/2,-slot_width/2,0])rotate([0,90,0])linear_fillet(9/5*(drive_diameter-slot_width)/2,drive_diameter/10); > } > > //basic 2d profile used for fillet shape > module profile(radius) > { > difference() > { > square(radius); > circle(r=radius); > } > } > > //linear fillet for use along straight edges > module linear_fillet(length,profile_radius) > { > > > translate([0,-profile_radius,profile_radius])rotate([0,90,0])linear_extrude(height=length,convexity=10)profile(profile_radius); > } > > module phillips_drive() > { > intersection() > { > phillips_fillet(); > > > cylinder(9/5*(drive_diameter-slot_width)/2,drive_diameter/2+(slot_width/2),slot_width/2); > } > } > > module socket_screw(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd) > { > ntr=od/2-(st/2)*cos(lf0)/sin(lf0); > $fn=60; > > difference() > { > union() > { > if (head_type=="socket") > { > socket_head(hg,df); > } > > if (head_type=="button") > { > button_head(hg,df); > > } > > if (head_type=="countersunk") > { > countersunk_head(hg,df); > > } > > translate([0,0,hg]) > if ( ntl == 0 ) > { > cylinder(h=0.01, r=ntr, center=true); > } > else > { > if ( ntd == -1 ) > { > cylinder(h=ntl+0.01, r=ntr, > $fn=floor(od*PI/rs), center=false); > } > else if ( ntd == 0 ) > { > union() > { > cylinder(h=ntl-st/2,r=od/2, > $fn=floor(od*PI/rs), center=false); > translate([0,0,ntl-st/2]) > cylinder(h=st/2, > r1=od/2, r2=ntr, > $fn=floor(od*PI/rs), center=false); > } > } > else > { > cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, > center=false); > } > } > translate([0,0,ntl+hg]) > screw_thread(od,st,lf0,lt,rs,cs); > } > //create opening for specific drive type > if (drive_type=="socket") > { > cylinder(r=drive_diameter/2,h=socket_depth,$fn=socket_facets); //socket > > > #translate([0,0,socket_depth])cylinder(r1=drive_diameter/2,r2=0,h=drive_diameter/3,$fn=socket_facets); > //socket tapers at base to allow printing without bridging and improve > socket grip > } > else > { > if (drive_type=="phillips") > { > translate([0,0,-0.001])phillips_drive(); > } > else //slot > { > > > translate([-(drive_diameter)/2,slot_width/2,-0.001])rotate([90,0,0])cube([drive_diameter,slot_depth,slot_width]); > } > } > } > } > > module socket_head(hg,df) > { > texture_points=2*PI*(head_diameter/2); > texture_offset=head_diameter/18; > texture_radius=head_diameter/24; > > rd0=df/2/sin(60); > x0=0; x1=df/2; x2=x1+hg/2; > y0=0; y1=hg/2; y2=hg; > > intersection() > { > cylinder(h=hg, r=rd0, $fn=60, center=false); > rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5)) > polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]); > } > > if (texture=="include") //add texture to socket head. Adjust > texture density and size using texture variables above > { > for (i= [1:texture_points]) > { > translate([cos(360/texture_points*i)*(head_diameter/2+texture_offset), > sin(360/texture_points*i)*(head_diameter/2+texture_offset), 1 ]) > > > rotate([0,0,360/texture_points*i])cylinder(r=texture_radius,h=head_height*0.6,$fn=3); > } > } > > } > > module button_head(hg,df) > { > rd0=df/2/sin(60); > x0=0; x1=df/2; x2=x1+hg/2; > y0=0; y1=hg/2; y2=hg; > > intersection() > { > cylinder(h=hg, r1=drive_diameter/2 + 1, r2=rd0, $fn=60, > center=false); > rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5)) > polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]); > } > } > > module countersunk_head(hg,df) > { > rd0=df/2/sin(60); > x0=0; x1=df/2; x2=x1+hg/2; > y0=0; y1=hg/2; y2=hg; > > intersection() > { > cylinder(h=hg, r1=rd0, r2=thread_outer_diameter/2-0.5, $fn=60, > center=false); > > rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5)) > polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]); > } > } > > /* Library included below to allow customizer functionality > * > * polyScrewThread_r1.scad by aubenc @ Thingiverse > * > * Modified by mike_mattala @ Thingiverse 1/1/2017 to remove deprecated > assign > * > * This script contains the library modules that can be used to generate > * threaded rods, screws and nuts. > * > * http://www.thingiverse.com/thing:8796 > * > * CC Public Domain > */ > > module screw_thread(od,st,lf0,lt,rs,cs) > { > or=od/2; > ir=or-st/2*cos(lf0)/sin(lf0); > pf=2*PI*or; > sn=floor(pf/rs); > lfxy=360/sn; > ttn=round(lt/st+1); > zt=st/sn; > > intersection() > { > if (cs >= -1) > { > thread_shape(cs,lt,or,ir,sn,st); > } > > full_thread(ttn,st,sn,zt,lfxy,or,ir); > } > } > > module hex_nut(df,hg,sth,clf,cod,crs) > { > > difference() > { > hex_head(hg,df); > > hex_countersink_ends(sth/2,cod,clf,crs,hg); > > screw_thread(cod,sth,clf,hg,crs,-2); > } > } > > > module hex_screw(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd) > { > ntr=od/2-(st/2)*cos(lf0)/sin(lf0); > > union() > { > hex_head(hg,df); > > translate([0,0,hg]) > if ( ntl == 0 ) > { > cylinder(h=0.01, r=ntr, center=true); > } > else > { > if ( ntd == -1 ) > { > cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs), > center=false); > } > else if ( ntd == 0 ) > { > union() > { > cylinder(h=ntl-st/2, > r=od/2, $fn=floor(od*PI/rs), center=false); > > translate([0,0,ntl-st/2]) > cylinder(h=st/2, > r1=od/2, r2=ntr, > $fn=floor(od*PI/rs), center=false); > } > } > else > { > cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false); > } > } > > translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs); > } > } > > module hex_screw_0(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd) > { > ntr=od/2-(st/2)*cos(lf0)/sin(lf0); > > union() > { > hex_head_0(hg,df); > > translate([0,0,hg]) > if ( ntl == 0 ) > { > cylinder(h=0.01, r=ntr, center=true); > } > else > { > if ( ntd == -1 ) > { > cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs), > center=false); > } > else if ( ntd == 0 ) > { > union() > { > cylinder(h=ntl-st/2, > r=od/2, $fn=floor(od*PI/rs), center=false); > > translate([0,0,ntl-st/2]) > cylinder(h=st/2, > r1=od/2, r2=ntr, > $fn=floor(od*PI/rs), center=false); > } > } > else > { > cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false); > } > } > > translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs); > } > } > > module thread_shape(cs,lt,or,ir,sn,st) > { > if ( cs == 0 ) > { > cylinder(h=lt, r=or, $fn=sn, center=false); > } > else > { > union() > { > translate([0,0,st/2]) > cylinder(h=lt-st+0.005, r=or, $fn=sn, center=false); > > if ( cs == -1 || cs == 2 ) > { > cylinder(h=st/2, r1=ir, r2=or, $fn=sn, center=false); > } > else > { > cylinder(h=st/2, r=or, $fn=sn, center=false); > } > > translate([0,0,lt-st/2]) > if ( cs == 1 || cs == 2 ) > { > cylinder(h=st/2, r1=or, r2=ir, $fn=sn, center=false); > } > else > { > cylinder(h=st/2, r=or, $fn=sn, center=false); > } > } > } > } > > module full_thread(ttn,st,sn,zt,lfxy,or,ir) > { > if(ir >= 0.2) > { > for(i=[0:ttn-1]) > { > for(j=[0:sn-1]) > { > pt = [[0,0,i*st-st], > [ir*cos(j*lfxy), ir*sin(j*lfxy), i*st+j*zt-st > ], > [ir*cos((j+1)*lfxy), ir*sin((j+1)*lfxy), > i*st+(j+1)*zt-st ], > [0,0,i*st], > [or*cos(j*lfxy), or*sin(j*lfxy), i*st+j*zt-st/2 > ], > [or*cos((j+1)*lfxy), or*sin((j+1)*lfxy), > i*st+(j+1)*zt-st/2 ], > [ir*cos(j*lfxy), ir*sin(j*lfxy), i*st+j*zt ], > [ir*cos((j+1)*lfxy), ir*sin((j+1)*lfxy), i*st+(j+1)*zt > ], > [0,0,i*st+st]]; > > polyhedron(points=pt,faces=[[1,0,3],[1,3,6],[6,3,8],[1,6,4], > //changed triangles to faces (to be deprecated) > [0,1,2],[1,4,2],[2,4,5],[5,4,6],[5,6,7],[7,6,8], > [7,8,3],[0,2,3],[3,2,7],[7,2,5] ]); > } > } > } > else > { > echo("Step Degrees too agresive, the thread will not be made!!"); > echo("Try to increase de value for the degrees and/or..."); > echo(" decrease the pitch value and/or..."); > echo(" increase the outer diameter value."); > } > } > > module hex_head(hg,df) > { > rd0=df/2/sin(60); > x0=0; x1=df/2; x2=x1+hg/2; > y0=0; y1=hg/2; y2=hg; > > intersection() > { > cylinder(h=hg, r=rd0, $fn=facets, center=false); > > rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5)) > polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]); > } > } > > module hex_head_0(hg,df) > { > cylinder(h=hg, r=df/2/sin(60), $fn=6, center=false); > } > > module hex_countersink_ends(chg,cod,clf,crs,hg) > { > translate([0,0,-0.1]) > cylinder(h=chg+0.01, > r1=cod/2, > r2=cod/2-(chg+0.1)*cos(clf)/sin(clf), > $fn=floor(cod*PI/crs), center=false); > > translate([0,0,hg-chg+0.1]) > cylinder(h=chg+0.01, > r1=cod/2-(chg+0.1)*cos(clf)/sin(clf), > r2=cod/2, > $fn=floor(cod*PI/crs), center=false); > } > > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
T
terrypingm@gmail.com
Wed, Jun 14, 2023 3:34 PM

Thanks Roger, I too had thought about self-threading. And will now experiment with it, starting with your code. But as that heavy duty nut had such a coarse thread (2 mm ?) and yet still worked, I wondered if a much thinner nut of similar thread might be a solution?

Terry

On 14 Jun 2023, at 15:33, nop head <nop.head@gmail.com> wrote:

I think imperial pots have 3/8" 32 tpi threads. The picture looks like a metric pot and they have M10 nuts with 0.75mm pitch, which is much finer than a normal M10 fine thread.

There is a potentiometer model in NopSCADlib and there is even a pot_nut() module to draw the nuts for them with the correct thread but I have never tried printing one.

On Wed, 14 Jun 2023 at 15:11, Terry <terrypingm@gmail.com> wrote:

It's a very long time since I used OpenSCAD and my printer, so 'rusty'
would be a gross understatement ;-) But to finish my current (hobby
electronics) project I need a nut to fit a '10 mm' pot.

Embedded images made my earlier post attempt too large so have used
links instead.

https://www.dropbox.com/s/84qorbyh9ueskzf/Dimensions.jpg?raw=1

I have a dozen or so pots, probably none under 40 years old, which are
without their nuts. I tried the hundred or so of my 'spare' nuts in vain

https://www.dropbox.com/s/eutnqjdw869s955/PotNutFails.jpg?raw=1

Strangely, the only thing that worked was this enormous nut, 6.45 mm
thick, with only 3 threads in that length. (That's approx,as I'm unclear
about the start and end points for measuring pitch.) And obviously far
too bulky to use.

https://www.dropbox.com/s/gw2hfkp1pp2bizd/LargeNut.jpg?raw=1

I could order an appropriate pot with accompanying nut, but I hate to
waste stuff. Once I have a nut for today's job I'll make a bunch of
them.

I downloaded Nut_job.scad from this promising page:
https://www.thingiverse.com/thing:193647/files

And then tentatively customised it to get the code below, which I'll
paste in full at the end.

https://www.dropbox.com/s/8i4hwzc689rjgfm/NutJob-1.jpg?raw=1

But before I re-learn the little OpenSCAD I once knew, dust off my Ender
3 V2 etc, could I please get advice on the appropriateness or otherwise
of that code. Or even a 'starter example' based on one of the libraries,
such as NopHead's NopSCADlib or BOSL2.

In a nutshell (sorry), I'm frankly looking for a quick practical
solution, postponing study until later.

The code:

/* 'Nut Job' nut, bolt, washer and threaded rod factory by Mike Thompson
1/12/2013, Thingiverse: mike_linus
*
* Licensing: This work is licensed under a Creative Commons
Attribution-NonCommercial-ShareAlike 3.0 Australia License.
* Further information is available here -
http://creativecommons.org/licenses/by-nc-sa/3.0/au/deed.en_GB
*
* v2 8/12/2013 - added socket head types
* v3 2/11/2014 - adjusted wing nut algorithm for better behaviour with
unusual nut sizes and added ISO262 metric references
* v4 31/12/2014 - added optional texture to socket heads, added ability
to change the number of facets for a hex head
* and adjusted wingnut base level on certain nut sizes
* v5 11/1/2015 - added phillips and slot drive types and improved
texture handling
* v6 21/2/2015 - added wing ratio to wingnuts
* v7 6/3/2016 - added extended options to control number of facets on
nuts, square sockets (or any number of facets) and socket depth control
* v8 1/1/2017 - modified library code to remove dependence on
deprecated 'assign' statement
*
* This script generates nuts, bolts, washers and threaded rod using the
library
* script: polyScrewThead.scad (modified/updated version
polyScrewThread_r1.scad)
* http://www.thingiverse.com/thing:8796, CC Public Domain
*
* Defaults are for a 8mm diameter bolts, rod, matching nuts and wing
nuts that work well together
* without cleanup or modification. Some default parameters such as the
nut outer diameter are deliberately
* altered to produce a snug fit that can still be hand tightened. This
may need to be altered
* depending on individual printer variances, slicing tools, filament
etc. Suggest printing a matching
* bolt and nut and adjusting as necessary. Note: slow print speeds,
low temperatures and solid
* fill are recommended for best results.
*/

/* [Component Type] */

type = "bolt";//[nut,bolt,rod,washer]

/* [Bolt and Rod Options] */

//Head type - Hex, Socket Cap, Button Socket Cap or Countersunk Socket
Cap (ignored for Rod)
head_type =
"hex";//[hex,socket,button,countersunk]
//Drive type - Socket, Phillips, Slot (ignored for Hex head type and
Rod)
drive_type = "socket";//[socket,phillips,slot]
//Distance between flats for the hex head or diameter for socket or
button head (ignored for Rod)
head_diameter = 12;
//Height of the head (ignored for Rod)
head_height = 5;
//Diameter of drive type (ignored for Hex head and Rod)
drive_diameter = 5;
//Width of slot aperture for phillips or slot drive types
slot_width = 1;
//Depth of slot aperture for slot drive type
slot_depth = 2;
//Surface texture (socket head only)
texture = "exclude";//[include,exclude]
//Outer diameter of the thread
thread_outer_diameter = 8;
//Thread step or Pitch (2mm works well for most applications ref.
ISO262: M3=0.5,M4=0.7,M5=0.8,M6=1,M8=1.25,M10=1.5)
thread_step = 2;
//Step shape degrees (45 degrees is optimised for most printers ref.
ISO262: 30 degrees)
step_shape_degrees = 45;
//Length of the threaded section
thread_length = 25;
//Countersink in both ends
countersink = 2;
//Length of the non-threaded section
non_thread_length = 0;
//Diameter for the non-threaded section (-1: Same as inner diameter of
the thread, 0: Same as outer diameter of the thread, value: The given
value)
non_thread_diameter = 0;

/* [Nut Options] */

//Type: Normal or WingNut
nut_type = "normal";//[normal,wingnut]
//Distance between flats for the hex nut
nut_diameter = 12;
//Height of the nut
nut_height = 6;
//Outer diameter of the bolt thread to match (usually set about 1mm
larger than bolt diameter to allow easy fit - adjust to personal
preferences)
nut_thread_outer_diameter = 9;
//Thread step or Pitch (2mm works well for most applications ref.
ISO262: M3=0.5,M4=0.7,M5=0.8,M6=1,M8=1.25,M10=1.5)
nut_thread_step = 2;
//Step shape degrees (45 degrees is optimised for most printers ref.
ISO262: 30 degrees)
nut_step_shape_degrees = 45;
//Wing radius ratio. The proportional radius of the wing on the wing
nut compared to the nut height value (default = 1)
wing_ratio = 1;
wing_radius=wing_ratio * nut_height;

/* [Washer Options] */

//Inner Diameter (suggest making diameter slightly larger than bolt
diameter)
inner_diameter = 8;
//Outer Diameter
outer_diameter = 14;
//Thickness
thickness = 2;

/* [Extended Options] */

//Number of facets for hex head type or nut. Default is 6 for standard
hex head and nut
facets = 6;
//Number of facets for hole in socket head. Default is 6 for standard
hex socket
socket_facets = 6;
//Depth of hole in socket head. Default is 3.5
socket_depth = 3.5;
//Resolution (lower values for higher resolution, but may slow
rendering)
resolution = 0.5;
nut_resolution = resolution;

//Hex Bolt
if (type=="bolt" && head_type=="hex")
{

hex_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,head_height,non_thread_length,non_thread_diameter);
}

//Rod
if (type=="rod")
{

hex_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,0,non_thread_length,non_thread_diameter);
}

//Hex Nut (normally slightly larger outer diameter to fit on bolt
correctly)
if (type=="nut" && nut_type=="normal")
{

hex_nut(nut_diameter,nut_height,nut_thread_step,nut_step_shape_degrees,nut_thread_outer_diameter,nut_resolution);
}

//Wing Nut variation of hex nut. Cylinders added to each side of nut for
easy turning - ideal for quick release applications
if (type=="nut" && nut_type=="wingnut")
{

rotate([0,0,30])hex_nut(nut_diameter,nut_height,nut_thread_step,nut_step_shape_degrees,nut_thread_outer_diameter,nut_resolution);
//nut

translate([(nut_diameter/2)+wing_radius-1,1.5,wing_radius/2+1])rotate([90,0,0])wing();
//attach wing

mirror(1,0,0)translate([(nut_diameter/2)+wing_radius-1,1.5,wing_radius/2+1])rotate([90,0,0])wing();
//attach wing
}

module wing()
{
difference()
{
cylinder(r=wing_radius,h=3,$fn=64); //cylinder
union()
{

translate([-wing_radius,-wing_radius-1,-0.5])cube([wing_radius*2,wing_radius/2,wing_radius*2]);
//remove overhang so flush with base of nut

rotate([0,0,90])translate([-wing_radius,wing_radius-1,-0.5])cube([wing_radius*2,wing_radius/2,wing_radius*2]);
//remove overhangs so flush with side of nut
}
}
}

//Washer
if (type=="washer")
{
difference()
{
cylinder(r=outer_diameter/2,h=thickness,$fn=100);

translate([0,0,-0.1])cylinder(r=inner_diameter/2,h=thickness+0.2,$fn=100);
}
}

//Socket Head Bolt
if (type=="bolt" && head_type!="hex")
{

socket_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,head_height,non_thread_length,non_thread_diameter);
}

module phillips_base()
{

linear_extrude(slot_width)polygon(points=[[0,0],[(drive_diameter-slot_width)/2,9/5*(drive_diameter-slot_width)/2],[(drive_diameter+slot_width)/2,9/5*(drive_diameter-slot_width)/2],[drive_diameter,0]]);

translate([(drive_diameter-slot_width)/2,0,(drive_diameter+slot_width)/2])rotate([0,90,0])linear_extrude(slot_width)polygon(points=[[0,0],[(drive_diameter-slot_width)/2,9/5*(drive_diameter-slot_width)/2],[(drive_diameter+slot_width)/2,9/5*(drive_diameter-slot_width)/2],[drive_diameter,0]]);
}

module phillips_fillet()
{
union()
{

translate([-(drive_diameter-slot_width)/2-(slot_width/2),slot_width/2,0])rotate([90,0,0])phillips_base();
translate([0,0,9/5*(drive_diameter-slot_width)/2])union()
{
inner_curve();
rotate([0,0,90])inner_curve();
rotate([0,0,180])inner_curve();
rotate([0,0,270])inner_curve();
}
}
}

module inner_curve()
{

translate([slot_width/2,-slot_width/2,0])rotate([0,90,0])linear_fillet(9/5*(drive_diameter-slot_width)/2,drive_diameter/10);
}

//basic 2d profile used for fillet shape
module profile(radius)
{
difference()
{
square(radius);
circle(r=radius);
}
}

//linear fillet for use along straight edges
module linear_fillet(length,profile_radius)
{

translate([0,-profile_radius,profile_radius])rotate([0,90,0])linear_extrude(height=length,convexity=10)profile(profile_radius);
}

module phillips_drive()
{
intersection()
{
phillips_fillet();

cylinder(9/5*(drive_diameter-slot_width)/2,drive_diameter/2+(slot_width/2),slot_width/2);
}
}

module socket_screw(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd)
{
ntr=od/2-(st/2)*cos(lf0)/sin(lf0);
$fn=60;

difference()
{
union()
{
if (head_type=="socket")
{
socket_head(hg,df);
}

if (head_type=="button")
{
button_head(hg,df);
}

if (head_type=="countersunk")
{
countersunk_head(hg,df);
}

translate([0,0,hg])
if ( ntl == 0 )
{
cylinder(h=0.01, r=ntr, center=true);
}
else
{
if ( ntd == -1 )
{
cylinder(h=ntl+0.01, r=ntr,
$fn=floor(od*PI/rs), center=false);
}
else if ( ntd == 0 )
{
union()
{
cylinder(h=ntl-st/2,r=od/2,
$fn=floor(od*PI/rs), center=false);
translate([0,0,ntl-st/2])
cylinder(h=st/2,
r1=od/2, r2=ntr,
$fn=floor(od*PI/rs), center=false);
}
}
else
{
cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs,
center=false);
}
}
translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs);
}
//create opening for specific drive type
if (drive_type=="socket")
{
cylinder(r=drive_diameter/2,h=socket_depth,$fn=socket_facets); //socket

#translate([0,0,socket_depth])cylinder(r1=drive_diameter/2,r2=0,h=drive_diameter/3,$fn=socket_facets);
//socket tapers at base to allow printing without bridging and improve
socket grip
}
else
{
if (drive_type=="phillips")
{
translate([0,0,-0.001])phillips_drive();
}
else //slot
{

translate([-(drive_diameter)/2,slot_width/2,-0.001])rotate([90,0,0])cube([drive_diameter,slot_depth,slot_width]);
}
}
}
}

module socket_head(hg,df)
{
texture_points=2*PI*(head_diameter/2);
texture_offset=head_diameter/18;
texture_radius=head_diameter/24;

rd0=df/2/sin(60);
x0=0; x1=df/2; x2=x1+hg/2;
y0=0; y1=hg/2; y2=hg;

intersection()
{
cylinder(h=hg, r=rd0, $fn=60, center=false);
rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
}

if (texture=="include") //add texture to socket head. Adjust
texture density and size using texture variables above
{
for (i= [1:texture_points])
{
translate([cos(360/texture_points*i)*(head_diameter/2+texture_offset),
sin(360/texture_points*i)*(head_diameter/2+texture_offset), 1 ])

rotate([0,0,360/texture_points*i])cylinder(r=texture_radius,h=head_height*0.6,$fn=3);
}
}

}

module button_head(hg,df)
{
rd0=df/2/sin(60);
x0=0; x1=df/2; x2=x1+hg/2;
y0=0; y1=hg/2; y2=hg;

intersection()
{
cylinder(h=hg, r1=drive_diameter/2 + 1, r2=rd0, $fn=60,
center=false);
rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
}
}

module countersunk_head(hg,df)
{
rd0=df/2/sin(60);
x0=0; x1=df/2; x2=x1+hg/2;
y0=0; y1=hg/2; y2=hg;

intersection()
{
cylinder(h=hg, r1=rd0, r2=thread_outer_diameter/2-0.5, $fn=60,
center=false);

rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
}
}

/* Library included below to allow customizer functionality
*
* polyScrewThread_r1.scad by aubenc @ Thingiverse
*
* Modified by mike_mattala @ Thingiverse 1/1/2017 to remove deprecated
assign
*
* This script contains the library modules that can be used to generate
* threaded rods, screws and nuts.
*
* http://www.thingiverse.com/thing:8796
*
* CC Public Domain
*/

module screw_thread(od,st,lf0,lt,rs,cs)
{
or=od/2;
ir=or-st/2*cos(lf0)/sin(lf0);
pf=2*PI*or;
sn=floor(pf/rs);
lfxy=360/sn;
ttn=round(lt/st+1);
zt=st/sn;

intersection()
{
if (cs >= -1)
{
thread_shape(cs,lt,or,ir,sn,st);
}

full_thread(ttn,st,sn,zt,lfxy,or,ir);
}
}

module hex_nut(df,hg,sth,clf,cod,crs)
{

difference()
{
hex_head(hg,df);

hex_countersink_ends(sth/2,cod,clf,crs,hg);

screw_thread(cod,sth,clf,hg,crs,-2);
}
}

module hex_screw(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd)
{
ntr=od/2-(st/2)*cos(lf0)/sin(lf0);

union()
{
hex_head(hg,df);

translate([0,0,hg])
if ( ntl == 0 )
{
cylinder(h=0.01, r=ntr, center=true);
}
else
{
if ( ntd == -1 )
{
cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs),
center=false);
}
else if ( ntd == 0 )
{
union()
{
cylinder(h=ntl-st/2,
r=od/2, $fn=floor(od*PI/rs), center=false);

translate([0,0,ntl-st/2])
cylinder(h=st/2,
r1=od/2, r2=ntr,
$fn=floor(od*PI/rs), center=false);
}
}
else
{
cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false);
}
}

translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs);
}
}

module hex_screw_0(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd)
{
ntr=od/2-(st/2)*cos(lf0)/sin(lf0);

union()
{
hex_head_0(hg,df);

translate([0,0,hg])
if ( ntl == 0 )
{
cylinder(h=0.01, r=ntr, center=true);
}
else
{
if ( ntd == -1 )
{
cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs),
center=false);
}
else if ( ntd == 0 )
{
union()
{
cylinder(h=ntl-st/2,
r=od/2, $fn=floor(od*PI/rs), center=false);

translate([0,0,ntl-st/2])
cylinder(h=st/2,
r1=od/2, r2=ntr,
$fn=floor(od*PI/rs), center=false);
}
}
else
{
cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false);
}
}

translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs);
}
}

module thread_shape(cs,lt,or,ir,sn,st)
{
if ( cs == 0 )
{
cylinder(h=lt, r=or, $fn=sn, center=false);
}
else
{
union()
{
translate([0,0,st/2])
cylinder(h=lt-st+0.005, r=or, $fn=sn, center=false);

if ( cs == -1 || cs == 2 )
{
cylinder(h=st/2, r1=ir, r2=or, $fn=sn, center=false);
}
else
{
cylinder(h=st/2, r=or, $fn=sn, center=false);
}

translate([0,0,lt-st/2])
if ( cs == 1 || cs == 2 )
{
cylinder(h=st/2, r1=or, r2=ir, $fn=sn, center=false);
}
else
{
cylinder(h=st/2, r=or, $fn=sn, center=false);
}
}
}
}

module full_thread(ttn,st,sn,zt,lfxy,or,ir)
{
if(ir >= 0.2)
{
for(i=[0:ttn-1])
{
for(j=[0:sn-1])
{
pt = [[0,0,i*st-st],
[ir*cos(j*lfxy), ir*sin(j*lfxy), i*st+j*zt-st
],
[ir*cos((j+1)*lfxy), ir*sin((j+1)*lfxy),
i*st+(j+1)*zt-st ],
[0,0,i*st],
[or*cos(j*lfxy), or*sin(j*lfxy), i*st+j*zt-st/2
],
[or*cos((j+1)*lfxy), or*sin((j+1)*lfxy),
i*st+(j+1)*zt-st/2 ],
[ir*cos(j*lfxy), ir*sin(j*lfxy), i*st+j*zt ],
[ir*cos((j+1)*lfxy), ir*sin((j+1)*lfxy), i*st+(j+1)*zt
],
[0,0,i*st+st]];

polyhedron(points=pt,faces=[[1,0,3],[1,3,6],[6,3,8],[1,6,4],
//changed triangles to faces (to be deprecated)
[0,1,2],[1,4,2],[2,4,5],[5,4,6],[5,6,7],[7,6,8],
[7,8,3],[0,2,3],[3,2,7],[7,2,5] ]);
}
}
}
else
{
echo("Step Degrees too agresive, the thread will not be made!!");
echo("Try to increase de value for the degrees and/or...");
echo(" decrease the pitch value and/or...");
echo(" increase the outer diameter value.");
}
}

module hex_head(hg,df)
{
rd0=df/2/sin(60);
x0=0; x1=df/2; x2=x1+hg/2;
y0=0; y1=hg/2; y2=hg;

intersection()
{
cylinder(h=hg, r=rd0, $fn=facets, center=false);

rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
}
}

module hex_head_0(hg,df)
{
cylinder(h=hg, r=df/2/sin(60), $fn=6, center=false);
}

module hex_countersink_ends(chg,cod,clf,crs,hg)
{
translate([0,0,-0.1])
cylinder(h=chg+0.01,
r1=cod/2,
r2=cod/2-(chg+0.1)*cos(clf)/sin(clf),
$fn=floor(cod*PI/crs), center=false);

translate([0,0,hg-chg+0.1])
cylinder(h=chg+0.01,
r1=cod/2-(chg+0.1)*cos(clf)/sin(clf),
r2=cod/2,
$fn=floor(cod*PI/crs), center=false);
}

_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

T
terrypingm@gmail.com
Wed, Jun 14, 2023 3:38 PM

Thanks nop head. I’ll first try Roger’s self-threading (tapping?) approach, although see also my reply to him about a ‘coarse’ thread.

--

Terry

On 14 Jun 2023, at 16:34, terrypingm@gmail.com wrote:

Thanks Roger, I too had thought about self-threading. And will now experiment with it, starting with your code. But as that heavy duty nut had such a coarse thread (2 mm ?) and yet still worked, I wondered if a much thinner nut of similar thread might be a solution?

Terry

On 14 Jun 2023, at 15:33, nop head <nop.head@gmail.com> wrote:

I think imperial pots have 3/8" 32 tpi threads. The picture looks like a metric pot and they have M10 nuts with 0.75mm pitch, which is much finer than a normal M10 fine thread.

There is a potentiometer model in NopSCADlib and there is even a pot_nut() module to draw the nuts for them with the correct thread but I have never tried printing one.

On Wed, 14 Jun 2023 at 15:11, Terry <terrypingm@gmail.com> wrote:

It's a very long time since I used OpenSCAD and my printer, so 'rusty'
would be a gross understatement ;-) But to finish my current (hobby
electronics) project I need a nut to fit a '10 mm' pot.

Embedded images made my earlier post attempt too large so have used
links instead.

https://www.dropbox.com/s/84qorbyh9ueskzf/Dimensions.jpg?raw=1

I have a dozen or so pots, probably none under 40 years old, which are
without their nuts. I tried the hundred or so of my 'spare' nuts in vain

https://www.dropbox.com/s/eutnqjdw869s955/PotNutFails.jpg?raw=1

Strangely, the only thing that worked was this enormous nut, 6.45 mm
thick, with only 3 threads in that length. (That's approx,as I'm unclear
about the start and end points for measuring pitch.) And obviously far
too bulky to use.

https://www.dropbox.com/s/gw2hfkp1pp2bizd/LargeNut.jpg?raw=1

I could order an appropriate pot with accompanying nut, but I hate to
waste stuff. Once I have a nut for today's job I'll make a bunch of
them.

I downloaded Nut_job.scad from this promising page:
https://www.thingiverse.com/thing:193647/files

And then tentatively customised it to get the code below, which I'll
paste in full at the end.

https://www.dropbox.com/s/8i4hwzc689rjgfm/NutJob-1.jpg?raw=1

But before I re-learn the little OpenSCAD I once knew, dust off my Ender
3 V2 etc, could I please get advice on the appropriateness or otherwise
of that code. Or even a 'starter example' based on one of the libraries,
such as NopHead's NopSCADlib or BOSL2.

In a nutshell (sorry), I'm frankly looking for a quick practical
solution, postponing study until later.

The code:

/* 'Nut Job' nut, bolt, washer and threaded rod factory by Mike Thompson
1/12/2013, Thingiverse: mike_linus
*
* Licensing: This work is licensed under a Creative Commons
Attribution-NonCommercial-ShareAlike 3.0 Australia License.
* Further information is available here -
http://creativecommons.org/licenses/by-nc-sa/3.0/au/deed.en_GB
*
* v2 8/12/2013 - added socket head types
* v3 2/11/2014 - adjusted wing nut algorithm for better behaviour with
unusual nut sizes and added ISO262 metric references
* v4 31/12/2014 - added optional texture to socket heads, added ability
to change the number of facets for a hex head
* and adjusted wingnut base level on certain nut sizes
* v5 11/1/2015 - added phillips and slot drive types and improved
texture handling
* v6 21/2/2015 - added wing ratio to wingnuts
* v7 6/3/2016 - added extended options to control number of facets on
nuts, square sockets (or any number of facets) and socket depth control
* v8 1/1/2017 - modified library code to remove dependence on
deprecated 'assign' statement
*
* This script generates nuts, bolts, washers and threaded rod using the
library
* script: polyScrewThead.scad (modified/updated version
polyScrewThread_r1.scad)
* http://www.thingiverse.com/thing:8796, CC Public Domain
*
* Defaults are for a 8mm diameter bolts, rod, matching nuts and wing
nuts that work well together
* without cleanup or modification. Some default parameters such as the
nut outer diameter are deliberately
* altered to produce a snug fit that can still be hand tightened. This
may need to be altered
* depending on individual printer variances, slicing tools, filament
etc. Suggest printing a matching
* bolt and nut and adjusting as necessary. Note: slow print speeds,
low temperatures and solid
* fill are recommended for best results.
*/

/* [Component Type] */

type = "bolt";//[nut,bolt,rod,washer]

/* [Bolt and Rod Options] */

//Head type - Hex, Socket Cap, Button Socket Cap or Countersunk Socket
Cap (ignored for Rod)
head_type =
"hex";//[hex,socket,button,countersunk]
//Drive type - Socket, Phillips, Slot (ignored for Hex head type and
Rod)
drive_type = "socket";//[socket,phillips,slot]
//Distance between flats for the hex head or diameter for socket or
button head (ignored for Rod)
head_diameter = 12;
//Height of the head (ignored for Rod)
head_height = 5;
//Diameter of drive type (ignored for Hex head and Rod)
drive_diameter = 5;
//Width of slot aperture for phillips or slot drive types
slot_width = 1;
//Depth of slot aperture for slot drive type
slot_depth = 2;
//Surface texture (socket head only)
texture = "exclude";//[include,exclude]
//Outer diameter of the thread
thread_outer_diameter = 8;
//Thread step or Pitch (2mm works well for most applications ref.
ISO262: M3=0.5,M4=0.7,M5=0.8,M6=1,M8=1.25,M10=1.5)
thread_step = 2;
//Step shape degrees (45 degrees is optimised for most printers ref.
ISO262: 30 degrees)
step_shape_degrees = 45;
//Length of the threaded section
thread_length = 25;
//Countersink in both ends
countersink = 2;
//Length of the non-threaded section
non_thread_length = 0;
//Diameter for the non-threaded section (-1: Same as inner diameter of
the thread, 0: Same as outer diameter of the thread, value: The given
value)
non_thread_diameter = 0;

/* [Nut Options] */

//Type: Normal or WingNut
nut_type = "normal";//[normal,wingnut]
//Distance between flats for the hex nut
nut_diameter = 12;
//Height of the nut
nut_height = 6;
//Outer diameter of the bolt thread to match (usually set about 1mm
larger than bolt diameter to allow easy fit - adjust to personal
preferences)
nut_thread_outer_diameter = 9;
//Thread step or Pitch (2mm works well for most applications ref.
ISO262: M3=0.5,M4=0.7,M5=0.8,M6=1,M8=1.25,M10=1.5)
nut_thread_step = 2;
//Step shape degrees (45 degrees is optimised for most printers ref.
ISO262: 30 degrees)
nut_step_shape_degrees = 45;
//Wing radius ratio. The proportional radius of the wing on the wing
nut compared to the nut height value (default = 1)
wing_ratio = 1;
wing_radius=wing_ratio * nut_height;

/* [Washer Options] */

//Inner Diameter (suggest making diameter slightly larger than bolt
diameter)
inner_diameter = 8;
//Outer Diameter
outer_diameter = 14;
//Thickness
thickness = 2;

/* [Extended Options] */

//Number of facets for hex head type or nut. Default is 6 for standard
hex head and nut
facets = 6;
//Number of facets for hole in socket head. Default is 6 for standard
hex socket
socket_facets = 6;
//Depth of hole in socket head. Default is 3.5
socket_depth = 3.5;
//Resolution (lower values for higher resolution, but may slow
rendering)
resolution = 0.5;
nut_resolution = resolution;

//Hex Bolt
if (type=="bolt" && head_type=="hex")
{

hex_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,head_height,non_thread_length,non_thread_diameter);
}

//Rod
if (type=="rod")
{

hex_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,0,non_thread_length,non_thread_diameter);
}

//Hex Nut (normally slightly larger outer diameter to fit on bolt
correctly)
if (type=="nut" && nut_type=="normal")
{

hex_nut(nut_diameter,nut_height,nut_thread_step,nut_step_shape_degrees,nut_thread_outer_diameter,nut_resolution);
}

//Wing Nut variation of hex nut. Cylinders added to each side of nut for
easy turning - ideal for quick release applications
if (type=="nut" && nut_type=="wingnut")
{

rotate([0,0,30])hex_nut(nut_diameter,nut_height,nut_thread_step,nut_step_shape_degrees,nut_thread_outer_diameter,nut_resolution);
//nut

translate([(nut_diameter/2)+wing_radius-1,1.5,wing_radius/2+1])rotate([90,0,0])wing();
//attach wing

mirror(1,0,0)translate([(nut_diameter/2)+wing_radius-1,1.5,wing_radius/2+1])rotate([90,0,0])wing();
//attach wing
}

module wing()
{
difference()
{
cylinder(r=wing_radius,h=3,$fn=64); //cylinder
union()
{

translate([-wing_radius,-wing_radius-1,-0.5])cube([wing_radius*2,wing_radius/2,wing_radius*2]);
//remove overhang so flush with base of nut

rotate([0,0,90])translate([-wing_radius,wing_radius-1,-0.5])cube([wing_radius*2,wing_radius/2,wing_radius*2]);
//remove overhangs so flush with side of nut
}
}
}

//Washer
if (type=="washer")
{
difference()
{
cylinder(r=outer_diameter/2,h=thickness,$fn=100);

translate([0,0,-0.1])cylinder(r=inner_diameter/2,h=thickness+0.2,$fn=100);
}
}

//Socket Head Bolt
if (type=="bolt" && head_type!="hex")
{

socket_screw(thread_outer_diameter,thread_step,step_shape_degrees,thread_length,resolution,countersink,head_diameter,head_height,non_thread_length,non_thread_diameter);
}

module phillips_base()
{

linear_extrude(slot_width)polygon(points=[[0,0],[(drive_diameter-slot_width)/2,9/5*(drive_diameter-slot_width)/2],[(drive_diameter+slot_width)/2,9/5*(drive_diameter-slot_width)/2],[drive_diameter,0]]);

translate([(drive_diameter-slot_width)/2,0,(drive_diameter+slot_width)/2])rotate([0,90,0])linear_extrude(slot_width)polygon(points=[[0,0],[(drive_diameter-slot_width)/2,9/5*(drive_diameter-slot_width)/2],[(drive_diameter+slot_width)/2,9/5*(drive_diameter-slot_width)/2],[drive_diameter,0]]);
}

module phillips_fillet()
{
union()
{

translate([-(drive_diameter-slot_width)/2-(slot_width/2),slot_width/2,0])rotate([90,0,0])phillips_base();
translate([0,0,9/5*(drive_diameter-slot_width)/2])union()
{
inner_curve();
rotate([0,0,90])inner_curve();
rotate([0,0,180])inner_curve();
rotate([0,0,270])inner_curve();
}
}
}

module inner_curve()
{

translate([slot_width/2,-slot_width/2,0])rotate([0,90,0])linear_fillet(9/5*(drive_diameter-slot_width)/2,drive_diameter/10);
}

//basic 2d profile used for fillet shape
module profile(radius)
{
difference()
{
square(radius);
circle(r=radius);
}
}

//linear fillet for use along straight edges
module linear_fillet(length,profile_radius)
{

translate([0,-profile_radius,profile_radius])rotate([0,90,0])linear_extrude(height=length,convexity=10)profile(profile_radius);
}

module phillips_drive()
{
intersection()
{
phillips_fillet();

cylinder(9/5*(drive_diameter-slot_width)/2,drive_diameter/2+(slot_width/2),slot_width/2);
}
}

module socket_screw(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd)
{
ntr=od/2-(st/2)*cos(lf0)/sin(lf0);
$fn=60;

difference()
{
union()
{
if (head_type=="socket")
{
socket_head(hg,df);
}

if (head_type=="button")
{
button_head(hg,df);
}

if (head_type=="countersunk")
{
countersunk_head(hg,df);
}

translate([0,0,hg])
if ( ntl == 0 )
{
cylinder(h=0.01, r=ntr, center=true);
}
else
{
if ( ntd == -1 )
{
cylinder(h=ntl+0.01, r=ntr,
$fn=floor(od*PI/rs), center=false);
}
else if ( ntd == 0 )
{
union()
{
cylinder(h=ntl-st/2,r=od/2,
$fn=floor(od*PI/rs), center=false);
translate([0,0,ntl-st/2])
cylinder(h=st/2,
r1=od/2, r2=ntr,
$fn=floor(od*PI/rs), center=false);
}
}
else
{
cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs,
center=false);
}
}
translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs);
}
//create opening for specific drive type
if (drive_type=="socket")
{
cylinder(r=drive_diameter/2,h=socket_depth,$fn=socket_facets); //socket

#translate([0,0,socket_depth])cylinder(r1=drive_diameter/2,r2=0,h=drive_diameter/3,$fn=socket_facets);
//socket tapers at base to allow printing without bridging and improve
socket grip
}
else
{
if (drive_type=="phillips")
{
translate([0,0,-0.001])phillips_drive();
}
else //slot
{

translate([-(drive_diameter)/2,slot_width/2,-0.001])rotate([90,0,0])cube([drive_diameter,slot_depth,slot_width]);
}
}
}
}

module socket_head(hg,df)
{
texture_points=2*PI*(head_diameter/2);
texture_offset=head_diameter/18;
texture_radius=head_diameter/24;

rd0=df/2/sin(60);
x0=0; x1=df/2; x2=x1+hg/2;
y0=0; y1=hg/2; y2=hg;

intersection()
{
cylinder(h=hg, r=rd0, $fn=60, center=false);
rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
}

if (texture=="include") //add texture to socket head. Adjust
texture density and size using texture variables above
{
for (i= [1:texture_points])
{
translate([cos(360/texture_points*i)*(head_diameter/2+texture_offset),
sin(360/texture_points*i)*(head_diameter/2+texture_offset), 1 ])

rotate([0,0,360/texture_points*i])cylinder(r=texture_radius,h=head_height*0.6,$fn=3);
}
}

}

module button_head(hg,df)
{
rd0=df/2/sin(60);
x0=0; x1=df/2; x2=x1+hg/2;
y0=0; y1=hg/2; y2=hg;

intersection()
{
cylinder(h=hg, r1=drive_diameter/2 + 1, r2=rd0, $fn=60,
center=false);
rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
}
}

module countersunk_head(hg,df)
{
rd0=df/2/sin(60);
x0=0; x1=df/2; x2=x1+hg/2;
y0=0; y1=hg/2; y2=hg;

intersection()
{
cylinder(h=hg, r1=rd0, r2=thread_outer_diameter/2-0.5, $fn=60,
center=false);

rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
}
}

/* Library included below to allow customizer functionality
*
* polyScrewThread_r1.scad by aubenc @ Thingiverse
*
* Modified by mike_mattala @ Thingiverse 1/1/2017 to remove deprecated
assign
*
* This script contains the library modules that can be used to generate
* threaded rods, screws and nuts.
*
* http://www.thingiverse.com/thing:8796
*
* CC Public Domain
*/

module screw_thread(od,st,lf0,lt,rs,cs)
{
or=od/2;
ir=or-st/2*cos(lf0)/sin(lf0);
pf=2*PI*or;
sn=floor(pf/rs);
lfxy=360/sn;
ttn=round(lt/st+1);
zt=st/sn;

intersection()
{
if (cs >= -1)
{
thread_shape(cs,lt,or,ir,sn,st);
}

full_thread(ttn,st,sn,zt,lfxy,or,ir);
}
}

module hex_nut(df,hg,sth,clf,cod,crs)
{

difference()
{
hex_head(hg,df);

hex_countersink_ends(sth/2,cod,clf,crs,hg);

screw_thread(cod,sth,clf,hg,crs,-2);
}
}

module hex_screw(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd)
{
ntr=od/2-(st/2)*cos(lf0)/sin(lf0);

union()
{
hex_head(hg,df);

translate([0,0,hg])
if ( ntl == 0 )
{
cylinder(h=0.01, r=ntr, center=true);
}
else
{
if ( ntd == -1 )
{
cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs),
center=false);
}
else if ( ntd == 0 )
{
union()
{
cylinder(h=ntl-st/2,
r=od/2, $fn=floor(od*PI/rs), center=false);

translate([0,0,ntl-st/2])
cylinder(h=st/2,
r1=od/2, r2=ntr,
$fn=floor(od*PI/rs), center=false);
}
}
else
{
cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false);
}
}

translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs);
}
}

module hex_screw_0(od,st,lf0,lt,rs,cs,df,hg,ntl,ntd)
{
ntr=od/2-(st/2)*cos(lf0)/sin(lf0);

union()
{
hex_head_0(hg,df);

translate([0,0,hg])
if ( ntl == 0 )
{
cylinder(h=0.01, r=ntr, center=true);
}
else
{
if ( ntd == -1 )
{
cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs),
center=false);
}
else if ( ntd == 0 )
{
union()
{
cylinder(h=ntl-st/2,
r=od/2, $fn=floor(od*PI/rs), center=false);

translate([0,0,ntl-st/2])
cylinder(h=st/2,
r1=od/2, r2=ntr,
$fn=floor(od*PI/rs), center=false);
}
}
else
{
cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false);
}
}

translate([0,0,ntl+hg]) screw_thread(od,st,lf0,lt,rs,cs);
}
}

module thread_shape(cs,lt,or,ir,sn,st)
{
if ( cs == 0 )
{
cylinder(h=lt, r=or, $fn=sn, center=false);
}
else
{
union()
{
translate([0,0,st/2])
cylinder(h=lt-st+0.005, r=or, $fn=sn, center=false);

if ( cs == -1 || cs == 2 )
{
cylinder(h=st/2, r1=ir, r2=or, $fn=sn, center=false);
}
else
{
cylinder(h=st/2, r=or, $fn=sn, center=false);
}

translate([0,0,lt-st/2])
if ( cs == 1 || cs == 2 )
{
cylinder(h=st/2, r1=or, r2=ir, $fn=sn, center=false);
}
else
{
cylinder(h=st/2, r=or, $fn=sn, center=false);
}
}
}
}

module full_thread(ttn,st,sn,zt,lfxy,or,ir)
{
if(ir >= 0.2)
{
for(i=[0:ttn-1])
{
for(j=[0:sn-1])
{
pt = [[0,0,i*st-st],
[ir*cos(j*lfxy), ir*sin(j*lfxy), i*st+j*zt-st
],
[ir*cos((j+1)*lfxy), ir*sin((j+1)*lfxy),
i*st+(j+1)*zt-st ],
[0,0,i*st],
[or*cos(j*lfxy), or*sin(j*lfxy), i*st+j*zt-st/2
],
[or*cos((j+1)*lfxy), or*sin((j+1)*lfxy),
i*st+(j+1)*zt-st/2 ],
[ir*cos(j*lfxy), ir*sin(j*lfxy), i*st+j*zt ],
[ir*cos((j+1)*lfxy), ir*sin((j+1)*lfxy), i*st+(j+1)*zt
],
[0,0,i*st+st]];

polyhedron(points=pt,faces=[[1,0,3],[1,3,6],[6,3,8],[1,6,4],
//changed triangles to faces (to be deprecated)
[0,1,2],[1,4,2],[2,4,5],[5,4,6],[5,6,7],[7,6,8],
[7,8,3],[0,2,3],[3,2,7],[7,2,5] ]);
}
}
}
else
{
echo("Step Degrees too agresive, the thread will not be made!!");
echo("Try to increase de value for the degrees and/or...");
echo(" decrease the pitch value and/or...");
echo(" increase the outer diameter value.");
}
}

module hex_head(hg,df)
{
rd0=df/2/sin(60);
x0=0; x1=df/2; x2=x1+hg/2;
y0=0; y1=hg/2; y2=hg;

intersection()
{
cylinder(h=hg, r=rd0, $fn=facets, center=false);

rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
}
}

module hex_head_0(hg,df)
{
cylinder(h=hg, r=df/2/sin(60), $fn=6, center=false);
}

module hex_countersink_ends(chg,cod,clf,crs,hg)
{
translate([0,0,-0.1])
cylinder(h=chg+0.01,
r1=cod/2,
r2=cod/2-(chg+0.1)*cos(clf)/sin(clf),
$fn=floor(cod*PI/crs), center=false);

translate([0,0,hg-chg+0.1])
cylinder(h=chg+0.01,
r1=cod/2-(chg+0.1)*cos(clf)/sin(clf),
r2=cod/2,
$fn=floor(cod*PI/crs), center=false);
}

_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

RW
Rogier Wolff
Wed, Jun 14, 2023 3:58 PM

On Wed, Jun 14, 2023 at 04:38:40PM +0100, terrypingm@gmail.com wrote:

... Roger's suggestion ...

I didn't reply that to the list as it is kind of ugly. :-)

(I suggested just a "round" hole, and some experimentation to find the
right size for the involved printer. I myself screw M3 screws into a
round 3mm hole. The undersizing of the hole when 3D printing happens to
be just right... )

Roger.

--
** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 **
**    Delftechpark 11 2628 XJ  Delft, The Netherlands.  KVK: 27239233    **
f equals m times a. When your f is steady, and your m is going down
your a is going up.  -- Chris Hadfield about flying up the space shuttle.

On Wed, Jun 14, 2023 at 04:38:40PM +0100, terrypingm@gmail.com wrote: > ... Roger's suggestion ... I didn't reply that to the list as it is kind of ugly. :-) (I suggested just a "round" hole, and some experimentation to find the right size for the involved printer. I myself screw M3 screws into a round 3mm hole. The undersizing of the hole when 3D printing happens to be just right... ) Roger. -- ** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 ** ** Delftechpark 11 2628 XJ Delft, The Netherlands. KVK: 27239233 ** f equals m times a. When your f is steady, and your m is going down your a is going up. -- Chris Hadfield about flying up the space shuttle.
P
pproj@posteo.de
Wed, Jun 14, 2023 4:16 PM

I was was looking at constructive tutorials, and it just stroke me, that
i urgently need to brag about it :)

look, this is all valid openscad:

include  <constructive-compiled.scad >

$skinThick=1.5;//thickness of the Skin in mm

assemble()
{
addRemove(height(skin(20)))
// hull() //you can add hull here
{
g(X(-10),chamfer(-4,-4-1))
tube( d=  skin(30),solid=true);

         g(X(4),chamfer(-1,-1,-5))
             box(skin(37), skin(18), h=skin(4));
 }
 remove(TOLEFT(TOFRONT))    box(30);

}

it creates this:

screen

isn't that cool? with so few lines of code, you  even get skins.

No hidden magic here:

$skinThick=1.5 is just the default value for omitted parameter of the
skin(dimension,skinThick) function. Just same objects added ans
subtracted with reduced sizes.

So why don't i just go and ....., ehmn.... create and use a standalone
library? well i did, and i use it for years, Just felt that i need to
brag.something wrong with it?

 you can do much with few lines of code.

Hope nobody is annoyed too much. somebody even interested... perhaps.

pproj.

code taken from:

https://github.com/solidboredom/constructive/blob/main/tutorials/tutorial-partIII.md#easily-create-skins-with-skinsize0skinthickskinthick--walls2----marginmargin

I was was looking at constructive tutorials, and it just stroke me, that i urgently need to brag about it :) look, this is all valid openscad: include <constructive-compiled.scad > $skinThick=1.5;//thickness of the Skin in mm assemble() { addRemove(height(skin(20))) // hull() //you can add hull here { g(X(-10),chamfer(-4,-4-1)) tube( d= skin(30),solid=true); g(X(4),chamfer(-1,-1,-5)) box(skin(37), skin(18), h=skin(4)); } remove(TOLEFT(TOFRONT)) box(30); } it creates this: screen isn't that cool? with so few lines of code, you  even get skins. No hidden magic here: $skinThick=1.5 is just the default value for omitted parameter of the skin(dimension,skinThick) function. Just same objects added ans subtracted with reduced sizes. So why don't i just go and ....., ehmn.... create and use a standalone library? well i did, and i use it for years, Just felt that i need to brag.something wrong with it?  you can do much with few lines of code. Hope nobody is annoyed too much. somebody even interested... perhaps. pproj. code taken from: https://github.com/solidboredom/constructive/blob/main/tutorials/tutorial-partIII.md#easily-create-skins-with-skinsize0skinthickskinthick--walls2----marginmargin
N
neri-engineering
Wed, Jun 14, 2023 10:27 PM

I totally agree that fewer lines of code is better, esp. when it does things correctly and quickly. Bravo.

As another example, see how clear this code is, for computing the angle between two vectors in 3-space.

// Returns an angle in the range [0,180]. Vectors need not be normalized.
function angle_between(vec1,vec2)=
atan2(vector_length(cross_product(vec1,vec2)), dot_product(vec1,vec2));

Supporting code for that:

function cross_product(vec1,vec2)=
[vec1[1]*vec2[2]-vec1[2]*vec2[1],
vec1[2]*vec2[0]-vec1[0]*vec2[2], vec1[0]*vec2[1]-vec1[1]*vec2[0]];

function vector_length(vec)=sqrt(vector_length_2(vec));

function vector_length_2(vec)=
vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2];

function dot_product(vec1,vec2)=
vec1[0]*vec2[0]+vec1[1]*vec2[1]+vec1[2]*vec2[2];

Sent with Proton Mail secure email.

------- Original Message -------
On Wednesday, June 14th, 2023 at 11:16 AM, pproj@posteo.de pproj@posteo.de wrote:

I was was looking at constructive tutorials, and it just stroke me, that i urgently need to brag about it :)

look, this is all valid openscad:

include

<

constructive

compiled.scad

$

skinThick

=

1.5

;

//

thickness of the Skin in mm

assemble()
{
addRemove(height(skin(

20

)))
// hull() //you can add hull here
{
g(X(

10

),chamfer(

4

,

4

1

))
tube( d

=

skin(

30

),solid

=

true

);

         g(X(

4

),chamfer(

1

,

1

,

5

))
box(skin(

37

), skin(

18

), h

=

skin(

4

));
}
remove(TOLEFT(TOFRONT))    box(

30

);
}

it creates this:

[screen]

isn't that cool? with so few lines of code, you even get skins.

No hidden magic here:

$

skinThick

=

1.5 is just the default value for omitted parameter of the skin(dimension,

skinThick

) function. Just same objects added ans subtracted with reduced sizes.

So why don't i just go and ....., ehmn.... create and use a standalone library? well i did, and i use it for years, Just felt that i need to brag.something wrong with it?

you can do much with few lines of code.

Hope nobody is annoyed too much. somebody even interested... perhaps.

pproj.

code taken from:

https://github.com/solidboredom/constructive/blob/main/tutorials/tutorial-partIII.md#easily-create-skins-with-skinsize0skinthickskinthick--walls2----marginmargin

I totally agree that fewer lines of code is better, esp. when it does things correctly and quickly. Bravo. As another example, see how clear this code is, for computing the angle between two vectors in 3-space. // Returns an angle in the range [0,180]. Vectors need not be normalized. function angle_between(vec1,vec2)= atan2(vector_length(cross_product(vec1,vec2)), dot_product(vec1,vec2)); Supporting code for that: function cross_product(vec1,vec2)= [vec1[1]*vec2[2]-vec1[2]*vec2[1], vec1[2]*vec2[0]-vec1[0]*vec2[2], vec1[0]*vec2[1]-vec1[1]*vec2[0]]; function vector_length(vec)=sqrt(vector_length_2(vec)); function vector_length_2(vec)= vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]; function dot_product(vec1,vec2)= vec1[0]*vec2[0]+vec1[1]*vec2[1]+vec1[2]*vec2[2]; Sent with [Proton Mail](https://proton.me/) secure email. ------- Original Message ------- On Wednesday, June 14th, 2023 at 11:16 AM, pproj@posteo.de <pproj@posteo.de> wrote: > I was was looking at constructive tutorials, and it just stroke me, that i urgently need to brag about it :) > > look, this is all valid openscad: > > include > > < > > constructive > > - > > compiled.scad > >> > > $ > > skinThick > > = > > 1.5 > > ; > > // > > thickness of the Skin in mm > > assemble() > { > addRemove(height(skin( > > 20 > > ))) > // hull() //you can add hull here > { > g(X( > > - > > 10 > > ),chamfer( > > - > > 4 > > , > > - > > 4 > > - > > 1 > > )) > tube( d > > = > > skin( > > 30 > > ),solid > > = > > true > > ); > > g(X( > > 4 > > ),chamfer( > > - > > 1 > > , > > - > > 1 > > , > > - > > 5 > > )) > box(skin( > > 37 > > ), skin( > > 18 > > ), h > > = > > skin( > > 4 > > )); > } > remove(TOLEFT(TOFRONT)) box( > > 30 > > ); > } > > it creates this: > > [screen] > > isn't that cool? with so few lines of code, you even get skins. > > No hidden magic here: > > $ > > skinThick > > = > > 1.5 is just the default value for omitted parameter of the skin(dimension, > > skinThick > > ) function. Just same objects added ans subtracted with reduced sizes. > > So why don't i just go and ....., ehmn.... create and use a standalone library? well i did, and i use it for years, Just felt that i need to brag.something wrong with it? > > you can do much with few lines of code. > > Hope nobody is annoyed too much. somebody even interested... perhaps. > > pproj. > > code taken from: > > https://github.com/solidboredom/constructive/blob/main/tutorials/tutorial-partIII.md#easily-create-skins-with-skinsize0skinthickskinthick--walls2----marginmargin
T
terrypingm@gmail.com
Thu, Jun 15, 2023 5:12 AM

I suspect that the self tapping method for M3 nuts is more successful than it will be for M10, because of the mechanics of starting the thread. Do you do it entirely by hand, or use accessories to assist with positioning the nut at right angles to the bolt, and to apply more force while maintaining that position?

Of course, the hole diameter is critical. I printed from that simple code and was rather surprised at how much smaller the hole was than specified. I’ll ream it out a bit.

If you print multiples of your M3 nuts, what approach do you find best? Just dragging the STL files onto Cura in a close group? Or coding so that they are physically joined at one easily broken point, for stability and faster printing? Or…

Terry

On 14 Jun 2023, at 16:58, Rogier Wolff R.E.Wolff@bitwizard.nl wrote:

On Wed, Jun 14, 2023 at 04:38:40PM +0100, terrypingm@gmail.com wrote:

... Roger's suggestion ...

I didn't reply that to the list as it is kind of ugly. :-)

(I suggested just a "round" hole, and some experimentation to find the
right size for the involved printer. I myself screw M3 screws into a
round 3mm hole. The undersizing of the hole when 3D printing happens to
be just right... )

Roger.

--
** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 **
**    Delftechpark 11 2628 XJ  Delft, The Netherlands.  KVK: 27239233    **
f equals m times a. When your f is steady, and your m is going down
your a is going up.  -- Chris Hadfield about flying up the space shuttle.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I suspect that the self tapping method for M3 nuts is more successful than it will be for M10, because of the mechanics of starting the thread. Do you do it entirely by hand, or use accessories to assist with positioning the nut at right angles to the bolt, and to apply more force while maintaining that position? Of course, the hole diameter is critical. I printed from that simple code and was rather surprised at how much smaller the hole was than specified. I’ll ream it out a bit. If you print multiples of your M3 nuts, what approach do you find best? Just dragging the STL files onto Cura in a close group? Or coding so that they are physically joined at one easily broken point, for stability and faster printing? Or… Terry On 14 Jun 2023, at 16:58, Rogier Wolff <R.E.Wolff@bitwizard.nl> wrote: On Wed, Jun 14, 2023 at 04:38:40PM +0100, terrypingm@gmail.com wrote: > ... Roger's suggestion ... I didn't reply that to the list as it is kind of ugly. :-) (I suggested just a "round" hole, and some experimentation to find the right size for the involved printer. I myself screw M3 screws into a round 3mm hole. The undersizing of the hole when 3D printing happens to be just right... ) Roger. -- ** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 ** ** Delftechpark 11 2628 XJ Delft, The Netherlands. KVK: 27239233 ** f equals m times a. When your f is steady, and your m is going down your a is going up. -- Chris Hadfield about flying up the space shuttle. _______________________________________________ OpenSCAD mailing list To unsubscribe send an email to discuss-leave@lists.openscad.org
RW
Rogier Wolff
Thu, Jun 15, 2023 5:48 AM

On Thu, Jun 15, 2023 at 06:12:59AM +0100, terrypingm@gmail.com wrote:

I suspect that the self tapping method for M3 nuts is more
successful than it will be for M10, because of the mechanics of
starting the thread. Do you do it entirely by hand, or use
accessories to assist with positioning the nut at right angles to
the bolt, and to apply more force while maintaining that position?

Yeah, for the small thickness nut it may make sense to print a helper
tool.

Of course, the hole diameter is critical. I printed from that simple
code and was rather surprised at how much smaller the hole was than
specified. I’ll ream it out a bit.

If manually reaming, the inside will be uneven. A "printed-in-one-go"
will need to be slightly larger.

I'm not printing M3 nuts. I'm screwing things to a larger 3D printed
object. One of the 3d-printing-youtube-gurus once tested those brass
hot-inserts. Turns out they are not stronger than "screw directly into
the plastic" like I'm doing.

If you print multiples of your M3 nuts, what approach do you find
best? Just dragging the STL files onto Cura in a close group? Or
coding so that they are physically joined at one easily broken
point, for stability and faster printing? Or…

I've never done M3 nuts. I just buy them 100 at a time. (actually last
few times: 10 bags of 100 at a time).

I do print large numbers of small objects.

You could do:

module mynut ()
{
cylinder (d=18.9,h=2,$fn=6);
}

module mynuts ()
{
mynut ();
translate ([15,8.5,0]) mynut ();
}

module array (nx, xp, ny, yp)
{
for (i=[0:1:nx-1])
for (j=[0:1:ny-1])
translate ([ixp, jyp,0]) children ();
}

array (3,30,5,17) mynuts ();
//array (5,20,5,17) mynut ();

but I usually code the "array" module inline in my maincode. BOSL will
surely have a helper function for this.

Roger. 

Terry

On 14 Jun 2023, at 16:58, Rogier Wolff R.E.Wolff@bitwizard.nl wrote:

On Wed, Jun 14, 2023 at 04:38:40PM +0100, terrypingm@gmail.com wrote:

... Roger's suggestion ...

I didn't reply that to the list as it is kind of ugly. :-)

(I suggested just a "round" hole, and some experimentation to find the
right size for the involved printer. I myself screw M3 screws into a
round 3mm hole. The undersizing of the hole when 3D printing happens to
be just right... )

Roger.

--
** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 **
**    Delftechpark 11 2628 XJ  Delft, The Netherlands.  KVK: 27239233    **
f equals m times a. When your f is steady, and your m is going down
your a is going up.  -- Chris Hadfield about flying up the space shuttle.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

--
** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 **
**    Delftechpark 11 2628 XJ  Delft, The Netherlands.  KVK: 27239233    **
f equals m times a. When your f is steady, and your m is going down
your a is going up.  -- Chris Hadfield about flying up the space shuttle.

On Thu, Jun 15, 2023 at 06:12:59AM +0100, terrypingm@gmail.com wrote: > I suspect that the self tapping method for M3 nuts is more > successful than it will be for M10, because of the mechanics of > starting the thread. Do you do it entirely by hand, or use > accessories to assist with positioning the nut at right angles to > the bolt, and to apply more force while maintaining that position? Yeah, for the small thickness nut it may make sense to print a helper tool. > Of course, the hole diameter is critical. I printed from that simple > code and was rather surprised at how much smaller the hole was than > specified. I’ll ream it out a bit. If manually reaming, the inside will be uneven. A "printed-in-one-go" will need to be slightly larger. I'm not printing M3 nuts. I'm screwing things to a larger 3D printed object. One of the 3d-printing-youtube-gurus once tested those brass hot-inserts. Turns out they are not stronger than "screw directly into the plastic" like I'm doing. > If you print multiples of your M3 nuts, what approach do you find > best? Just dragging the STL files onto Cura in a close group? Or > coding so that they are physically joined at one easily broken > point, for stability and faster printing? Or… I've never done M3 nuts. I just buy them 100 at a time. (actually last few times: 10 bags of 100 at a time). I do print large numbers of small objects. You could do: module mynut () { cylinder (d=18.9,h=2,$fn=6); } module mynuts () { mynut (); translate ([15,8.5,0]) mynut (); } module array (nx, xp, ny, yp) { for (i=[0:1:nx-1]) for (j=[0:1:ny-1]) translate ([i*xp, j*yp,0]) children (); } array (3,30,5,17) mynuts (); //array (5,20,5,17) mynut (); but I usually code the "array" module inline in my maincode. BOSL will surely have a helper function for this. Roger. > > Terry > > On 14 Jun 2023, at 16:58, Rogier Wolff <R.E.Wolff@bitwizard.nl> wrote: > > On Wed, Jun 14, 2023 at 04:38:40PM +0100, terrypingm@gmail.com wrote: > > > ... Roger's suggestion ... > > I didn't reply that to the list as it is kind of ugly. :-) > > (I suggested just a "round" hole, and some experimentation to find the > right size for the involved printer. I myself screw M3 screws into a > round 3mm hole. The undersizing of the hole when 3D printing happens to > be just right... ) > > Roger. > > -- > ** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 ** > ** Delftechpark 11 2628 XJ Delft, The Netherlands. KVK: 27239233 ** > f equals m times a. When your f is steady, and your m is going down > your a is going up. -- Chris Hadfield about flying up the space shuttle. > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org -- ** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 ** ** Delftechpark 11 2628 XJ Delft, The Netherlands. KVK: 27239233 ** f equals m times a. When your f is steady, and your m is going down your a is going up. -- Chris Hadfield about flying up the space shuttle.