Gas station without pumps

2019 July 14

Shakespeare cookie cutter

Filed under: Uncategorized — gasstationwithoutpumps @ 14:49
Tags: , , , , , ,

I have been trying to create a cookie cutter and stamp of Shakespeare’s head on my 3D printer.  I started by hand tracing one of the engravings of Shakespeare’s head using inkscape, to get a simplified line drawing:

The tracing looked good to me, but there may still be too much detail for a cookie cutter.

I decomposed the drawing into two parts: the outline and the internal lines (as shown by the colors).  I then used OpenSCAD to create three designs: a stamp for the embossing the lines, a cutter shell to cut the outside edge, and a knob for putting on the other end of a shaft for the stamp.  I had to install a new version of OpenSCAD, because the old one I had could not import splines.  The new one does, but gives no way to control the number of polygons created, so I often had 10-minute waits as it tried to generate the geometry.

My first attempt (to make a 5cm cookie) was a miserable failure, because the holes for the shaft closed up, being almost 1mm smaller in diameter than specified. Also the thin lines for the stamp ended up being too thin and too close together (particularly for the mouth), so the printer ended up blobbing them together.  The design might have worked with a higher-quality printer, but the almost any filament printer is going to have trouble with 0.5mm wide ridges that are 2mm tall.

My second attempt widened the lines and separated them a little, increased the cookie size to 6cm, and added some compensation for the spreading that was closing the holes.  Here are the parts:

From left to right, we have the stamp, the cutter, and the knob. The knob has been fitted with a 5cm ⅛” stainless-steel rod and a 4cm spring.

The parts looked much better this time, and the shaft fits comfortably in the holes in the knob and the stamp, though I will need to find a good glue for attaching the PLA and the 316L stainless steel.  I don’t think I want to use a 2-part epoxy (I have trouble mixing small quantities), but standard superglue may be too brittle—I’ll probably try it anyway, if I have any that has not solidified in the container.

Both the stainless-steel rod and the spring are leftovers from previous projects: Two-electrode vs. four-electrode impedance spectroscopy and Physics Lab 4: spring constants results.

I did one trick in Cura to save some printing time.  Rather than doing 100% infill for the whole stamp and knob, I used only 20% infill, but requested a thick top layer for the stamp and bottom layer for the knob—thick enough to be solid down to the end of the shaft.  I also requested thick side walls, so that the sides of the hole were solid. The reduced infill doesn’t save much on the stamp, where the hole for the shaft is rather shallow, but it made the knob substantially lighter and somewhat faster to print.

There were still some problems with stringing and blobbing around the eyes and mouth:

The eyes and the mouth still have serious problems with stringing and blobbing.

I tried trimming off the excess plastic in the details and found that the top few layers of the stamp delaminated too easily.  Things look a bit better after the cleanup, but the stamp no longer has uniform height ridges, with a variation from 1.5mm to 2.5mm high.

After cleanup, the stamp looks better, but the details still seem to be too small for cookies, and the printing is too messy.

I’m not sure what my next step is on the design is.

  • I could make a larger print (up to about 10cm), which might make an Instagrammable cookie, but would be a bit large for a really useful cookie cutter.  Even then I’ll probably have problems with stringing and blobbing on the fine details.
  • I could try to simplify the eyes and mouth further, to reduce the need for fine details.  I’m not much of an artist, so I don’t know how successful I can be at that, but I think it will be essential for a usable stamp.

I’m feeling now that I should have been less ambitious for my first cookie-stamp design (maybe even doing a simple cutter, rather than cutter and stamp).

2019 July 7

3D slug heart

Filed under: Uncategorized — gasstationwithoutpumps @ 18:34
Tags: , , , , , ,

Earlier today I posted about adding a ring to scanlime‘s banana-slug design on Thingiverse by merging two STL files in Cura.  Today, I tried using the “include” command of OpenSCAD to get a properly merged STL file that I can post to Thingiverse.

The OpenSCAD code is quite simple:

module torus(big_radius=3, small_radius=1, big_fn=100, small_fn=30)
{   rotate_extrude($fn=big_fn)
    translate([big_radius,0,0])
    circle(r=small_radius, $fn=small_fn);
}

union()
{
    import("slug-fixup.stl",convexity=5);
    translate([-15,27,0])
        intersection()
        {   translate([0,0,1]) torus(big_radius=3.6, small_radius=2);
            translate([0,0,50]) cube(size=[100,100,100], center=true);
        }
}

I decided to go one step further and make a “slug heart” as suggested by my wife—it would be good for IEEE to sell at Valentine’s Day next year:

module torus(big_radius=3, small_radius=1, big_fn=100, small_fn=30)
{   rotate_extrude($fn=big_fn)
    translate([big_radius,0,0])
    circle(r=small_radius, $fn=small_fn);
}

module slug()
{    translate([-18,0,0]) rotate(a=[0,0,-12]) import("slug-fixup.stl",convexity=5);
}
union()
{
    slug();
    mirror([1,0,0]) slug();
    translate([0,25,0])
        intersection()
        {   translate([0,0,1]) torus(big_radius=3.6, small_radius=2);
            translate([0,0,50]) cube(size=[100,100,100], center=true);
        }
}
slug heart jewelry

View of the heart showing the ring for hanging it. This was printed at “draft” resolution (0.2mm/layer)—the jewelry will look better with 0.1mm/layer

slug heart jewelry

View of the heart showing the interior heart shape. I still only have green filament, but the slug will look much better in gold.

The slug-heart pendant weighs 13.46 grams in draft mode—I suspect it will be a similar weight for the final printing when I get the gold filament.

UPDATE 2019 July 7: I released the design as https://www.thingiverse.com/thing:3735198

3D slug printing

Filed under: Uncategorized — gasstationwithoutpumps @ 14:39
Tags: , , , , , , ,

I used my Monoprice Delta Mini 3D printer again yesterday, after a long break since the last usage.  My wife wanted a banana-slug charm to hang on her new mustard-yellow purse—she liked the color and size of the 3D-printed slug I had bought her from the UCSC IEEE chapter, but it did not have any easy way to attach it to the purse.

I found the design on Thingiverse by  scanlime, and checked the licensing (CC by 3.0), which only requires attribution, even for commercial uses.

I wanted to add a ring to the slug, so that it could be attached to a keyring.  Unfortunately, the design is only available as an STL file, and I’ve been using OpenSCAD, and I forgot that OpenSCAD has an import option for importing STL files, so I did a crude hack instead:  I made a ring in OpenSCAD, exported it as STL, then placed it in Cura overlapping the slug STL file.  When I sliced the models, the two files were merged producing a single gcode file, that printed as a single object. I think I want to see if I can also use the “include” command and get a properly merged STL file that I can post to Thingiverse.

I printed the model with 0.1mm resolution (finer than the resolution used for the IEEE printing, but I was not trying to produce slugs in sufficient quantity to sell them, so a slower printing to get a smoother surface was fine for me).

The gold slug is the one I bought from the IEEE student chapter, and the green one is the one I printed with the added ring.

The green color is obviously not suitable for banana slugs, but I’ve ordered some gold filament to print the slug properly.

One interesting side effect of slicing two overlapping models is that the exterior wall of each model was preserved, so that there were interior lines in the finished slicing corresponding to the original exterior walls.  This is an interesting, if somewhat awkward, way to get Cura to create specific interior structure, in addition to the generic interior fill patterns that it uses.

I have ordered two different gold filaments: Hatchbox Gold, which is what the IEEE slug was printed with, and CC3D Silk Gold, which should be shinier.  I’ve also ordered some hardware for attaching the slug to the purse (split rings and lobster hook).  I’ll have enough filament to do hundreds of slugs, since it only weighs 6.51g (not that I plan to make more than a handful—one in each color for my wife, and maybe another one for my backpack). The extra shiny gold filament can be used to make costume jewelry for WEST Performing Arts perhaps.  The filament costs a little over 1¢/gram, so the only real cost is the design and printing time.

Incidentally, the photographs were taken using another recent acquisition: a large Shibusa Photo Studio in a Bag, which I got from American Science and Surplus.  I think that the reason they were marked down is that the sides are so warped that they unsnap under the weight of the top.  I managed to make the thing work by using binder clips to insert some MDF pieces to stiffen the sides.  I think that I want to cut a couple of permanent MDF pieces that are exactly the right size and shape to support the top cleanly.  It would probably be best to use a laser cutter, but I’ll probably just use my scroll saw.

UPDATE 2019 July 7: I released the model as https://www.thingiverse.com/thing:3735186

2018 August 14

3D-printed small snifter

Filed under: Uncategorized — gasstationwithoutpumps @ 11:51
Tags: , , , , , , ,

To practice using a different feature of OpenSCAD, I tried making a wine glass by rotating a 2D outline around the Z-axis.  OpenSCAD has much more limited 2D capabilities than SVG, allowing only polygons, not smooth curves, so it took me a while to come up with a way to get a decent shape with just a few vertices.

The tiny wine glass looks ok, but the single-layer walls of the bowl leak, and the stem is too springy.

My first design was based on a tall, thin wine glass, but the glass was too tall for the print volume of the Monoprice Delta Mini printer, so I tried printing it scaled down by a factor of 2. The printer had a lot of trouble with this tiny design. Perhaps the biggest problem is that the thin stem is too flexible, so the printer head dragged the bowl around as it was printing. The stick-slip action resulted in a few small holes in the single-layer bowl.

I then tried adjusting the design so that the default settings would still produce the wine glass, but different settings would match a mini-snifter that does fit in the print volume. This mini-snifter has a bowl volume of about 135ml (4.5oz), and the snifter weighs 33g. I printed it at 0.15 mm/layer, with a wall count of 5 in Cura, 6 top and bottom layers, and 10% infill.

The roughness of the surface is probably due to inconsistent feeding of filament, except where the bowl flares out widely. There the filament is drooping a bit due to insufficient support.

The mini-snifter holds water and is a reasonably close approximation to the glass that I was copying.

Side view of the snifter, showing the “seam” that results from Cura starting each layer by moving to the same starting position on the circle.

Bottom view of the snifter, showing the flat surface created by the glass bed added to my printer.

Inside view of the bowl of the snifter.

Snifter on its side, to show the roughness of the printing where the bowl widens unsupported. The vertices of the polygon that is rotated are also clearly visible here as three lines around the bowl.

I’ve included the OpenSCAD source code below, but it can be more easily downloaded from
https://www.thingiverse.com/thing:3049512

// OpenSCAD module for making goblets
// Kevin Karplus
// 2018 Aug 14
// Creative Commons - Attribution - Non-Commercial - Share Alike license.</pre>

function interp(x, y0, y1) = (1-x)*y0 + x*y1;

// Goblet using rotation about Z-axis
// Defaults are for a tall, narrow wine glass: too tall for the
// Monoprice Delta Mini 3D printer
// h is height
// foot_r is radius of foot
// foot_h is height of foot where it joins stem
// stem_r is radius of stem
// stem_h is height of stem where it joins bowl
// bowl_bottom_r is radius of bowl at stem_h
// bowl_mid_r is radius of bowl at h-bowl_mid_depth
// bowl_top_r is radius of bowl at top
// thickness is thickness of sides of bowl.
module goblet(h= 214, foot_r=36, foot_h=12, stem_r=4, stem_h=110,
bowl_bottom_r=12, bowl_mid_r=28, bowl_mid_depth=42,
bowl_top_r=25, thickness=1.5)
{
bowl_depth=h-stem_h;
sphere_width = interp(0.75, bowl_mid_r,bowl_bottom_r) -thickness;
echo( "sphere_width=", sphere_width);

delta_r =interp(0.5,bowl_mid_r,bowl_bottom_r)-bowl_bottom_r;
delta_d =bowl_depth-interp(0.7,bowl_mid_depth,bowl_depth);
echo("delta_d=", delta_d, "delta_r=",delta_r);
alpha = atan( delta_d/delta_r);
echo ("alpha=", alpha);
sphere_radius= sphere_width/sin(alpha);
sphere_height = stem_h+sphere_radius;
echo( "sphere_radius=", sphere_radius);

difference()
{
rotate_extrude($fa=2)
{ polygon(
points=[
// foot
[0,0], [foot_r,0], [foot_r,thickness],
[foot_r-4, thickness],
[stem_r*1.5, foot_h- 0.5*stem_r],

// stem
[stem_r,foot_h],
[stem_r, stem_h*0.75],
[interp(0.5,stem_r,bowl_bottom_r), 0.9*stem_h],

//bowl
[bowl_bottom_r,stem_h],
[interp(0.5,bowl_mid_r,bowl_bottom_r),
h-interp(0.7,bowl_mid_depth,bowl_depth)],
[interp(0.2,bowl_mid_r,bowl_bottom_r),
h-interp(0.5,bowl_mid_depth,bowl_depth)],
[bowl_mid_r,
h-interp(0.2,bowl_mid_depth,bowl_depth)],
[bowl_mid_r,
h-interp(-0.07,bowl_mid_depth,bowl_depth)],
[bowl_top_r, h],
[bowl_top_r-thickness, h],
[bowl_mid_r-thickness,
h-interp(-0.07,bowl_mid_depth,bowl_depth)],
[bowl_mid_r-thickness,
h-interp(0.2,bowl_mid_depth,bowl_depth)],
[interp(0.2,bowl_mid_r,bowl_bottom_r) -thickness,
h-interp(0.5,bowl_mid_depth,bowl_depth)],
[interp(0.5,bowl_mid_r,bowl_bottom_r)-thickness,
h-interp(0.7,bowl_mid_depth,bowl_depth)],
[interp(0.75,bowl_mid_r,bowl_bottom_r)-thickness,
h- interp(0.85,bowl_mid_depth,bowl_depth)],
[0,stem_h]
]);
};
translate([0,0,sphere_height])
color("red")
intersection()
{ sphere(r=sphere_radius, $fs=0.1);
translate([0,0,-2*sphere_radius+delta_d])
cube([10*sphere_radius, 10*sphere_radius, 2*sphere_radius],
center=true);
}
}

}

// The default example is for a small snifter, with an interior volume of about 135ml.
// Printed in PLA with 0.15mm layers, wall line count 5, top and bottom layer count 6, and 10% infill, it weighs 33g.
goblet(h=95, foot_r=29, foot_h=10, stem_r=4.5, stem_h=30,
bowl_bottom_r=18, bowl_mid_r=33, bowl_mid_depth=40,
bowl_top_r=23, thickness=1.8);
<pre>

2018 August 3

Tool for sweeping roof valleys

Filed under: Uncategorized — gasstationwithoutpumps @ 21:42
Tags: , , , , , ,

As I mentioned in Fixing Monoprice Delta Mini end stops,

I’ve also been working on creating broomstick threading on the printer, both to test the ability of the printer to do screw threads and to make a socket and bracket for attaching a broom head to a telescoping pole for cleaning the valleys of my tile roof.  I’ll post on that in a separate post, with pictures, once I get the whole thing working.

I designed the threads using OpenSCAD, which has no built-in support for creating helical structures like threaded rods and sockets. I found an open-source thread module on the web, but I found its parameterization awkward, so I ended up writing my own.

Here are my practice pieces for designing threaded rods and sockets with OpenSCAD, and printing them on the Monoprice Delta Mini.

All the test pieces were printed with the threads spiraling around the vertical Z-axis, to minimize the amount of unsupported filament. The undersides of the threads are a bit rough, but the roughness can be minimized by making the threads have a nearly triangular profile, so that only a little bit of filament is unsupported in each layer.

The first threaded rod, at the top left, screws easily into a broom head, and has fairly smooth surfaces, but was a bit too loose (diameters a little too small) and only a rather thin part of the thread was taking most of the contact force. The second one was sturdier, but still too loose.  The third one was too fat and would not screw into a broom head, but the fourth one was a good fit, screwing in easily, but not being wobbly.

The first two sockets worked with the first two printed screws, but not with the steel threads on my broom sticks—there was not enough clearance.  The third one fit fairly well and had smooth threads, but the threads were rather thin, and I felt they would not be sturdy enough. The two sockets with plates were beefier, and were experiments in seeing whether I could print horizontal screw holes.  I printed holes for #8 and #9 flat-head screws (countersunk), and the bridging did not cause problems with loose filaments.

I did have a little problem with the flat plates not printing properly, which I tracked down to the glass plate on the bed rotating a little in the clips (pretty much as Michael Johnson had warned me).  I fixed the problem by adding some dabs of hot-melt glue to hold the clips to the plate.  I have renew the hot-melt glue every few prints, since it does not bond the glass and the PLA permanently, but I find that an acceptable tradeoff for the ease of removing prints from glass rather than the bed that the printer comes with.

Here is the final socket attached to the broom head with 1″ #8 wood screws.

