Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.
Back in the day, heatsinks like this sat atop Moah Powah Pentium CPUs:
ET227 transistor on heatsink
I picked it because the hulking ET227 transistor fit neatly on its backside, it seemed capable of handling 30 to 50 W of power, and I have several of them in the Big Box o’ Heatsinks. No careful thermal analysis was involved…
Mounting it on the polycarbonate sheet inside the repurposed GX270 case involved drilling & tapping a pair of 6-32 holes in one side:
ET227 Heatsink – tapping
That’s not rigid tapping on a Sherline, it’s aligning a hand-turned tap in the spindle bore. Sorry.
And, yeah, you’re not supposed to leave the semiconductors mounted when you’re drilling the heatsink. I figure there’s nothing I can possibly do without using a hammer that will bother that transistor in the slightest. What, me worry?
The transistor collector runs at line voltage, which means the entire heatsink will pose a lethal shock hazard. I thought about isolating the collector and failed to come up with anything I’d trust to be both thermally conductive and electrically insulating over the long term; the screw heads must be isolated from the collector plate, too.
The screws stick out below the polycarbonate sheet, just above the grounded EMI shell lining the case, so I flattened them a bit:
ET227 Heatsink – mounting screws
The simple rectangular strip to the rear of the chassis mounting clips is just slightly thicker than the screw heads, so they can’t possibly contact the case:
Chassis Clips
It gets glued to the underside of the nearly invisible sheet:
ET227 heatsink – gluing screw shield
With Kapton tape over the heads, Just In Case:
ET227 Heatsink – mounted
It makes a nice linear counterpoint to the jumble of AC interface wiring:
AC Interface Chassis
The insulating sheet on the case lid came from the bottom of the original GX270 system board, where I think it served much the same purpose. It’s surely not rated for AC line voltages, but the thought must count for something:
The Dell GX270 system board mounts on a tray, latching into small tabs, with a single screw locking it in place. The tray then slides into the metal EMI shield / case, latching onto more tabs, with a spring-loaded pair of tabs snapping into a slot under the green latch:
Optiplex GX270 – system board tray
All that is well and good for a mass-production PC system board, but poses a problem for mounting anything else: there’s no room for screw heads below the tray, adhesives really don’t bond to slightly flexible aluminum sheets, and I definitely can’t do large-scale precision metal bending.
So a cheat seems in order. The general idea is to support a 6 mm polycarbonate sheet on clips that slide under the small tabs along the front, support the sheet on the rear tabs, and secure it with the screw. That’s thick enough to allow tapping holes for mounting screws, so everything else can mount to the sheet.
The sheet fits around the power supply on the right, protrudes over the rear of the tray to the back of the case (with a recess around the green latch), and clears the hinge assembly on the left. There are no dimensions, as it’s all done by eye with the Joggy Thing.
AC Chassis Shaping
A drive bay EMI plug from a long-discarded PC provided some nice springy steel strips that slide neatly under those tray tabs:
Drive EMI shield
That actually took a bit of trial-and-error:
AC Chassis mounting brackets – practice makes perfect
My first attempts used slightly thicker steel that didn’t fit nearly as well, plus I wasn’t quite sure how wide they should be.
As with nearly all plastic doodads around here, the white plastic mounting clips / brackets come from the M2:
Chassis Clips
The two brackets in the middle of the solid model slide around the tabs at the rear corners of the tray and capture the bent-over top section below the polycarbonate sheet.
The strip in the rear goes around the screws holding the heatsink to the sheet; more on that later.
The PLA brackets get themselves glued to the sheet with IPS #4 solvent adhesive, a hellish mixture of chlorinated hydrocarbons that attacks most plastics with gleeful enthusiasm. I positioned the brackets on the tray, slobbered adhesive on their tops, slapped the polycarbonate sheet in place, and applied clamps:
AC Chassis – gluing bracket blocks
The final bonds weren’t as uniform as I’d like, but they seem rugged enough. The lip along the rear of the tray was slightly higher on the left edge, which may have interfered with the clamping pressure; it’s obviously not a controlled dimension.
The tapped holes in the sheet accommodate screws for various bits & pieces.
Under ordinary circumstances, a fuseholder mounts in a square-ish panel cutout, but there’s no convenient panel to be found in the repurposed GX270 case. So now there’s a holder for the fuseholder stuck to the side of the power supply inside the case:
Fuseholder – installed
The square tube covers the entire fuseholder, with the quick-connect tabs protruding from the back, to provide enough surface area for the double-stick foam tape.
Looking down into the solid model, you can see the reduced width near the back end:
Fuseholder Holder
The black fuseholder contains a 5 A fast blow fuse, which should be entirely adequate for normal operation. In the event that a wire breaks loose and contacts the metal shell surrounding the whole chassis, it will pop instantly. That won’t disable the power supply, but it will remove line voltage from the entire motor controller chassis.
Remember that the source power line goes to the center QC tab, thus burying the always-hot contact deep in the fuseholder.
The OpenSCAD source code:
// Fuseholder mount
// Ed Nisley - KE4ZNU - August 2014
//- Extrusion parameters must match reality!
ThreadThick = 0.20;
ThreadWidth = 0.40;
HoleWindage = 0.2; // extra clearance
Protrusion = 0.1; // make holes end cleanly
AlignPinOD = 1.70; // assembly alignment pins: filament dia
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
//----------------------
// Dimensions
Shell = [25.0,25]; // outside = bezel size + some stiffening
Mount = [17.3,15.7,21.0]; // mount section = slight compression in X
Base = [13.5,15.7,17.0]; // clearance over crimped contact
OAL = Mount[2] + Base[2];
//----------------------
// Useful routines
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) {
RangeX = floor(100 / Space);
RangeY = floor(125 / Space);
for (x=[-RangeX:RangeX])
for (y=[-RangeY:RangeY])
translate([x*Space,y*Space,Size/2])
%cube(Size,center=true);
}
//----------------------
// Build it
ShowPegGrid();
difference() {
translate([0,0,OAL/2])
cube([Shell[0],Shell[1],OAL],center=true);
translate([0,0,Base[2] + Mount[2]/2])
cube(Mount + [0,0,2*Protrusion],center=true);
translate([0,0,Base[2]/2])
cube(Base + [0,0,2*Protrusion],center=true);
}
This angled ring fits under a repurposed CPU cooler:
Blower Mount – solid model
Viewed perpendicular to the angled surface, it’s a circle, so what looks like a vertical cylinder is actually slightly oval to make the top come out right. That way, the walls are vertical, not angled, and it doesn’t stand crooked on the base plate.
Such a shape is trivially easy for a 3D printer:
Blower mount – on build platform
And looks about like you’d expect on the blower, which is why that surface must be a circle:
Blower Mount – bottom view
A trial fit in the case, along with a bunch of parts I haven’t written up yet:
Blower Mount – installed
Under normal circumstances, you’d want the blower a bit higher and level, but there just wasn’t anywhere else to fit the fuseholder. Besides, this way the airflow goes slightly upward toward the clearance over the top of that monster heatsink. Some air flows along the side of the heatsink to cool the isolated power supply you can’t quite see in the far corner of the chassis beyond that tangle of wires.
The angle seems pretty close to right, although I must get the rest of the circuitry running to know if the airflow can actually transfer the heat from the heatsink out of the case.
It doesn’t take much OpenSCAD source code to define the shape:
// Blower mount
// Ed Nisley - KE4ZNU - August 2014
//- Extrusion parameters must match reality!
ThreadThick = 0.20;
ThreadWidth = 0.40;
HoleWindage = 0.2; // extra clearance
Protrusion = 0.1; // make holes end cleanly
AlignPinOD = 1.70; // assembly alignment pins: filament dia
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
//----------------------
// Dimensions
MountOD = 85.0; // a bit smaller than the housing OD
MountID = 60.0; // carve out to reduce printing time
Base = 5.0; // minimum thickness (allowing for some overhang)
ElevationAngle = atan(20/90); // net tilt across fan base
ElevationDelta = MountOD * tan(ElevationAngle);
echo(str("Elevation angle: ",ElevationAngle," delta: ",ElevationDelta));
//----------------------
// Useful routines
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) {
RangeX = floor(100 / Space);
RangeY = floor(125 / Space);
for (x=[-RangeX:RangeX])
for (y=[-RangeY:RangeY])
translate([x*Space,y*Space,Size/2])
%cube(Size,center=true);
}
//----------------------
// Build it
ShowPegGrid();
difference() {
scale([1,cos(ElevationAngle),1])
cylinder(d=MountOD,h=Base + ElevationDelta);
translate([-MountOD,-MountOD/2,Base])
rotate([ElevationAngle,0,0])
cube([2*MountOD,2*MountOD,ElevationDelta],center=false);
translate([0,0,-Protrusion])
cylinder(d=MountID,h=Base + 3*ElevationDelta);
}
Given the fragility of ferrite toroids in general and slit toroids in particular, a touch of up-armoring seems sensible:
FT82-43 toroid – mounted
The solid model includes a toroid shell with roughly the right curves:
Toroid Mount – Show layout
That puts a nice rounded shape on the bottom of the armor, not that that makes much difference:
Toroid Mount – Build layout
The central hole passes a 4-40 brass, nylon, or stainless steel screw. Most of the magnetic field stays within the ferrite and, heck, this isn’t a crazy-sensitive analog application, so even an ordinary steel screw shouldn’t cause any particular problems.
The rectangular (not pie-wedge) slit barely passes the Hall effect sensor.
I’ll pour some clear epoxy over the toroid, with tape masking the ferrite core and sealing the ends, to immobilize the windings. That sounds like a good idea after calibration and suchlike.
The OpenSCAD source code, which should be sufficiently parametric that I can crank ’em out for all the other toroids large enough to accept a screw:
// Toroid coil mounting bracket
// Ed Nisley - KE4ZNU - August 2014
Layout = "Mount"; // Coil Mount Build Show
//- Extrusion parameters must match reality!
// Print with 4 shells and 3 solid layers
ThreadThick = 0.20;
ThreadWidth = 0.40;
HoleWindage = 0.2; // extra clearance
Protrusion = 0.1; // make holes end cleanly
AlignPinOD = 1.70; // assembly alignment pins: filament dia
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
//----------------------
// Dimensions
ID = 0; // subscripts for cylindrical objects
OD = 1;
LEN = 2;
Coil = [10.25,23.50,8.3]; // wound toroid core
SensorThick = 2.0;
BaseThick = IntegerMultiple(1.0,ThreadThick); // baseplate under coil
WallThick = IntegerMultiple(1.0,ThreadWidth); // walls beside coil
ScrewHoleDia = 4.0; // allow alignment slop around 3 mm / #4 screws
//----------------------
// Useful routines
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) {
RangeX = floor(100 / Space);
RangeY = floor(125 / Space);
for (x=[-RangeX:RangeX])
for (y=[-RangeY:RangeY])
translate([x*Space,y*Space,Size/2])
%cube(Size,center=true);
}
//----------------------
// Basic coil shape
module CoilShape() {
CornerRadius = min((Coil[LEN] / 2),((Coil[OD] - Coil[ID]) / 2)) / 3;
MidRadius = (Coil[ID] + Coil[OD]) / 4;
HalfX = (Coil[OD] - Coil[ID]) / 4 - CornerRadius;
HalfY = (Coil[LEN] / 2) - CornerRadius;
echo(CornerRadius,MidRadius,HalfX,HalfY);
color("Goldenrod")
render(convexity = 2)
rotate(180/20)
rotate_extrude(convexity=3,$fn=20)
translate([MidRadius,0])
hull()
for (i=[-1,1],j=[-1,1])
translate([i*HalfX,j*HalfY])
circle(r=CornerRadius,$fn=24);
}
//----------------------
// Mount
module Mount() {
difference() {
rotate(180/20)
cylinder(h=(BaseThick + Coil[LEN]),d=(Coil[OD] + 2*WallThick),$fn=20);
translate([0,0,-Coil[LEN]]) // make screw hole
rotate(180/6)
PolyCyl(ScrewHoleDia,3*Coil[LEN],$fn=6);
translate([0,0,BaseThick + Coil[LEN]/2]) // set bottom curve
CoilShape();
translate([0,0,BaseThick + Coil[LEN]]) // clear out top
CoilShape();
translate([(Coil[ID]/2 + Coil[OD]/2),0,0])
cube([Coil[OD],SensorThick,3*Coil[LEN]],center=true);
}
}
ShowPegGrid();
if (Layout == "Coil") {
CoilShape();
}
if (Layout == "Mount")
Mount();
if (Layout == "Show") {
Mount();
translate([0,0,(BaseThick + Coil[LEN]/2)])
CoilShape();
}
if (Layout == "Build") {
Mount();
}
Mary recently learned that large spools of thread have a cross-wound lay that should feed over the end, not from the side as do ordinary stack-wound spools. So I built a right-angle adapter that fits over the not-quite-vertical spool pin on the sewing machine and aims directly at the thread tensioner:
Large spool adapter – on sewing machine
The solid model shows off the fluted rod that passes through the spool:
Large Spool Adapter – solid model – mount
It’s more impressive from the other end:
Large Spool Adapter – solid model – spool end
The first pass at the rod had six flutes, but that seemed unreasonably fine; now it has four. The round base on the rod provides more griptivity to the platform while building and has enough space for the two alignment pins that position it in the middle of the dome:
Large Spool Adapter – solid model – alignment holes
The dome gets glued to the rod base plate:
Large spool adapter – clamped
The spool pin hole is a snug fit around the pin on the sewing machine, because otherwise it would tend to rotate until the spool pointed to the rear of the machine. The fluted rod is a snug friction fit inside the (cardboard) spool. Some useful dimensions:
Spool pin (on Model 158): 5 mm OD, 40 mm tall
Large spool cores: 16 mm ID, 27 mm OD, 70 mm long
I had all manner of elaborate plans to make an expanding fluted rod, but came to my senses and built the simple version first. If that rod isn’t quite big enough, I can build another adapter, just like this one, only slightly larger. The source code includes a 0.5 mm taper, which may suffice.
Back in the day, shortly after the Thing-O-Matic started producing dependable results, one of the very first things I made was a simple adapter to mount large spools on the pin in the most obvious way:
Large spool adapter – old TOM version
Now we all know better than that, my OpenSCAD-fu has grown stronger, and the M2 produces precise results. Life is good!
The OpenSCAD source code:
// Large thread spool adapter
// Ed Nisley - KE4ZNU - August 2014
Layout = "Show"; // Build Show Spindle Spool
Gap = 10.0; // between pieces in Show
//- Extrusion parameters must match reality!
// Print with 4 shells and 3 solid layers
ThreadThick = 0.20;
ThreadWidth = 0.40;
HoleWindage = 0.2; // extra clearance
Protrusion = 0.1; // make holes end cleanly
AlignPinOD = 1.70; // assembly alignment pins: filament dia
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
//----------------------
// Dimensions
LEN = 0; // subscripts for cylindrical objects
ID = 1;
OD = 2;
Spindle = [40.0,5.0,14.0]; // spool spindle on sewing machine
Spool = [70.0,16.0,27.0]; // spool core
Taper = 0.50; // spool diameter increase at base
CottonRoll = [65.0,Spool[OD],45.0]; // thread on spool
Mount = [Spindle[LEN],(Spindle[ID] + 4*ThreadWidth),1.0*Spool[ID]];
Flutes = 4;
Flange = [2.0,Spool[OD],Spool[OD]];
ScrewHole = [10.0,4.0 - 0.7,5.0]; // retaining screw
PinOC = Spool[ID]/4; // alignment pin spacing
//----------------------
// Useful routines
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) {
RangeX = floor(100 / Space);
RangeY = floor(125 / Space);
for (x=[-RangeX:RangeX])
for (y=[-RangeY:RangeY])
translate([x*Space,y*Space,Size/2])
%cube(Size,center=true);
}
//- Locating pin hole with glue recess
// Default length is two pin diameters on each side of the split
module LocatingPin(Dia=AlignPinOD,Len=0.0) {
PinLen = (Len != 0.0) ? Len : (4*Dia);
translate([0,0,-ThreadThick])
PolyCyl((Dia + 2*ThreadWidth),2*ThreadThick,4);
translate([0,0,-2*ThreadThick])
PolyCyl((Dia + 1*ThreadWidth),4*ThreadThick,4);
translate([0,0,-(Len/2 + ThreadThick)])
PolyCyl(Dia,(Len + 2*ThreadThick),4);
}
//----------------------
// Spindle
module SpindleMount() {
render(convexity=4)
difference() {
union() {
resize([0,0,Mount[OD]]) // spool backing plate
translate([0,CottonRoll[OD]/2,0])
sphere(d=CottonRoll[OD],center=true);
translate([0,CottonRoll[OD]/4,0]) // mounting post
rotate([90,0,0])
cylinder(d=Mount[OD],h=CottonRoll[OD]/2,center=true);
}
translate([0,(2*Mount[LEN] - Protrusion),Mount[OD]/4]) // punch spindle hole
rotate([90,0,0])
// PolyCyl(Spindle[ID],2*Mount[LEN],6);
cylinder(d=Spindle[ID],h=2*Mount[LEN],$fn=6);
for (i=[-1,1]) { // punch alignment pin holes
translate([i*PinOC,CottonRoll[OD]/2,0])
LocatingPin(Len=Mount[OD]/3);
}
translate([0,0,-CottonRoll[OD]]) // remove half toward spool
cube(2*CottonRoll[OD],center=true);
}
}
//----------------------
// Spool holder
module SpoolMount() {
difference() {
union() {
translate([0,0,(Flange[LEN] - Protrusion)])
difference() {
cylinder(d1=(Spool[ID] + Taper),d2=Spool[ID],h=Spool[LEN],$fn=2*Flutes); // fit spool ID
for (a=[0 : 360/Flutes : 360-1]) // create flutes
rotate(a + 180/Flutes)
translate([Spool[ID]/2,0,-Protrusion])
rotate(180/16)
cylinder(r=Spool[ID]/4,h=(Spool[LEN] + 2*Protrusion),$fn=16);
translate([0,0,(Spool[LEN] - ScrewHole[LEN])]) // punch screw hole
PolyCyl(ScrewHole[ID],(ScrewHole[LEN] + Protrusion),6);
}
cylinder(d=Flange[OD],h=Flange[LEN]); // base flange
}
for (i=[-1,1]) // punch alignment pin holes
translate([0,i*PinOC,0]) // ... orients solid flange up
LocatingPin(Len=Flange[LEN]);
}
}
ShowPegGrid();
if (Layout == "Spindle") {
SpindleMount();
}
if (Layout == "Spool") {
SpoolMount();
}
if (Layout == "Show") {
translate([0,Mount[OD]/4,2.0]) {
rotate([90,0,0])
SpindleMount();
translate([0,Gap,CottonRoll[OD]/2])
rotate([-90,0,0]) rotate(90)
SpoolMount();
}
color("Orange") {
translate([0,0,2])
cylinder(d=Spindle[ID],h=Spindle[LEN],$fn=6);
cylinder(d=Spindle[OD],h=2.0,$fn=18);
}
}
if (Layout == "Build") {
translate([-5,0,0])
rotate(90)
SpindleMount();
translate([Flange[OD]/2,0,0])
SpoolMount();
}
A friend had his Makergear M2 filament drive motor stop driving the filament; the problem turned out to be a severely worn pinion gear on the motor shaft. Perhaps Makergear got a pallet of bad motors, as the problem seems to affect a batch of printers made during the middle of 2013, more or less.
The motor on my printer came off the line in early 2013, if that’s really a date code:
M2 Extruder motor – data sticker
There’s no manufacturer, but the 104022 number matches up with a Kysan motor. The description doesn’t say anything about the interior of the gearbox, but that’s not surprising. The gear ratio is 5.2:1, not the 5:1 I’d been assuming, which gets compensated out later on.
The pinion gear is worn, but not severely, and the three planet gears are in fine shape:
M2 Extruder – planetary gears
Slather everything with lithium gear grease, stuff the parts back in place, and it’s all good.
The socket-head set screws may have a bit of threadlock, as they’re firmly set in place, and, as you’d expect, Harbor Freight hex wrenches are made of butter-soft steel that’s totally useless in sizes below about 2.5 mm. In fact, those screws rounded the end of an old Craftsman wrench, so maybe they’re slightly oversize.