Archive for June, 2013
Another coaxial power plug lost its tip inside a lithium ion battery pack used with the APRS + Voice circuitry on our bikes, as I could barely see at the bottom of the socket:
Rather than cutting the pack apart, I buttered up the end of an intact plug with some ABS solvent glue (a hellish homebrew mixture of acetone and MEK), rammed it into the socket, and held it in place for a minute:
The tip emerged on the first try:
Even better, it cracked off the plug without too much effort:
More solvent glue and a few hours of clamping worked fine:
That cable is now back in service.
Back in the day, this was a “chart”:
The back sports an 1889 copyright date:
It’s a steel slab about 3/16 inch thick.
Perhaps the original owner, one “E Dunbeck”, scribed his name on the back. Perhaps he gave / sold it to Mad Phil, who passed it on to me. Although I may not use it much, it has a place of honor in the tool cabinet…
You could get a new 185 Time Saver direct from Starrett, with the front and back sides reversed: same holes, mostly the same printing, just flipped.
Verily, they don’t make ’em like they used to!
Dan sent me a Kysan 17HD-B8X300-A, a leadscrew-equipped stepper motor with much higher torque than the Makergear Z axis motor. According to the Kysan description, which is all we have to go on: 4.2 V @ 1.5 A means 2.8 Ω, at which current it produces 5.5 kg·cm = 540 mN·m of torque. I measure 3.2 Ω and 3.5 mH, not that that makes much difference.
I worked out some of the numbers in that post and, if they’re close, then the new motor has twice the torque of the OEM one. What’s more important is that the new motor will work correctly with a microstepping drive and won’t bake while doing so.
The new motor has more metal to it than the old one:
The leadscrew follower nut has unthreaded holes, but, mercifully, has the same OD, fits nicely into the Z stage, and those four holes line up perfectly.
I chopped off most of the wires and spliced a JST plug onto the end; of course, the motor ran backwards. Having foreseen that eventuality, I had not shrunk the tubing over the wires: swap a pair, shrink the tubing, and it’s done:
Some notes from the operation:
- Disconnect all the cables
- Remove HBP + glass plate
- Lay printer on +X side of the chassis
- Remove screws holding Z motor to chassis
- Remove nylock nuts and screws from leadscrew follower nut
- Remove Z axis home switch
- Run Z stage to top of rods
- The leadscrew bearing will probably have fallen out by now
- Loosen Z rod clamp nuts & bolts (top & bottom of rods)
- Push Z rods out using a nut driver, pull with a rag for traction
- Be ready to catch the Z stage when you remove the rods!
- Angle motor & leadscrew out of the chassis
- Angle new motor & leadscrew into the chassis
- Reinstall everything in reverse order
- Recalibrate everything…
The Z rod sliders have little balls inside, but they didn’t fall out during this adventure. I don’t know if that’s reliable information or not.
Now, to see what a better motor can do…
It should be possible to sense the filament diameter with a cheap webcam and some optics:
The general idea:
Given that LinuxCNC runs on a bone-stock PC, you can plug in a stock USB webcam and capture pictures (I have done this already). Because LinuxCNC isolates the motion control in a hard real time process, you can run heavy metal image manipulation code in userland (think ImageMagick) without affecting the motors.
So you can put a macro lens in front of a webcam (like that macro lens holder) and mount it just above the extruder with suitable lighting to give a high-contrast view of the filament. Set it so the filament diameter maps to about 1/4 of the width of the image, for reasons explained below.
For a crappy camera with 640×480 resolution, this gives you 160 pixel / 1.75 mm filament = 91 pixel/mm → about 0.01 mm resolution = 0.6%. Use a better camera, get better resolution: 1280 pixel = 0.3% resolution.
That gives you roughly 1% or 0.5% resolution in area. This is pretty close to the holy grail for DIY filament diameter measurement.
Add two first-surface mirrors / prisms aligned at right angles, so that the camera sees three views of the filament: straight on, plus two views at right angles, adjacent to the main view. Set the optics so they’re all about 1/4 of the image width, to produce an image with three parts filament and one part high-contrast background separating them. This is the ideal, reality will be messier.
Figure 1 shows an obvious arrangement, the mirrors in Figure 2 give more equal distances.
You could align the mirrors to provide three views at mutual 120° angles, which would equalize the distances and give you three identical angles for roundness computation, should that matter.
Diameter measurement process:
- Extract one (*) scan line across the image.
- Convert to binary pixels: 1 = filament, 0 = background, perhaps with ImageMagick auto thresholding.
- Add pixel values across the line, divide by 3, multiply by mm/pixel → average filament diameter.
Adding binary pixels is easy: it’s just the histogram, which ImageMagick does in one step. Dump data to a file / pipe, process it with Python. It all feeds into a LinuxCNC HAL component, which may constrain the language to C / Python / something else.
(*) You can get vertical averaging over a known filament length, essentially for free. Extract three (or more) scan lines, process as above, divide by 3 (or more), and you get a nicely averaged average.
Win: the image is insensitive to position / motion / vibration within reasonable limits, because you’re doing the counting on pixel values, not filament position. The camera can mount near, but not on, the extruder, so you can measure the filament just above the drive motor without cooking the optics or vibrating the camera to death.
Win: it’s non-contacting, so there’s not much to get dirty
Win: you get multiple simultaneous diameter measurements around one slice of the filament
You could mount the camera + optics at one end of the printer’s axis (on the M2, the X axis). Drive the extruder to a known X position, take a picture of the straight-on view, drive to another position, take a picture of the mirrored views, and you have two pictures in perfect focus. Combine & process as above.
You can do that every now and again, because any reasonable filament won’t vary that much over a few tens of millimeters. Maybe you do it once per layer, as part of the Z step process?
You could generalize this to a filament QC instrument that isn’t on the printer itself: stream the filament from spool to spool while measuring it every 10 mm, report the statistics. That measurement could run without stopping, because you don’t reposition the filament between measurements: it’s all fixed-focus against a known background. You could have decent roller guides for the filament to ensure it’s in a known position.
Heck, that instrument could produce a huge calibration file that gives diameter / roundness vs. position along the entire length of the filament. Use it to accept/reject incoming plastic supplies or, even better, feed the data into the printer along with the spool to calibrate the extrusion on the fly without fancy optics or measurements.
Dan wonders if this might be patented. I’m sure it is: I’m nowhere near as bright as the average engineering bear at a company that’s been spending Real Money for three decades. My working assumption: all the knowledge is out there, behind a barrier I can’t see through or reach around: there’s no point in looking for it beyond a casual Google search on the obvious terms that, so far, hasn’t produced anything similar.
Memo to Self: Might even be marketable, right up until they crush me like a bug…
In order to get the crash-test dummy stepper running on the X axis, I had to increase the
MIN_FERROR values by about two orders of magnitude from their defaults, which suggested I didn’t understand what I was doing and should run some numbers. I don’t profess to know how this works under the hood, though, but what follows seems to make sense.
Software step generation (which I’m not using) has an obvious limitation: the real-time software can produce at most one pulse per interrupt, so the maximum interrupt rate limits the maximum speed. The normal maximum rate is half a pulse per interrupt (the rising and falling edges occur on successive interrupts), but the software step generator can also produce a complete step pulse in a single interrupt; I don’t know the interaction between minimum step pulse width and interrupt period.
The maximum interrupt frequency / minimum interrupt period depends on the interrupt latency jitter, which seems to run around 5 to 10 μs for PC hardware that’s usable with software step generation. Assuming the pulse itself requires a few microseconds, then the minimum period seems to be around 20 to 25 μs, which limits the maximum step frequency to about 40 or 50 kHz. The Marlin firmware has an upper limit of 40000 step/s.
For comparison, a 50 μs base period works fine for the Sherline CNC mill, which tops out at 0.4 inch/s → 6400 step/s → 156 μs/step. That’s one reason converting a CNC mill to a 3D printer doesn’t work well; “normal” 3D printer speeds overtax leadscrews.
However, (I think) the fixed interrupt timing produces horrible period granularity: a 20 μs interrupt period = 50 kHz step frequency means that the next lower frequency with regular pulses is 25 kHz. Any speed requiring pulses between 25 kHz and 50 kHz will (I think) get irregular step timing that is, on the average, correct. That resembles Marlin’s multiple steps per interrupt bunching, without the fixed clumps.
To avoid all that, I’m using a Mesa 5i25 FPGA board that generates step timing in hardware based on a multi-megahertz clock. The specs don’t include a maximum step rate or granularity, but all indications are that it works wonderfully well; I plan to do some measurements to see what’s happening.
Assuming that the 5i25 can emit stepper pulses pretty much exactly when they’re supposed to happen, then the critical timing events depend on the servo loop period, for which everyone seems to use the default 1 ms. At each of those interrupts, the motion controller figures out what the stepper frequencies should be for the next period and twiddles the 5i25 to make them happen.
If, at the end of the next millisecond, the actual (calculated) and projected positions don’t match up, then the motion controller triggers a following error. This all happens in software, as there’s no actual position feedback from the motors.
Assuming that the required stepper pulse rate doesn’t exceed the maximum frequency, (I think) there’s only one point where a following error can happen: at the junction between constant-acceleration and constant-velocity motion. The worst case (seems to be) a
G0 move that ramps upward from a dead stop to the maximum allowed speed with the maximum allowed acceleration for an axis. Recall that RepRap firmware seems to use the same code for
G1 and limits the
G0 speed to whatever the most recent
F defined, so you tend to not find
G0 commands in RepRap-family G-Code.
The Trajectory Control doc suggests that the planner uses half the maximum defined acceleration while blending path segments. I used the full acceleration, which seems reasonable for single, non-blended motion.
I don’t know if the motion planner forces the junction to fall exactly at an interrupt time, but if it doesn’t, then the axis could accelerate for nearly a whole period after it should start the constant-velocity part of the path. The incremental distance would be:
x = 1/2 a t2
Assuming 10 m/s acceleration, the excess distance would be 0.005 mm after 1 ms. The default
FERROR value in PNCConf, which applies during rapid motion, turns out to be 0.0050 mm; I did see following errors as the motion begins, so I think that’s what triggers them.
On the other end of the motion, where the motor slows at a constant acceleration to a dead stop, I think the final position may have a jitter of ±1 motor (micro)step, so the
MIN_FERROR value must be at least twice as large as the minimum step size. The M2 runs at 88.9 step/mm (with 1/16 microstepping), so 1 step = 0.011 mm. The default
MIN_FERROR in PNCConf is 0.0005 mm (half a micron!) and following errors happened quite predictably at the end of motion.
MIN_FERROR by two orders of magnitude brought it to 0.0500 mm, a bit over the 0.022 = 2 * 0.011 required to cover the ±1 step endpoint error. Because I didn’t really understand what I was doing (and may not, even now), I had been changing both of the following error limits by factors of 10, and that last change turned out to be just enough.
While working all that out, I changed the M542 stepper brick DIP switches to use 1/20 microstepping, which increases the XY resolution to (36 mm/rev) / (4000 step/rev) = 0.009 mm/step → 111.1 step/mm. That doesn’t make any practical difference, but it pushes the XY step size below ten microns, which is certainly good for bragging rights. Yes, I know all about the lack of position accuracy from a microstepping motor, but work with me on this.
Based on those numbers, I picked:
FERROR= 0.050 mm
MIN_FERROR= 0.020 mm
Given that 3D printing involves gooey molten plastic laid down in half-millimeter strips, micron-scale error limits really don’t make much practical difference, but at least now (I think) I understand a bit more about the error boundaries.
Also, these limits have nothing to do with the G61.x Exact Path / G64 Path Blending G-Code commands, which tell the motion planner how much slop to allow when computing the path. Given all that gooey plastic, running with something like
G64 P0.1 Q0.1 might improve the overall speed quite a bit.
The cables with their tidy terminations make it a little neater, but all this stuff really needs a permanent home:
I used the LinuxCNC PNCConf utility to define a minimal system with little more than the X axis parameters filled in:
Then I could jog the stepper motor using the Axis UI:
And it worked!
Actually, it didn’t. The first motion instantly tripped a Following Error, so I bumped those values up a bit. Then I fiddled with accelerations and speeds and suchlike. Then I adjusted the Axis defaults to not be so nose-pickin’ slow. And then it Just Worked.
Not much to show, but at least I know the whole LinuxCNC to 5i25 to 7i76 to M542 to motor chain functions pretty much as it should, which is worth knowing. From here on out, it’s a matter of fine tuning…
Both the Mesa 7i76 and the M542 stepper driver boards use Phoenix-style pluggable screw terminals that simplify the connections: just strip the wires, jam them into the holes, and tighten the screw. That works great in an industrial situation where the equipment gets wired up once and stays that way forever, but I expect that I’ll be doing far too much twiddling… which means the stripped wire ends will fray and shed strands across the boards.
So, while wiring up a stepper motor, I tried soldering the wires to several different terminals I have lying around, just to see how they work.
The M542 stepper driver brick shows the assortment:
On the far left, the four stepper wires end in right-angle PCB pins harvested from surplus connectors. This didn’t work nearly as well as I’d like, simply because the pins are entirely too bulky. I’m not sure quite how the bricks will be arranged, but I think a right-angle connection won’t work well at all.
The field power from the 24 VDC supply arrives on some (cheap) 18 AWG speaker zip cord, terminated in straight-line PCB pins. Those worked better, but they do stick out a goodly amount. Methinks the right thing to do with larger wire is just solder the strands together, clean the end, and not bother with pins. That’s not so good for strain relief (it concentrates at the end of the soldered strands), but, with some tubing added, maybe it’ll be Good Enough.
The 26 AWG input wires from the 7i76 terminate in turret pins originally intended for PCB terminations or test points, back in the day when you (well, I) could actually see such things; I have a bag of 1000 that I’ve been chewing away at for a while. I think these wires are simply too small for the screw terminals, so they really need a pin of some sort and I like the way the turret pins work. The heatstink tubing provides a bit of strain relief, which always comes in handy.
The two stray wires will eventually go to the “Enable” input. It turns out that these bricks defaults to Enabled with no input signal, so you cannot depend on a wiring fault disabling the motor: a broken Enable wire enables the drive output. This seems flat-out dumb, but I suppose there’s some planet on which it makes sense.
I snipped a bunch of 3/8 inch (call it 10 mm) lengths of tubing, but that turns out to be slightly too long for the 7i76 terminal layout:
So the next iteration must be a bit shorter.
Yes, you can get commercial crimp pin terminations; search eBay for
crimp insulated terminal pins, some of which are curving around the planet even as I type. They won’t fit into the tight confines of the 7i76, but they should be better for the M542 bricks. The smallest size fits 22 through 16 AWG wires, so my tiny cable wires may need some steroids to bulk ’em up.
On the stepper motor end of the cable, I picked up a bunch of JST connectors and crimp pins. Unfortunately, the proper crimp tool runs into the hundreds of dollars, even from the usual eBay suppliers, and I really don’t have that much need for those pins. So I just soldered wires from the cable to the pins and mashed them down with needle nose pliers:
The alert reader will notice an egregious wire color coding faceplant. I made a corresponding blunder on the other end and nobody will ever know. Next time, maybe I’ll get it right.
That makes for a nice connection at the motor:
The thin black cable has nine 26 AWG conductors that I’m doubling up for the motors. In round numbers, 26 AWG stranded has about 120 mΩ/m resistance, so two in parallel work out to 60 mΩ/m. Assuming a meter of cable between the driver and the motor, a 1 A winding current will drop 120 mV along the way and dissipate 1/8 W, which seems defensible. It’s obviously Good Enough for signal wiring.
It is most definitely not good enough for, say, the heaters.
The motivation for using that cable: it’s thin and super-flexy, not the rigid cylinder you get with larger conductors. Plus, I have a huge supply of the stuff… it originally served as RS-232 cable, with molded connectors on each end of a 30 foot length, with four such cables assembled into a super-cable with nylon padding yarn laid inside a protective outer sheath. Must have cost a fortune to the original buyer; decades ago I got three or five of the assemblies and have been harvesting cable ever since.