Of course, one socket at the end of the broom head would not be very secure—the length of the broom head makes a pretty big lever arm for twisting, and PLA is not that strong a plastic. So I designed a support for the broomstick at the other end of the broom head.  I could, perhaps, have used a commercial conduit strap, but the screw holes in them are a bit far apart for screwing to the broom head, so I made one that fits the broom handle I’m using precisely.

Here are the practice pieces I made, to make sure that the broom handle would fit and to check that I could make long screw holes. Note the notch on the right-hand example.

The first test piece held the broomstick well, but did not allow the broomstick to be inserted and withdrawn easily—there are a pair of screws on the brookstick that hold on the threaded end, and the screwheads stick out a little. The notch in the second test piece was carefully designed to just allow the screwheads through, but I added 1mm more clearance for the final piece.  The test pieces were printed with thin shells and 10% or 20% infill, and so were very light, but I printed the final pieces with thick shells and high infill (50%?), so that they ended up fairly solid.

The screw head on one side fits through the notch, and on the other side is in the diagonal space left by extending the circular hole to form a U. The block is held in place with 2″ #9 deck screws.

Although the deck screws were supposed to drill their own holes in the wood, I found that I had to drill pilot holes for them—the first one I inserted split the wooden broom head, which I had to glue back together. I also made a mistake in printing the U-shaped piece with the screw holes horizontal, as torquing down the last screw started to split the plastic along the laminations. If I were to reprint it, I would print it “legs-up” so that the deck screws compress the laminations together.

Here is the finished roof-valley sweeper, mounted on the telescoping pole.

The broom head is still usable as an ordinary broom, as the extra hardware does not interfere with inserting a broomstick in the normal way.

I used the roof-valley sweeper today to clean one of the roof valleys on my tile roof (the one reachable from the porch roof). It worked well to remove a year’s accumulation of leaves and twigs, though I’ll probably have to use it again this fall, after the trees have shed their leaves. I still have the other roof valleys to clean, which needs to be done with the telescoping pole from a ladder.

I don’t expect the PLA pieces to last forever (this is not UV-resistant material), but I store the broom head in a dark garage, so I expect to get a few year’s use out of them.

I’ve included the OpenSCAD source code below, but it can be more easily downloaded from
https://www.thingiverse.com/thing:3033594

The threaded_rod module:

// All dimensions in mm

// build a polygon for the cross-section of the thread 
// perpendicular to the thread.  
// The outer edge of the thread is on x=0 and all coordinate <=0
module thread_cross_section(height, pitch, base_fraction, top_fraction, pitch_angle)
{
    scale = cos(pitch_angle);
    scaled_top  = top_fraction*pitch*scale;
    scaled_base = base_fraction*pitch*scale;
    polygon(points= [ [-height,0], 
        [0, -(scaled_base-scaled_top)/2],
        [0, -(scaled_base+scaled_top)/2],
        [-height,-scaled_base]]);    
}

// one segment of the thread for the threaded rod, but oriented along the z-axis
module thread_segment(height, pitch, base_fraction, top_fraction, pitch_angle, segments_per_turn)
{
    length = pitch/(sin(pitch_angle) * segments_per_turn);
    // echo("pitch=",pitch, "pitch_angle=",pitch_angle, segments_per_turn,"segments, length=",length);
    linear_extrude(height=length, slices=1)
    {   thread_cross_section(height=height, pitch=pitch,
            top_fraction=top_fraction,
            base_fraction=base_fraction,
            pitch_angle=pitch_angle);
    }
}


// make a long cone for intersecting with screw to trim z=0 end
module chamfer_cone(inner_diam, outer_diam, chamfer_length, total_length)
{
    cylinder(d1=inner_diam, 
             d2=inner_diam+ (outer_diam-inner_diam)*total_length/chamfer_length,
            h=total_length, $fn=60);
}

