Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.
Tag: Improvements
Making the world a better place, one piece at a time
Although the M2’s heated build platform works well enough, somebody who knows what he’s doing (you know who you are: thanks!) sent me an improved version. It’s a PCB heater, laid out to compensate for the usual edge cooling, firmly attached to a tempered glass plate with genuine 3M thermally conductive tape:
Improved M2 HBP – test setup
They designed the heater around the 30 VDC power supply used in their other equipment. Although I had high moderate hopes that a boost power supply would convert the 24 V supply I already had for the stepper driver bricks into the 30 V for the heater, it was not to be. So there’s a 36 V 9.7 A 350 W supply arcing around the planet that (I think) should work better: adjust the voltage down as far as it’ll go, soak up another few volts in the solid-state relay, and Things Should Be Close Enough to 30 V. One can buy a genuine 30 V supply, but it costs surprisingly more than either 24 V or 36 V supplies on the surplus / eBay market and won’t really provide the proper voltage without upward tweaking anyway.
I replaced their standard 0.156 inch square terminals with Anderson Powerpoles, soldered a length of shielded cable to the 100 kΩ thermistor pads, and gimmicked up a connection to the 24 V supply; it delivered 23.7 V at the PCB terminals. The thermistor is 100 kΩ at 25 °C and 11.4 kΩ at 77 °C. The PCB heater is 5.9 Ω at 25 °C and 7.3 Ω at 77 °C; it dissipates 77 W at 77 °C (no, that’s not a typo).
The ultimate temperature looks to be about 90 °C with a 24 V supply, which isn’t quite enough for ABS (which I’m not using in the M2 right now, but probably will eventually). The time constant, assuming the 1-e-1 point is 66 °C, works out to about 9 minutes; it’ll be up to final temperature in half an hour. Those numbers aren’t quite as accurate as one might wish, because the heater power drops as the temperature rises and the copper resistance increases.
A 30 V supply would dissipate 120 W at 77 °C and rumor has it that the ultimate temperature is around 125 °C, which would be fine for ABS. Goosing the power a bit would produce more heat, but I’v been running the Thing-O-Matic at 110 °C and that’s good enough. More power, of course, gets it to the temperature setpoint faster, which is probably a Very Good Thing.
Obviously, you need PWM to control the temperature; given a 9 minute time constant, a bang-bang controller will work perfectly well.
The original data, including the thermistor resistance after I got my act together, plus a cute little temperature-vs-time graph:
Improved M2 HBP – 24 V supply
The colored flyspecks are part of the paper; I salvaged a stack of fancy menu cards from a trash can and padded them up as geek scratch paper.
A bit of rummaging in the Big Box o’ Weatherstripping produced the stub end of a spool bearing 1/4 x 1/8 foam tape that exactly fills the gap between the Basement Safe’s door and liner:
Basement Safe – Foam door seal – latch side
The hinge side of the door has tape between the door liner and the safe wall, because that closes in compression rather than shear:
Basement Safe – Foam door seal – hinge side
There should be a big bump in the humidity record marking that installation, but I don’t expect any immediate difference. If the silica gel lasts more than two months, I’ll consider it a win.
A day or so after kvetching about that informal DCRT vehicle entrance to the head planner developing the Dutchess County Master Plan for bicycle & pedestrian facilities, this appeared:
DCRT Overocker Crossing – block on informal entrance
Notice the blue electrical junction box on the right? That can’t possibly be a Good Thing… but, so far, it doesn’t seem to bother anybody enough to repair it.
Those missing ADA strips at Grand have been swept out, converting them into rough-bottomed trenches across the trail. At least they’re not quite so slip-prone, even if they’re still a tripping hazard.
Then wound them with grossly excessive amounts of wire (the up-armored core on the right appeared earlier):
Slit Ferrite Toroid current sensors
The smaller toroid is an FT37-43 that barely covers the active area of an SS49-style Hall effect sensor, but experience with the FT50 toroid suggests that’ll be entirely enough:
slit FT37 toroid trial fit to SS48-style Hall effect sensor
Data on the uncut toroids:
Property
FT50-61
FT37-43
Outer diameter (OD) – inch
0.50
0.375
Inner diameter (ID) – inch
0.281
0.187
Length – inch
0.188
0.125
Cross section area – cm2
0.133
0.133
Mean path length (MPL) – cm
3.02
2.15
Volume – cm3
0.401
0.163
Relative Permeability (μr )
125
850
Saturation flux G @ 10 Oe
2350
2750
Inductance factor (AL) – nH/turn2
68.0
420
Those overstuffed windings improved the sensitivity, but increased the winding resistance far beyond what’s reasonable.
Data on the slit toroids:
Toroid ID
FT50-61
FT37-43
FT50-61
Measured air gap – cm
0.15
0.15
0.17
Winding data
Turns
120
80
25
Wire gauge – AWG
28
32
26
Winding resistance – mΩ
530
920
100
Predicted B field – G/A
872
660
163
Hall effect sensor @ 1.9 mV/G
Predicted output – mV/mA
1.7
1.3
0.31
Actual output – mV/mA
1.9
1.9
0.37
Actual/predicted ratio – %
+12
+46
+19
The last few lines in that table show the transimpedance (transresistance, really, but …) based on the winding current to Hall sensor output voltage ratio (in either mV/mA or V/A, both dimensionally equivalent to ohms), which is why the toroid’s internal magnetic flux doesn’t matter as long as it’s well below saturation.
Gnawing the 80 turn winding off the FT37-43 toroid and rewinding it with 15 turns of 24 AWG wire dropped the winding resistance to 23 mΩ and the transimpedance to 0.36 mV/mA:
FT37-43 with 15 turns 24 AWG – Hall sensor
However, applying a voltage gain of about 28 (after removing the sensor’s VCC/2 bias) will produce a 0-to-5 V output from 500 mA input, which seems reasonable.
Decades ago, one jaw on my little 1/4 inch wrench that fits 4-40 nuts broke off. I brazed it back on, fully aware that one day it would break off again, because brazing isn’t really a suitable repair technique for a wrench, even one labeled as “Precision” in that time-honored manner of all low-cost tools.
Time passes, I’m tightening screws against 4-40 nuts, and the jaw gives way:
Precision wrench – broken jaw
So I sawed off a strip of bedframe steel that fit the nuts better than the original stamped steel, did a bit of hand filing, and came up with a reasonable replacement:
Precision wrench – detail
I rammed it into the handle, just as they’d done with the original stamped steel shape:
For reasons I won’t go into, I just installed another water heater. This one, nominally a GE that’s made by Rheem, has a perfectly aligned anode rod access port. This view shows the insulation filling the port, after removing the plastic cap:
GE Water Heater Anode Rod – as shipped
A bit of excavation reveals the top of the rod:
GE Water Heater Anode Rod – excavated
And the 1-1/16 six-point socket fits exactly through the port and mates perfectly with the rod:
The CNC version of the corner clips looks much better than the prototypes:
M2 glass retaining clip
Tightening the screws until the clip just flattens puts enough force on the glass + heat spreader stack to hold it firmly against the balls in the bottom pad. The solid rubber L-shaped bumpers and screws hold the glass in position against XY forces… and the whole affair looks much better than the original (and perfectly serviceable) bulldog clips. These clips free up the entire surface of the glass plate, minus four 12 mm triangles that you could, if you were desperate, print right over.
Although it’d be easier to just hack out an angular clip, I wrote a bit of G-Code to put a nice radius on each corner. The clip sits atop the rubber bumper with a 0.5 mm margin to keep the metal edges away from fingers; they’re smooth, but it’s still a strip of 6 mil (= 0.15 mm) phosphor bronze and feels a lot like a knife edge if you press hard enough.
The radius on the three outside corners is a special-case solution of the general circle-through-three-points problem, taking advantage of the symmetry and right-triangle-ness of the corners. This sketch shows the details:
M2 Platform Clip Doodles 4 – corner fairing with margin
The two corners on the bevel over the glass plate have a fixed radius. I reworked my original fairing arc solution for outside cutting and doodled it up for this situation:
M2 Platform Clip Doodles 5 – bevel full solution
The outside corner radius worked out to 5 mm and I set the bevel radius at 3 mm. I think the latter made those corners a bit too sharp, but it’s Good Enough for my simple needs.
Drilling and machining the clips required a fixture:
I used cutter diameter compensation to mill the edges, starting oversize by 1.5 mm and working downward by 0.5 mm on each pass to the actual diameter. That gradually trimmed off the edges without any excitement, so I could start with rough-trimmed stock and not worry about precision hand trimming.
I thought climb milling (CW around the part) would produce better results, but it tended to smear the phosphor bronze against the fixture:
M2 Corner Clips – Climb milling tool paths
Conventional milling (CCW around the part) actually worked, but it required fancier entry and exit moves:
M2 Corner Clips – Conventional milling tool paths
This part is the kind and size of machining perfectly suited to a Sherline CNC mill…
The LinuxCNC G-Code source:
( M2 Build Platform Corner Clips )
( Ed Nisley - KE4ZNU - July 2013 )
( Fixture origin at right-front corner pip )
( Flow Control )
#<_Do_Drill> = 0 ( Drill two holes in clip )
#<_Do_Mill> = 1 ( Mill clip outline )
#<_Climb_Mill> = 0 ( 0 = conventional 1 = climb)
( Fixture info )
#<_Drill_X_Fixture> = 5.0 ( Drill station origin )
#<_Drill_Y_Fixture> = 5.0
#<_Drill_Num> = 30 ( Drill number in tool table)
#<_Drill_Retract> = 15
#<_Drill_Depth> = -1.0
#<_Drill_Feed> = 300
#<_Drill_Speed> = 3000
#<_Mill_X_Fixture> = 40.0 ( Mill station origin )
#<_Mill_Y_Fixture> = 5.0
#<_Mill_Num> = 3 ( Mill number in tool table)
#<_Mill_Dia> = 4.60 ( actual tool diameter)
#<_Mill_Dia_Incr> = 0.50
#<_Mill_Dia_Steps> = 3
#<_Mill_Retract> = 15
#<_Mill_Depth> = -0.5
#<_Mill_Feed> = 300
#<_Mill_Speed> = 8000
(----------------)
( Initialize first tool length at probe switch )
( Assumes G59.3 is still in machine units, returns in G54 )
( ** Must set these constants to match G20 / G21 condition! )
#<_Probe_Speed> = 400 ( set for something sensible in mm or inch )
#<_Probe_Retract> = 1 ( ditto )
O<Probe_Tool> SUB
G49 ( clear tool length compensation )
G30 ( move above probe switch )
G59.3 ( coord system 9 )
G38.2 Z0 F#<_Probe_Speed> ( trip switch on the way down )
G0 Z[#5063 + #<_Probe_Retract>] ( back off the switch )
G38.2 Z0 F[#<_Probe_Speed> / 10] ( trip switch slowly )
#<_ToolZ> = #5063 ( save new tool length )
G43.1 Z[#<_ToolZ> - #<_ToolRefZ>] ( set new length )
G54 ( coord system 0 )
G30 ( return to safe level )
O<Probe_Tool> ENDSUB
(-------------------)
(-- Initialize first tool length at probe switch )
O<Probe_Init> SUB
#<_ToolRefZ> = 0.0 ( set up for first call )
O<Probe_Tool> CALL
#<_ToolRefZ> = #5063 ( save trip point )
G43.1 Z0 ( tool entered at Z=0, so set it there )
O<Probe_Init> ENDSUB
(-------------------)
(-- Mill one pass around outline with tool diameter passed in #1 )
O<MillOutline> SUB
#<X_Size> = 22.0 ( size of support spider pad = nominal clip size )
#<Y_Size> = 22.0
#<Base_Bevel> = 3.2 ( X or Y length of corners clipped from spider pad )
#<Bevel_Size> = 9.0 ( remaining part of trimmed edges on clip )
#<Bevel_Radius> = 3.0 ( fairing radius at bevel corners on clip)
#<R_Div_Root2> = [#<Bevel_Radius> / SQRT[2]]
#<R_1M_Recip_R2> = [#<Bevel_Radius> * [1 - 1/SQRT[2]]]
#<R_Root2_M1> = [#<Bevel_Radius> * [SQRT[2] - 1]]
#<Margin> = 0.5 ( recess inside of nominal )
#<X_Min> = [#<Margin>]
#<X_Max> = [#<X_Size> - #<Margin>]
#<Y_Min> = [#<Margin>]
#<Y_Max> = [#<Y_Size> - #<Margin>]
#<Corner_Rad> = [[#<Margin> * [1 - SQRT[2]] + [#<Base_Bevel> / SQRT[2]]] / [SQRT[2] - 1]]
O<Climb> IF [#<_Climb_Mill>]
G0 X#<X_Min> Y[#<Y_Max> + 3*#<_Mill_Dia>]
G1 Z#<_Mill_Depth> F#<_Mill_Feed>
G41.1 D#1
G3 X[#<X_Min>] Y#<Y_Max> I0 J[0-1.5*#<_Mill_Dia>] ( cutter comp on: entry move)
G1 X[#<Bevel_Size> - #<R_Root2_M1>]
G2 X[#<Bevel_Size> + #<R_1M_Recip_R2>] Y[#<Y_Max> - #<R_1M_Recip_R2>] J[0-#<Bevel_Radius>]
G1 X[#<X_Max> - #<R_1M_Recip_R2>] Y[#<Bevel_Size> + #<R_1M_Recip_R2>]
G2 X#<X_Max> Y[#<Bevel_Size> - #<R_Root2_M1>] I[0-#<R_Div_Root2>] J[0-#<R_Div_Root2>]
G1 Y[#<Y_Min> + #<Corner_Rad>]
G2 X[#<X_Max> - #<Corner_Rad>] Y#<Y_Min> I[0-#<Corner_Rad>] J0
G1 X[#<X_Min> + #<Corner_Rad>]
G2 X#<X_Min> Y[#<Y_Min> + #<Corner_Rad>] I0 J#<Corner_Rad>
G1 Y[#<Y_Max> - #<Corner_Rad>]
G2 X[#<X_Min> + #<Corner_Rad>] Y#<Y_Max> I#<Corner_Rad> J0
G40
G0 X#<X_Min> Y[#<Y_Max> + 3*#<_Mill_Dia>]
(G3 X#<Bevel_Size> Y[#<Y_Max> + 3*#<_Mill_Dia>] I0 J[1.5*#<_Mill_Dia>]) ( cutter comp off: safe exit)
G0 X#<X_Min> ( return to start)
O<Climb> ELSE
G0 X#<X_Size> Y[#<Y_Size> + #1/2]
G1 Z#<_Mill_Depth> F#<_Mill_Feed>
G42.1 D#1
G1 X#<Bevel_Size> Y[#<Y_Max>] ( cutter comp on: entry move)
G1 X[#<X_Min> + #<Corner_Rad>]
G3 X#<X_Min> Y[#<Y_Max> - #<Corner_Rad>] I0 J[0-#<Corner_Rad>]
G1 Y[#<Y_Min> + #<Corner_Rad>]
G3 X[#<X_Min> + #<Corner_Rad>] Y[#<Y_Min>] I#<Corner_Rad> J0
G1 X[#<X_Max> - #<Corner_Rad>]
G3 X[#<X_Max>] Y[#<Y_Min> + #<Corner_Rad>] I0 J#<Corner_Rad>
G1 Y[#<Bevel_Size> - #<R_Root2_M1>]
G3 X[#<X_Max> - #<R_1M_Recip_R2>] Y[#<Bevel_Size> + #<R_1M_Recip_R2>] I[-#<Bevel_Radius>]
G1 X[#<Bevel_Size> + #<R_1M_Recip_R2>] Y[#<Y_Max> - #<R_1M_Recip_R2>]
G3 X[#<Bevel_Size> - #<R_Root2_M1>] Y#<Y_Max> I[-#<R_Div_Root2>] J[-#<R_Div_Root2>]
G2 Y[#<Y_Max> + 3*#<_Mill_Dia>] J[#<_Mill_Dia>*1.5] ( get away from corner)
G40
G0 X#<X_Size> ( cutter comp off: safe exit)
G0 Y[#<Y_Size> + #1/2] ( return to start)
O<Climb> ENDIF
O<MillOutline> ENDSUB
(----------------)
( Start machining... )
G17 G40 G49 G54 G80 G90 G94 G99 ( reset many things )
G21 ( metric! )
G91.1 ( incremental arc centers)
(msg,Verify: G30.1 position in G54 above tool change switch? )
M0
(msg,Verify: fixture origin XY touched off? )
M0
(msg,Verify: Current tool Z=0 touched off? )
M0
( Set up probing)
O<Probe_Init> CALL
T0 M6
(---- Drill holes)
O<DoDrill> IF [#<_Do_Drill>]
(debug,Insert drill tool = #<_Drill_Num>)
T#<_Drill_Num> M6
O<Probe_Tool> CALL
(debug,Set spindle to #<_Drill_Speed> rpm )
M0
G0 X#<_Drill_X_Fixture> Y#<_Drill_Y_Fixture>
G0 Z#<_Drill_Retract>
G10 L20 P2 X0 Y0 Z#<_Drill_Retract> ( P2 = G55)
G55 ( drill station coordinates )
G81 X5.0 Y15.0 Z#<_Drill_Depth> R#<_Drill_Retract> F#<_Drill_Feed>
G81 X15.0 Y5.0
G54
O<DoDrill> ENDIF
(---- Mill outline )
( Start with large diameter and end with actual diameter to trim in stages)
O<DoMill> IF [#<_Do_Mill>]
(debug,Insert mill tool = #<_Mill_Num>)
T#<_Mill_Num> M6
O<Probe_Tool> CALL
(debug,Set spindle to #<_Mill_Speed> rpm )
M0
G0 X#<_Mill_X_Fixture> Y#<_Mill_Y_Fixture>
G0 Z#<_Mill_Retract>
G10 L20 P2 X0 Y0 Z#<_Mill_Retract> ( P2 = G55)
G55 ( mill station coordinates )
#<PassCount> = 0
O<MillLoop> DO
#<Diameter> = [#<_Mill_Dia> + [#<_Mill_Dia_Steps> - #<PassCount>]*#<_Mill_Dia_Incr>]
O<MillOutline> CALL [#<Diameter>]
#<PassCount> = [#<PassCount> + 1]
O<MillLoop> WHILE [#<PassCount> LE #<_Mill_Dia_Steps>]
( Finishing pass with zero cut )
O<MillOutline> CALL [#<Diameter>]
G0 Z#<_Mill_Retract>
G54
O<DoMill> ENDIF
G30
(msg,Done!)
M2
The rest of the doodles, which don’t match up with the final G-Code because they represent the earliest versions of the layout: