Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.
Tag: Thing-O-Matic
Using and tweaking a Makerbot Thing-O-Matic 3D printer
Scaling the cubes to about 15 mm on a side puts a 6×6 array neatly on the build plate. Takes nigh onto four hours to print all 36 of them at 30 mm/s print and 100 mm/s move… a bit over 6 minutes each.
The print quality is Good Enough. The bottom surface of the front cubes faces forward and reflects the scale markings:
When confronted with a zombie horde, though, nothing exceeds like excess:
Finned CO2 Cartridge Array
In real life, they’re 12 gram CO2 capsules, of the type used in tire inflators and air pistols. I knew I’d find something to do with the box of empties I’d been accumulating: they became (somewhat threatening) tchotchkes. This was inspired by that thing, although that STL file doesn’t render into anything and, as with many interesting Thingiverse things, there’s no source code.
These fins were an exercise in thin-wall printing: the outer square is one thread thick, the diagonal struts are two threads, and the ring around the nozzle has just a touch of fill inside, with a one-thread-thick base below the cartridge nozzle:
Fin Array on build platform
The solid model looks about like you’d expect:
Fin Assembly- solid model
The teeny little quarter-cylinders in the corners encourage Skeinforge to do the right thing: build each quadrant in one pass, leaving the corners unfinished. The diagonals must be exactly two threads wide to make that possible: each strut thread connects to the corresponding single-thread outer edge.
It turns out that my box has several different types of CO2 cartridges and the nozzle ends are all different. To get it right, there’s a template for matching the curves:
Cartridge nozzle template
That end of the cartridge consists of a cylinder for the body, a sphere mated to a tangential conic section, another conic fillet, and then the cylindrical nozzle. Basically, you twiddle with the parameters until the template comes pretty close to fitting, then fire off a few trial fins until it comes out right.
CO2 Capsule Nozzle – solid model detail
They were a big hit at the Long Island Linux Users Group meeting…
The OpenSCAD source code:
// CO2 capsule tail fins
// Ed Nisley KE4ZNU - Oct 2011
Layout = "Show"; // Show Build FinBlock Cartridge Fit
include
//-------
//- Extrusion parameters must match reality!
// Print with +0 shells and 3 solid layers
ThreadThick = 0.33;
ThreadWidth = 2.0 * ThreadThick;
HoleWindage = 0.2;
Protrusion = 0.1; // make holes end cleanly
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
//-------
// Capsule dimensions
BodyDia = 18.70;
BodyRad = BodyDia/2;
BodyLength = 53.0; // between hemispherical endcap centers
BodyBaseLength = 21; // tip to endcap center
TipDia = 7.40;
TipRad = TipDia/2;
TipLength = IntegerMultiple(4.0,ThreadThick);
FilletLength = 5.0; // fillet between tip and cone
FilletTop = TipLength + FilletLength;
FilletBaseDia = 8.60;
FilletBaseRad= FilletBaseDia/2;
FilletTopDia = 9.5;
FilletTopRad = FilletTopDia/2;
ConeTop = 16.0; // tip to tangent with endcap
ConeLength = ConeTop - FilletTop;
echo(str("Cone Length: ",ConeLength));
IntersectZ = ConeTop; // coordinates of intersect tangent
IntersectX = sqrt(pow(BodyRad,2) - pow(BodyBaseLength - ConeTop,2));
echo(str("IntersectZ: ",IntersectZ));
echo(str("IntersectX: ",IntersectX," dia: ",2*IntersectX));
//-------
// Fin dimensions
FinThick = 1*ThreadWidth; // outer square
StrutThick = 2*FinThick; // diagonal struts
FinSquare = 24.0;
FinTaperLength = sqrt(2)*FinSquare/2 - sqrt(2)*FinThick - ThreadWidth;
FinBaseLength = 2*TipLength;
//-------
module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes
Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
FixDia = Dia / cos(180/Sides);
cylinder(r=(FixDia + HoleWindage)/2,h=Height,$fn=Sides);
}
module ShowPegGrid(Space = 10.0,Size = 1.0) {
Range = floor(50 / Space);
for (x=[-Range:Range])
for (y=[-Range:Range])
translate([x*Space,y*Space,Size/2])
%cube(Size,center=true);
}
//-------
// CO2 cartridge outline
module Cartridge() {
$fn = 48;
union() {
translate([0,0,BodyBaseLength]) {
cylinder(r=BodyDia/2,h=BodyLength);
translate([0,0,BodyLength])
sphere(r=BodyRad);
}
intersection() {
translate([0,0,BodyBaseLength])
sphere(r=BodyRad);
union() {
translate([0,0,(TipLength + FilletLength+ConeLength)])
cylinder(r=BodyRad,h=(BodyBaseLength - ConeLength));
translate([0,0,(TipLength + FilletLength)])
cylinder(r1=FilletTopRad,r2=IntersectX,h=(ConeLength + Protrusion));
translate([0,0,TipLength])
cylinder(r1=FilletBaseRad,r2=FilletTopRad,h=(FilletLength + Protrusion));
}
}
translate([0,0,FilletTop])
cylinder(r1=FilletTopRad,r2=IntersectX,h=ConeLength);
translate([0,0,TipLength])
cylinder(r1=FilletBaseRad,r2=FilletTopRad,h=(FilletLength + Protrusion));
translate([0,0,-Protrusion])
PolyCyl(TipDia,(TipLength + 2*Protrusion));
}
}
//-------
// Diagonal fin strut
module FinStrut() {
rotate([90,0,45])
translate([0,0,-StrutThick/2])
linear_extrude(height=StrutThick)
polygon(points=[
[0,0],
[FinTaperLength,0],
[FinTaperLength,FinBaseLength],
[0,(FinBaseLength + FinTaperLength)]
]);
}
//-------
// Fin outline
module FinBlock() {
union() {
translate([0,0,FinBaseLength/2])
difference() {
cube([FinSquare,FinSquare,FinBaseLength],center=true);
difference() {
cube([(FinSquare - 2*FinThick),
(FinSquare - 2*FinThick),
(FinBaseLength + 2*Protrusion)],center=true);
for (Index = [0:3])
rotate(Index*90)
translate([(FinSquare/2 - FinThick),(FinSquare/2 - FinThick),0])
cylinder(r=StrutThick,h=(FinBaseLength + 2*Protrusion),center=true,$fn=16);
}
}
for (Index = [0:3])
rotate(Index*90)
FinStrut();
cylinder(r=IntegerMultiple((FilletBaseRad + StrutThick),ThreadWidth),h=TipLength);
}
}
//-------
// Fins
module FinAssembly() {
difference() {
FinBlock();
translate([0,0,ThreadThick]) // add one layer to close base cylinder
Cartridge();
}
}
module FinFit() {
translate([0,0.75*BodyBaseLength,2*ThreadThick])
rotate([90,0,0])
difference() {
translate([-FinSquare/2,-2*ThreadThick,0])
cube([IntegerMultiple(FinSquare,ThreadWidth),
4*ThreadThick,
1.5*BodyBaseLength]);
translate([0,0,5*ThreadWidth])
Cartridge();
}
}
//-------
// Build it!
ShowPegGrid();
if (Layout == "FinBlock")
FinBlock();
if (Layout == "Cartridge")
Cartridge();
if (Layout == "Show") {
FinAssembly();
color(LG) Cartridge();
}
if (Layout == "Fit")
FinFit();
if (Layout == "Build")
FinAssembly();
My buddy Mark One asked me to make a golf-ball sized Thing that’s the intersection of three mutually orthogonal cylinders. He claims I (subtractively) machined one from solid plastic, many many years ago, but I cannot imagine I ever had that level of machine shop fu; right now, I’m not sure how I’d fixture the thing.
Cylinder Thing – solid model
It’s much easier with a 3D printer…
Of course, spheroids aren’t printable without support, but you can chop one in half to reveal the nice, flat interior surfaces, then add holes for alignment pegs. Using 0.50 infill makes for a compact mesh inside the ball:
Cylinder Thing – building
Smooth a few imperfections from the mating surfaces and add four pegs (the other two are busy propping the right-hand half off the countertop). Somewhat to my surprise, the alignment holes came out a perfect push fit for the 2.9 mm actual-OD filament with my more-or-less standard 0.2 mm HoleWindageFinagle Constant. This also uses the 1.005 XY scale factor to adjust for ABS shrinkage, not that that matters in this case:
Cylinder Thing – alignment pegs
Then solvent-bond everything together forever more:
Cylinder Thing – clamped
The seam is almost imperceptible around the equator, perhaps because I didn’t slobber solvent right up to the edge. I did print one without the alignment pegs and demonstrated that you (well, I) can’t glue a spheroid without fixturing the halves; that one goes in my Show-n-Tell heap.
The 0.33 mm Z resolution produces sucky North and South poles; the East, West, Left, and Right poles are just fine, as are the eight Tropical Vertices. After mulling for a bit, I rotated a cylindrical profile upward:
Cylinder Thing Rotated – solid model
The obvious contour lines fit the cylinder much better, although you can see where better Z resolution would pay off:
Cylinder Thing – rotated
This was at 0.33 mm x 0.66 mm, 200 °C, 30 & 100 mm/s, 2 rpm. No delamination problems; I applied a wood chisel to persuade those big flat surfaces to part company with the Kapton tape.
The OpenSCAD source code:
// Three intersecting cylinders
// Ed Nisley KE4ZNU - Oct 2011
Layout = "Build"; // Show Build
//- Extrusion parameters must match reality!
// Print with +1 shells and 3 solid layers
// Use infill solidity = 0.5 or more...
ThreadThick = 0.33;
ThreadWidth = 2.0 * ThreadThick;
HoleWindage = 0.2;
Protrusion = 0.1; // make holes end cleanly
//------ Model dimensions
CylDia = 2*IntegerMultiple(40.0/2,ThreadThick);
CylRad = CylDia/2;
echo(str("Actual diameter: ",CylDia));
Angle = [45,0,0]; // rotate to choose build orientation
$fn=128;
AlignPegDia = 2.90;
//-------
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes
Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
FixDia = Dia / cos(180/Sides);
cylinder(r=(FixDia + HoleWindage)/2,h=Height,$fn=Sides);
}
module ShowPegGrid(Space = 10.0,Size = 1.0) {
Range = floor(50 / Space);
for (x=[-Range:Range])
for (y=[-Range:Range])
translate([x*Space,y*Space,Size/2])
%cube(Size,center=true);
}
//------- Model bits & pieces
module OneCyl() {
cylinder(r=CylRad,h=CylDia,center=true);
}
module ThreeCyl() {
intersection() {
OneCyl();
rotate([90,0,0]) OneCyl();
rotate([0,90,0]) OneCyl();
}
}
module HemiThing() {
difference() {
rotate(Angle)
ThreeCyl();
translate([0,0,-CylRad])
cube(CylDia,center=true);
for (Index = [0:3])
rotate(Index*90)
translate([CylRad/2,0,-Protrusion])
PolyCyl(AlignPegDia,5+Protrusion);
}
}
//---------
ShowPegGrid();
if (Layout == "Show")
ThreeCyl();
if (Layout == "Build") {
translate([CylRad,CylRad,0])
HemiThing();
translate([-CylRad,-CylRad,0])
HemiThing();
}
The Wouxun KG-UV3D has three holes along the base that capture three tabs in the battery case, with tapered edges to align the case with the contacts. After a few passes to get the dimensions right, the plate matching those features came out like this:
Base plate with tabs
The solid model shows the edge tapering down to a single layer:
Case Tab Base – Solid Model
The compound taper on the corners must match both the base and the sides of the radio. The bottom plate and shell have corresponding tapers that extend across the glued joints:
Radio interface tapers
That worked out surprisingly well, given the small dimensions and odd angles. The tabs, in particular, bumped right up against the 0.66 mm extrusion width; they’re 2.0 mm thick, so there’s barely one thread width inside the perimeter for fill. A bit of filing & slicing removed the usual enlargement at the end / start of each perimeter thread on the tabs, which is entirely acceptable for something this finicky.
The OpenSCAD source code with dimensions is all part of that post, but here’s the radio base shape that gets subtracted from the plate to make those tabs:
Radio Base Polygon – solid model
This seemed easier than adding a bunch of tiny pegs & triangles, but it’s certainly tedious working around a polygon:
Unlike my old ICOM IC-Z1A, the Wouxun KG-UV3D radio has mic and speaker jacks recessed into the case, so that a custom plug plate can absorb all the stress from forces applied to the cables without wiggling the plugs. Even better, there’s a removable cover with a mounting screw that can hold the new plate in place!
Wouxun plug mounting plate – overview
The first pass at the mount required a bit of filing, as the deepest part of the recess turns out to be not exactly rectangular. That’s (probably) fixed in the source code:
Wouxun plug plate – detail
The solid model looks about like you’d expect, with terribly thin side walls between the plugs and the not-quite-rectangular section. The whole affair is asymmetrical around the long axis; the not-quite-rectangular block and hole really are offset:
Plug Mount Plate – Solid Model
When printed, the thin sections come out one 0.66 mm plastic thread wide:
Wouxun plug mounting plate – build
I spent quite some time iterating through OpenSCAD, RepG, and SkeinLayer to make sure that came out right. This is from a later version with larger recesses around the plugs:
Plug Mount Plate – skeinlayer
Some epoxy eased down along the plugs will lock them into the plastic, with an epoxy putty turd over the top to stabilize the cables and terminal connections. That’s a T6 Torx bit to mate with the 2 mm screw (with a captive washer!) pulled from the Small Drawer o’ Salvaged Metric Screws:
Wouxun plug plate – trial fit
The OpenSCAD source code is part of the huge block of code at the bottom of that post, but here’s the relevant section:
ABS plastic shrinks as it cools and large objects with thin sections tend to delaminate, as seen in the Barbie Pistol and a few other objects. The box for the GPS+voice interface is four threads thick and 35 mm tall, which provided enough energy to rip the side apart:
Box wall delamination
Solvent glue and a clamp shoved it back together again:
Clamping delamination
This one was extruded at 190 °C, which works fine for small objects and isn’t quite enough to fuse something like this. I’ll crank it up to 210 °C for the next iteration to see if that improves the result.