// Build a threaded rod with trapezoidal threading
//       ____________                  _____________
//  ____/            \_______________/
// Threads start at z=0 on the x axis.
module threads(
        //Screw thread dimensions:
        //Length of Screw
        screw_length = 25.0,

        // Diameter at base of threads
        inner_diam = 13.5,
        // diameter at top of threads
        outer_diam = 18,

        //Thread Pitch
        pitch = 5.0,
        // Thread fraction (thickness of thread at base/pitch)
        base_fraction=1,
        // Thread fraction (thickness of thread at top/pitch)
        top_fraction=0,

        // how much of turn is made per segment of result
        degrees_per_segment=6,

        // chamfer at start (Z=0)  (defaults to pitch/2, use 0 to turn off)
        chamfer_start=-1,
        // chamfer at end (Z=screw_length)
        chamfer_end=0
        )
{
    pi= 3.1415926535897932346;
    pitch_angle = atan(pitch/ (pi *outer_diam));
    
    augmented_length = screw_length+pitch;
    turns = augmented_length/pitch;
    segments_per_turn = 360/ degrees_per_segment;
    segments = ceil(turns*segments_per_turn);
    
    // set the lengths for the chamfers if defaults needed
    local_chamfer_start = chamfer_start<0? pitch/2: chamfer_start;
    local_chamfer_end = chamfer_end<0? 0: chamfer_end; intersection() { if (local_chamfer_start>0)  
        {   chamfer_cone(inner_diam=inner_diam, 
                outer_diam=outer_diam, 
                chamfer_length=local_chamfer_start,
                total_length=augmented_length);
        }
        else
        {    cylinder(d=2*outer_diam, h=augmented_length);
        }
        translate([0,0,screw_length])   
            rotate([180,0,0]) 
                if (local_chamfer_end>0) 
                {     chamfer_cone(inner_diam=inner_diam, 
                    outer_diam=outer_diam, 
                    chamfer_length=local_chamfer_end,
                    total_length=augmented_length);
                }
                else
                {   cylinder(d=2*outer_diam, h=augmented_length); 
                }
        union()
        {
            color("red") cylinder(d=inner_diam+0.001, h=screw_length, $fn=segments_per_turn);
            for (i = [0:segments])
            {   angle = i*degrees_per_segment;
                translate([outer_diam*cos(angle)/2,
                          outer_diam*sin(angle)/2,
                          i*pitch*degrees_per_segment/360])
                    rotate([0,0,angle])
                        rotate([90-pitch_angle,0,0])
                thread_segment(height=(outer_diam-inner_diam)/2, 
                    pitch=pitch, 
                    base_fraction=base_fraction,
                    top_fraction=top_fraction, 
                    pitch_angle=pitch_angle, 
                    segments_per_turn=segments_per_turn);
            } 
        }
    }
}

// example
// rotate([-180,0,0]) union()
// {
//    color("green") translate([0,0,25-0.001])
//            cylinder(d=23, h=5,$fn=60);
//    threads(top_fraction=0.3, base_fraction=0.6, 
//        screw_length=25,
//        inner_diam=15, outer_diam=18);
// }

The broomstick socket:

use <threaded_rod.scad>

// create a screwhole for metric screw of given length,
// with head extending in -z direction and screw in +z direction
// Loose=0.10 for loose fit, 0.05 for tight fit, about -0.15 for threaded hole
module screw_hole(metric_size=3, length=10, loose=0.10)
{   union()
    {   cylinder(d=metric_size*(1+loose), h=length*1.1, $fs=0.3);  // body of screw
    translate([0,0,-metric_size]) cylinder(d=metric_size*2.2, h=metric_size*1.1, $fs=0.3);  // counterbore for head of screw
    }
}

// make countersunk hole for flathead screw
// surface on xy plane at (0,0), screw extends in +z direction.
// length is the length of the hole for the threads (past the base of the head)
// diam is the diameter of the hole for the screw threads
// depth is the depth of the countersink
// top_diam is the diameter at the surface (the xy plane)
module countersunk(length=35, diam=5, depth=3, top_diam=11)
{
    union()
    {    cylinder (d=diam, h=length+depth, $fs=0.3);   // hole for screw
        // countersink (adding 0.001 overshoot to avoid coincident faces)
        translate([0,0,-0.001]) cylinder (d1=top_diam+0.2, d2=diam, h=depth+0.1, $fs=0.3); 
    }
}

// make countersunk hole for 10-24 flathead machine screw
module countersunk_10_24(length=35)
{    countersunk(length=length, diam=5, depth=3, top_diam=11);

} 

// make countersunk hole for 8-32 flathead wood screw 
module countersunk_8_32(length=22, diam=4.3, top_diam=7.6, depth=3.2)
{
    countersunk(length=length, diam=3.2, top_diam=7.6, depth=3.2);
}


// example using broom handle thread
module broom_handle()
 {
    rotate([-180,0,0]) union()
    {
        color("green") translate([0,0,15-0.001]) cylinder(d=23, h=5,$fn=60);
        threads(top_fraction=0.35, base_fraction=0.7, 
            screw_length=15,
            inner_diam=15.5, outer_diam=18.5);
    }
}
// makes a threaded rod that matches the one in broom_handle,
// but bloats diameters and threads.
// By subtracting this from an object, we should be able to
// create an acceptable socket for the broom handle.
module bloated_broom_thread(bloat=0.5, depth=20,
	inner_diam=15.5,
	outer_diam=18.5,
	pitch=5,
	top_fraction=0.35,
	base_fraction=0.7)
{
    threads(top_fraction=min(0.95,top_fraction+0.5*bloat/pitch), 
        base_fraction=min(1,base_fraction+0.5*bloat/pitch), 
        screw_length=depth,
        inner_diam=inner_diam+bloat, outer_diam=outer_diam+bloat,
        pitch=pitch, chamfer_start=0);
}

// Make a cylinder with a plate whose outer edge is tangential to the cylinder
// cylinder has axis along z-axis.
// Plate is parallel to xz-plane on positive y side.
// The cylindrical boss has a fillet that goes from the diameter
//   an extra "fillet" mm wider on each side where it touches the plate.
module plate_with_boss(width=55, length=55, boss_diam=30, thickness=5, fillet=2.5)
{
   boss_radius = boss_diam/2;
   fillet_height=boss_radius-thickness;
   union()
   {  
      color("green")cylinder(d=boss_diam, h=length, $fn=90);
      color("red") translate([-width/2,boss_radius-thickness+0.001,0.001]) cube([width,thickness,length]);
      color("blue") translate([-boss_radius-0.001,0,-0.001]) cube([boss_diam+0.002, boss_radius-0.001, length]);
       linear_extrude(height=length)
       {    polygon(points=[
                [boss_radius-0.1, fillet_height+0.1],
                [boss_radius, fillet_height-fillet], 
                [boss_radius+0.25*fillet, fillet_height-0.5*fillet],
                [boss_radius+0.5*fillet, fillet_height-0.25*fillet],
                [boss_radius+fillet, fillet_height]
           ]);
       }
       linear_extrude(height=length)
       {    polygon(points=[
                [-boss_radius+0.1, fillet_height+0.1],
                [-boss_radius, fillet_height-fillet], 
                [-boss_radius-0.25*fillet, fillet_height-0.5*fillet],
                [-boss_radius-0.5*fillet, fillet_height-0.25*fillet],
                [-boss_radius-fillet, fillet_height]
           ]);
       }
   }  
}

boss_diam=28;
depth=30;   // length of threads in socket
width = 60; // width of plate
length = depth+4; // length of plate
thickness = 7;

screw_depth=max(0,thickness-3.5);  // leave thin plate closing hole

screw_x = boss_diam/2+7;
screw_y = boss_diam/2-thickness-0.001;
screw_z = 8;
screw_holes=true;
rotate([180,0,0])
    difference()
    {   plate_with_boss(boss_diam=boss_diam, length=length, width=width, thickness=thickness);
        translate([0,0,-0.01]) bloated_broom_thread(depth=depth);
        if (screw_holes)
        {    
            translate([screw_x, screw_y, screw_z])
                rotate([-90,0,0]) 
                    countersunk_8_32(length=screw_depth);
            translate([-screw_x, screw_y, screw_z])
                rotate([-90,0,0]) 
                    countersunk_8_32(length=screw_depth);
            translate([screw_x, screw_y, length-screw_z])
                rotate([-90,0,0]) 
                    countersunk_8_32(length=screw_depth);
            translate([-screw_x, screw_y, length-screw_z])
                rotate([-90,0,0]) 
                    countersunk_8_32(length=screw_depth);
        }
    }

The guide for the broomstick:

// create a screwhole for metric screw of given length,
// with head extending in -z direction and screw in +z direction
// Loose=0.10 for loose fit, 0.05 for tight fit, about -0.15 for threaded hole
module screw_hole(metric_size=3, length=10, loose=0.10)
{   union()
    {   cylinder(d=metric_size*(1+loose), h=length*1.1, $fs=0.3);  // body of screw
    translate([0,0,-metric_size]) cylinder(d=metric_size*2.2, h=metric_size*1.1, $fs=0.3);  // counterbore for head of screw
    }
}

// make countersunk hole for flathead screw
// surface on xy plane at (0,0), screw extends in +z direction.
// length is the length of the hole for the threads (past the base of the head)
// diam is the diameter of the hole for the screw threads
// depth is the depth of the countersink
// top_diam is the diameter at the surface (the xy plane)
module countersunk(length=35, diam=5, depth=3, top_diam=11)
{
    union()
    {    cylinder (d=diam, h=length+depth, $fs=0.3);   // hole for screw
        // countersink (adding 0.001 overshoot to avoid coincident faces)
        translate([0,0,-0.001]) cylinder (d1=top_diam+0.2, d2=diam, h=depth+0.1, $fs=0.3); 
    }
}

// make countersunk hole for 10-24 flathead machine screw
module countersunk_10_24(length, diam=5, depth=3, top_diam=11)
{     countersunk(length=length, diam=diam, top_diam=top_diam, depth=depth);
} 

// make countersunk hole for #9 flathead wood screw
module countersunk_9(length, diam=4.4, top_diam=8.3, depth=4)
{     countersunk(length=length, diam=diam, top_diam=top_diam, depth=depth);
} 

// make countersunk hole for 8-32 flathead wood screw 
module countersunk_8_32(length=22, diam=4.3, top_diam=7.6, depth=3.2)
{
    countersunk(length=length, diam=diam, top_diam=top_diam, depth=depth);
}

module rounded_posy_cube(x,y,z,radius=1)
{
    difference()
    {    cube([x,y,z]);
         translate([0,y,0]) 
            cube([2*radius,2*radius, 2*z+1], center=true);
         translate([x,y,0]) 
            cube([2*radius,2*radius, 2*z+1], center=true);
    }
    translate([radius, y-radius, 0]) cylinder(r=radius, h=z, $fs=0.1);
    translate([x-radius, y-radius, 0]) cylinder(r=radius, h=z, $fs=0.1);
}

U_diam=26;
inner_depth=28;
thickness=6;

U_radius = U_diam/2;
center_y = inner_depth-U_radius;
outer_height = inner_depth+thickness;

width = 60;
length = 34; // length of plate
thickness = 6;

screw_length=outer_height+2; 

// screw_x = max(U_radius+thickness+2.2, width/2-thickness-2.2);
screw_x=21;   // (moved in slightly to engage wood better)
screw_y = outer_height+0.001;
screw_z = 8;
screw_holes=true;

notch_angle = atan(center_y/U_radius);
notch_depth = 2;
notch_radius= 5;

notch_offset = U_radius+notch_depth-notch_radius;
notch_x = cos(notch_angle)*notch_offset;
notch_y = center_y + sin(notch_angle)*notch_offset;

test=false;   // set to trim the model in Z for fast printing of
    // a size test

rotate([-90,0,0])   // to make this "legs up" when printing
difference()
{   translate([-width/2,0,0]) 
        rounded_posy_cube(width,outer_height, length, radius=3);
    
    // hole for handle
    translate([0,center_y,-0.01])
        cylinder(d=U_diam, h=length+0.02, $fn=100);
    
    //extend hole to base 
    translate([-U_radius,-0.01,-0.02])
        cube([U_diam,center_y+0.02, length+0.04]);
  
    // cut notch to allow screw head through
    translate([notch_x, notch_y, -1])
        cylinder(r=notch_radius, h=length+2, $fs=0.1);
    // cut notch to allow screw head through
    translate([-notch_x, 2*center_y-notch_y, -1])
        cylinder(r=notch_radius, h=length+2, $fs=0.1);

    if (screw_holes)
    {    
        translate([screw_x, screw_y, screw_z])
            rotate([90,0,0]) 
                countersunk_9(length=screw_length);
        translate([-screw_x, screw_y, screw_z])
            rotate([90,0,0]) 
                countersunk_9(length=screw_length);
        translate([screw_x, screw_y, length-screw_z])
            rotate([90,0,0]) 
                countersunk_9(length=screw_length);
        translate([-screw_x, screw_y, length-screw_z])
            rotate([90,0,0]) 
                countersunk_9(length=screw_length);
    }
    
    if (test)
    {   // just include up through the lower screw hole
        translate([-width,-1, screw_z+6])
            cube([2*width, 2*outer_height, length]);
    }
}
Next Page »

%d bloggers like this: