Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.
Category: Software
General-purpose computers doing something specific
Wouldn’t it be great if you could export all that stuff to a text file in a readable format? The CSV files come close, but they’re not really meant for human consumption.
Subject to revision, your mileage may vary, past performance is no indication of future yield, perfectly safe when used exactly as directed, shake before using, don’t touch that dial!
While printing up handouts for my talk at Cabin Fever, I finally tracked down why Adobe Reader was producing such crappy colors.
The left is before and the right is after the fix, scanned at the same time with the same image adjustments:
Oversaturated vs normal printing
All of the print settings appeared correct (plain paper, 720 dpi, normal contrast, etc, etc), but Adobe Reader (and only Adobe Reader) looked like it was trying to print on vastly higher quality paper than I was using. Too much ink, too much contrast, generally useless results.
The solution was, as always, trivial, after far too much fiddling around.
In Reader’s Print dialog, there’s a button in the lower-left corner labeled Advanced. Clicky, then put a checkmark in the box that says Let printer determine colors.
And then It Just Works.
Equally puzzling: ask for 25 copies of a two-page document, check the Collate box, and you get 25 page 1, 25 page 2, then more page 1 starts coming out. I bet I’d get 25 x 25 sheets of paper by the time it gave up.
I have no idea what’s going on, either.
Memo to Self: verify that the box stays checked after updates.
This was more tedious than it ought to be, but OpenSCAD now runs on my desktop box and uses OpenGL 2.2, courtesy of a not too obsolete nVidia GeForce 9400 dual-head card.
OpenSCAD has a slew of pre-reqs, most of which were already installed. However, the openscad and cgal non-packages live in the Arch AUR collection, so they required manual twiddling to install.
The pre-reqs:
cgal, which in turn requires cmake via pacman
opencsg
The recommended PKGBUILD patch is easy enough to do by hand.
The final build step takes ten minutes using both cores, but the final result uses OpenCSG the way it should.
Oddly, the OpenSCAD rendering process for the few objects I’ve checked takes longer than on the laptop. Weird.
This does not get the most recent build from the developers, but it’s close enough for my simple needs right now. The mailing list archive is invaluable.
Then there was the laptop saga. Maybe the reason the laptop is faster is that it’s not actually using OpenCSG at all.
With the thermistors nestled all snug in their wells, I turned on the heat and recorded the temperatures. I picked currents roughly corresponding to the wattages shown, only realizing after the fact that I’d been doing the calculation for the 5 Ω Thing-O-Matic resistors, not the 6 Ω resistor I was actually using. Doesn’t matter, as the numbers depend only on the temperatures, not the wattage.
This would be significantly easier if I had a thermocouple with a known-good calibration, but I don’t. Assuming that the real temperature lies somewhere near the average of the six measurements is the best I can do, so … onward!
Plotting the data against the average at each measurement produces a cheerful upward-and-to-the-right graph:
Data vs Ensemble Average
So the thermocouples seem reasonably consistent.
Plotting the difference between each measurement and the average of all the measurements at that data point produces this disconcertingly jaggy result:
Difference from Ensemble Average
The TOM thermocouple seems, um, different, which is odd, because the MAX6675 converts directly from thermocouple voltage to digital output with no intervening software. It’s not clear what’s going on; I don’t know if the bead was slightly out of its well or if that’s an actual calibration difference. I’ll check it later, but for now I will simply run with the measurements.
Eliminating the TOM data from the average produces a better clustering of the remaining five readings, with the TOM being even further off. The regression lines show the least-squares fit to each set of points, which look pretty good:
Difference from Average without TOM
Those regression lines give the offset and slope of the best-fit line that goes from the average reading to the actual reading, but I really need an equation from the actual reading for each thermocouple to the combined average. Rather than producing half a dozen graphs, I applied the spreadsheet’s SLOPE() and INTERCEPT() functions with the average temperature as Y and the measured temperature as X.
That produced this table:
TOM MPJA Craftsman A Craftsman B Fluke T1 Fluke T2
M = slope 1.0534 0.5434 0.5551 0.5539 1.0112 1.0154
B = intercept -1.6073 -15.3703 -19.4186 -16.9981 -0.7421 -0.3906
And then, given a reading from any of the thermocouples, converting that value to the average requires plugging the appropriate values from that table into good old
y = mx + b
For example, converting the Fluke 52 T1 readings produces this table of values. The Adjusted column shows the result of that equation and the Delta Avg column gives the difference from the average temperature (not shown here) for that reading.
The Max Avg Error (the largest value of the absolute difference from the average temperature at each point) after correction is 0.78 °C for this set. The others are less than that, with the exception of the TOM thermocouple, which differs by 1.81 °C.
So now I can make a whole bunch of temperature readings, adjust them to the same “standard”, and be off by (generally) less than 1 °C. That’s much better than the 10 °C of the unadjusted readings and seems entirely close enough for what I need…
OpenSCAD grumps about not finding OpenGL 2.0 whenever it starts up on my ancient laptop, which is tedious: that situation just isn’t going to change. Not a fatal error, although I do wonder what the OpenCSG rendering would look like.
Anyhow, a bit of rummaging turns up a hack that’ll cause OpenSCAD to STFU and just start up. That doesn’t make OpenCSG work, which is pretty much not a problem for my simple needs.
On Ubuntu-flavored distros, install driconf, then activate two options (in the Performance and Debugging tabs, respectively):
Enable limited ARB_fragment_shader support on 915/945
Enable stub ARB_occlusion_query support on 915/945
Once again I’m planning to attend the Cabin Fever Expo in York; my shop assistant says this year she won’t barf in the kitchen sink Thursday evening just before bedtime…
If I’m going to haul a Sherline CNC setup that far and spend all day talking machining, I must have some tchotchkes / swag to talk about. We figured a small plastic dog tag with relevant URLs would be appropriate.
Cabin Fever Dog Tag
I modeled the tag after my father’s WWII tag, including the mysterious notch. The rounded ends actually have three curves: two small fairing arcs blend the sides into the end cap.
The G-Code routine figures out all the coordinates and suchlike from some basic physical measurements & guesstimates, so tweaking the geometery is pretty straightforward. There was a blizzard going on while I wrote it: a fine day to spend indoors hacking code.
My assistant fired up Inkscape, laid out the text, figured out how to coerce G-Code out of Inkscape using the cnc-club.ru extension, then aligned it properly with the center of the chain hole as the origin on the right side. My routine calls the text G-Code file as a subroutine.
The extension’s header and footer files wrap EMC2’s SUB / ENDSUB syntactic sugar around the main file. The default files include an M2 that kills off the program; took a while to track that one down.
The header file:
O<dogtagtext> SUB
And the matching footer file:
O<dogtagtext> ENDSUB
The Inkscape-to-gcode instructions come out with absolute coordinates relative to the origin you define when you create the layout. The nested loops in my wrapper slap a G55 coordinate offset atop each label in turn, then call the subroutine.
The result is pretty slick:
Screenshot: AXIS Dog Tags
I carved out that proof-of-concept label atop double-sided adhesive tape, but peeling off the goo is a real pain; a 2×3 array will be much worse. I’d rather do that than figure out how to clamp the fool things to the sacrificial plate, though.
The engraving is 0.2 mm deep with a Dremel 30 degree tool. My shop assistant describes it as “disturbing” the acrylic, not actually engraving a channel. This isn’t entirely a Bad Thing, as the font isn’t quite a stick font and the outline of each character mushes together. We must fiddle with the font a bit more; she favors a boldified OCR-A look.
Some lessons:
The Kate G-Code syntax highlighter isn’t down with EMC2’s dialect
Be very sure you touch off the workpiece origin in G54, not G55
Xylene doesn’t bother acrylic and works fine on tape adhesive
Symlinks aimed across an NFS link work fine in ~/emc2/nc_files/
That 2×3 array may be too big for the Sherline’s tooling plate
Tool length probing FTW!
The G-Code:
(Cabin Fever 2011 Dogtag)
(Ed Nisley - KE4ZNU - December 2010)
(Origin at center of chain hole near right side)
(Stock held down with double-stick tape)
(--------------------)
(Flow Control)
#<_DoText> = 1
#<_DoDrill> = 1
#<_DoMill> = 1
( Sizes and Shapes)
(-- Tag array layout)
#<_NumTagsX> = 3 (number of tags along X axis)
#<_NumTagsY> = 2 ( ... Y axis)
#<_TagSpaceX> = 60 (center-to-center along X axis)
#<_TagSpaceY> = 35 ( ... Y axis)
(-- Tag Dimensions)
#<_TagSizeX> = 50.8 (2.0 inches in WWII!)
#<_TagSizeY> = 28.6 (1-1/8 inches)
#<_TagSizeZ> = 2.0
#<_HoleOffsetX> = 4.0 (hole center to right-side tag edge)
#<_NotchSizeX> = 3.5 (locating notch depth from far left edge)
#<_NotchCtrY> = 5.0 (locating notch from Y=0)
#<_NotchAngleBot> = 30 (lower angle in notch)
#<_NotchAngleTop> = 45 (upper angle in notch)
(-- Fairing Curve Dimensions as offsets from end arc center)
#<_EndFairR> = [0.68 * #<_TagSizeY>]
#<_CornerFairR> = [0.25 * #<_TagSizeY>]
#<_PCRadius> = [#<_EndFairR> - #<_CornerFairR>]
#<_PCY> = [[#<_TagSizeY> / 2] - #<_CornerFairR>]
#<_PCTheta> = ASIN [#<_PCY> / #<_PCRadius>]
#<_PCX> = [#<_PCRadius> * COS [#<_PCTheta>]]
#<_P1Y> = [#<_TagSizeY> / 2] (top / bottom endpoint)
#<_P1X> = #<_PCX>
#<_P2X> = [#<_EndFairR> * COS [#<_PCTheta>]]
#<_P2Y> = [#<_EndFairR> * SIN [#<_PCTheta>]]
(-- Tooling)
#<_TraverseZ> = 1.0 (safe clearance above workpiece)
#<_DrillDia> = 3.2 (drill for hole and notch)
#<_DrillNum> = 1 ( ... tool number)
#<_DrillRadius> = [#<_DrillDia> / 2]
#<_DrillFeed> = 200 (drill feed for holes)
#<_DrillRPM> = 3000
#<_MillDia> = 3.2 (mill for outline)
#<_MillNum> = 1 ( ... tool number)
#<_MillRadius> = [#<_MillDia> / 2]
#<_MillFeed> = 150 (tool feed for outlines)
#<_MillRPM> = 5000
#<_TextDia> = 0.1 (engraving tool)
#<_TextNum> = 1
#<_TextFeed> = 600 (tool feed for engraving)
#<_TextRPM> = 10000
(-- Useful calculated values)
#<_TagRightX> = #<_HoleOffsetX> (extreme limits of tag in X)
#<_TagLeftX> = [#<_TagRightX> - #<_TagSizeX>]
#<_EndFairRtX> = [#<_TagRightX> - #<_EndFairR>]
#<_EndFairLfX> = [#<_TagLeftX> + #<_EndFairR>]
#<_NotchCtrX> = [#<_TagLeftX> + #<_NotchSizeX> - #<_DrillRadius>]
(--------------------)
(--------------------)
( 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
(--------------------)
(Start machining)
G40 G49 G54 G80 G90 G94 G97 G98 (reset many things)
G21 (metric!)
(msg,Verify G30.1 position in G54 above tool change switch)
M0
(msg,Verify XYZ=0 touched off at left front tag hole center on surface)
M0
O<Probe_Init> CALL
T0 M6 (clear the probe tool)
(-- Engrave Text)
O<DoText> IF [#<_DoText>]
(msg,Insert engraving tool)
T#<_TextNum> M6 (load engraving tool)
O<Probe_Tool> CALL
F#<_TextFeed>
S#<_TextRPM>
(debug,Set spindle to #<_TextRPM>)
M0
G0 X0 Y0 (get safely to first tag)
G0 Z#<_TraverseZ> (to working level)
G10 L20 P2 X0 Y0 Z#<_TraverseZ> (set G55 origin to 0,0 at this point)
G55 (activate G55 coordinates)
O3000 REPEAT [#<_NumTagsX>]
O3100 REPEAT [#<_NumTagsY>]
O<dogtagtext> CALL
G0 X0 Y0
G10 L20 P2 Y[0 - #<_TagSpaceY>] (set Y orgin relative to next tag in +Y direction)
O3100 ENDREPEAT
G10 L20 P2 X[0 - #<_TagSpaceX>] Y[[#<_NumTagsY> - 1] * #<_TagSpaceY>] (next to +X, Y to front)
O3000 ENDREPEAT
G54 (bail out of G55 coordinates)
(-- Drill holes)
O<DoDrill> IF [#<_DoDrill>]
T0 M6
(msg,Insert drill)
T#<_DrillNum> M6
O<Probe_Tool> CALL
F#<_DrillFeed>
S#<_DrillRPM>
#<_DrillZ> = [0 - #<_TagSizeZ> - #<_DrillRadius>]
(debug,Set spindle to #<_DrillRPM>)
M0
G0 X0 Y0 (get safely to first tag)
G0 Z#<_TraverseZ> (to working level)
#<IndexX> = 0
O1000 DO
#<IndexY> = 0
O1100 DO
#<TagOriginX> = [#<IndexX> * #<_TagSpaceX>]
#<TagOriginY> = [#<IndexY> * #<_TagSpaceY>]
G81 X#<TagOriginX> Y#<TagOriginY> Z#<_DrillZ> R#<_TraverseZ>
G81 X[#<TagOriginX> + #<_NotchCtrX>] Y[#<TagOriginY> + #<_NotchCtrY>] Z#<_DrillZ> R#<_TraverseZ>
#<IndexY> = [#<IndexY> + 1]
O1100 WHILE [#<IndexY> LT #<_NumTagsY>]
#<IndexX> = [#<IndexX> + 1]
O1000 WHILE [#<IndexX> LT #<_NumTagsX>]
G30 (go home)
O<DoDrill> ENDIF
(-- Machine outlines)
O<DoMill> IF [#<_DoMill>]
T0 M6 (eject drill)
(msg,Insert end mill)
T#<_MillNum> M6 (load mill)
O<Probe_Tool> CALL
F#<_MillFeed>
S#<_MillRPM>
(debug,Set spindle to #<_MillRPM>)
M0
G0 X0 Y0 (get safely to first tag)
G0 Z#<_TraverseZ> (to working level)
G10 L20 P2 X0 Y0 Z#<_TraverseZ> (set G55 origin to 0,0 at this point)
G55 (activate G55 coordinates)
O2000 REPEAT [#<_NumTagsX>]
O2100 REPEAT [#<_NumTagsY>]
G0 X[#<_NotchCtrX>] Y[#<_NotchCtrY>] (get to center of notch hole)
G0 Z[0 - #<_TagSizeZ>] (down to cutting level)
G91 (relative coordinate for notch cutting)
G1 X[0 - #<_NotchSizeX>] Y[0 - #<_NotchSizeX> * TAN [#<_NotchAngleBot>]]
G1 X[0 + #<_NotchSizeX>] Y[0 + #<_NotchSizeX> * TAN [#<_NotchAngleBot>]]
G1 X[0 - #<_NotchSizeX>] Y[0 + #<_NotchSizeX> * TAN [#<_NotchAngleTop>]]
G90 (back to abs coords)
G42.1 D#<_MillDia> (cutter comp to right)
G1 X[#<_TagLeftX>] Y0 (comp entry move to tip of left endcap)
G3 X[#<_EndFairLfX> - #<_P2X>] Y[0 - #<_P2Y>] I[#<_EndFairR>] J0 (left endcap front half)
G3 X[#<_EndFairLfX> - #<_P1X>] Y[0 - #<_P1Y>] I[#<_P2X> - #<_PCX>] J[#<_P2Y> - #<_PCY>]
G1 X[#<_EndFairRtX> + #<_P1X>] (front edge)
G3 X[#<_EndFairRtX> + #<_P2X>] Y[0 - #<_P2Y>] I0 J[#<_CornerFairR>]
G3 X[#<_EndFairRtX> + #<_P2X>] Y[#<_P2Y>] I[0 - #<_P2X>] J[#<_P2Y>] (right endcap)
G3 X[#<_EndFairRtX> + #<_P1X>] Y[#<_P1Y>] I[#<_PCX> - #<_P2X>] J[#<_PCY> - #<_P2Y>]
G1 X[#<_EndFairLfX> - #<_P1X>] (rear edge)
G3 X[#<_EndFairLfX> - #<_P2X>] Y[#<_P2Y>] I0 J[0 - #<_CornerFairR>]
G3 X[#<_EndFairLfX> - #<_P2X>] Y[0 - #<_P2Y>] I[#<_P2X>] J[0 - #<_P2Y>] (left endcap complete)
G0 Z#<_TraverseZ>
G40
G0 X0 Y0
G10 L20 P2 Y[0 - #<_TagSpaceY>] (set Y orgin relative to next tag in +Y direction)
O2100 ENDREPEAT
G10 L20 P2 X[0 - #<_TagSpaceX>] Y[[#<_NumTagsY> - 1] * #<_TagSpaceY>] (next to +X, Y to front)
O2000 ENDREPEAT
G54 (bail out of G55 coordinates)
G30 (go home)
O<DoMill> ENDIF
M2
This is a stick in the ground for the current config files I’m using with EMC 2.4.5. Even the automagically generated files may have some tweakage, which is why I’m putting them here…
[Update: this is for a Dell Dimension 4550 with a latency around 10 µs, occasional glitches to 20 µs, and a very rare burp to 80 µs. Worked fine, but those rare burps were disturbing.]
# Include your customized HAL commands here
# This file will not be overwritten when you run stepconf again
#--------------
# Get buttons and joysticks from Logitech Dual Action gamepad
loadusr -W hal_input -KA Dual
#--------------
# Home switches are all in parallel, active low
net homeswitches <= parport.0.pin-10-in-not
net homeswitches => axis.0.home-sw-in
net homeswitches => axis.1.home-sw-in
net homeswitches => axis.2.home-sw-in
#--------------
# Probe input is active low
net probe-in <== parport.0.pin-15-in-not
net probe-in ==> motion.probe-input
custom_postgui.hal
#-- empty
Logitech_Gamepad.hal
# HAL config file automatically generated by Eagle-CAD ULP:
# [/mnt/bulkdata/Project Files/eagle/ulp/hal-write-array.ulp]
# (C) Martin Schoeneck.de 2008
# Mods Ed Nisley 2010
# Path [/mnt/bulkdata/Project Files/eagle/projects/EMC2 HAL Configuration/]
# ProjectName [Logitech Gamepad]
# File name [/mnt/bulkdata/Project Files/eagle/projects/EMC2 HAL Configuration/Logitech_Gamepad.hal]
# Created [11:51:27 10-Nov-2010]
####################################################
# Load realtime and userspace modules
loadrt constant count=16
loadrt and2 count=17
loadrt flipflop count=4
loadrt mux2 count=5
loadrt mux4 count=1
loadrt not count=8
loadrt or2 count=10
loadrt scale count=7
loadrt timedelay count=1
loadrt toggle count=1
loadrt wcomp count=6
####################################################
# Hook functions into threads
addf toggle.0 servo-thread
addf wcomp.1 servo-thread
addf wcomp.2 servo-thread
addf wcomp.3 servo-thread
addf and2.0 servo-thread
addf and2.4 servo-thread
addf and2.3 servo-thread
addf and2.2 servo-thread
addf and2.1 servo-thread
addf constant.6 servo-thread
addf constant.5 servo-thread
addf constant.4 servo-thread
addf constant.3 servo-thread
addf constant.2 servo-thread
addf constant.1 servo-thread
addf constant.0 servo-thread
addf constant.7 servo-thread
addf constant.8 servo-thread
addf scale.1 servo-thread
addf scale.2 servo-thread
addf scale.3 servo-thread
addf mux4.0 servo-thread
addf mux2.0 servo-thread
addf scale.4 servo-thread
addf scale.0 servo-thread
addf wcomp.5 servo-thread
addf wcomp.4 servo-thread
addf wcomp.0 servo-thread
addf flipflop.1 servo-thread
addf flipflop.0 servo-thread
addf and2.5 servo-thread
addf and2.6 servo-thread
addf and2.7 servo-thread
addf and2.8 servo-thread
addf flipflop.2 servo-thread
addf flipflop.3 servo-thread
addf or2.4 servo-thread
addf or2.8 servo-thread
addf or2.7 servo-thread
addf or2.6 servo-thread
addf or2.5 servo-thread
addf or2.3 servo-thread
addf or2.2 servo-thread
addf or2.1 servo-thread
addf or2.0 servo-thread
addf not.1 servo-thread
addf not.2 servo-thread
addf not.3 servo-thread
addf not.4 servo-thread
addf not.5 servo-thread
addf not.6 servo-thread
addf not.7 servo-thread
addf not.0 servo-thread
addf constant.9 servo-thread
addf mux2.1 servo-thread
addf mux2.2 servo-thread
addf mux2.3 servo-thread
addf mux2.4 servo-thread
addf constant.10 servo-thread
addf constant.11 servo-thread
addf scale.5 servo-thread
addf scale.6 servo-thread
addf constant.12 servo-thread
addf constant.13 servo-thread
addf timedelay.0 servo-thread
addf constant.14 servo-thread
addf constant.15 servo-thread
addf and2.16 servo-thread
addf and2.15 servo-thread
addf and2.14 servo-thread
addf and2.13 servo-thread
addf and2.12 servo-thread
addf and2.11 servo-thread
addf and2.10 servo-thread
addf and2.9 servo-thread
addf or2.9 servo-thread
####################################################
# Set parameters
####################################################
# Set constants
setp constant.0.value +0.02
setp constant.1.value -0.02
setp constant.2.value 60
setp constant.3.value 1.00
setp constant.4.value 0.10
setp constant.5.value 0.50
setp constant.6.value 0.10
setp constant.7.value +0.5
setp constant.8.value -0.5
setp constant.9.value 0.0
setp constant.10.value [TRAJ]MAX_LINEAR_VELOCITY
setp constant.11.value [TRAJ]MAX_ANGULAR_VELOCITY
setp constant.12.value -1.0
setp constant.13.value 0.1
setp constant.14.value 0.020
setp constant.15.value 0.000
####################################################
# Connect Modules with nets
net a-button-minus input.0.btn-trigger or2.2.in0 and2.15.in0
net a-button-plus input.0.btn-thumb2 or2.2.in1 and2.16.in0
net a-buttons-active or2.2.out or2.3.in0 or2.4.in1
net a-disable not.7.out and2.5.in1
net a-enable or2.4.in0 flipflop.3.out not.7.in mux2.4.sel
net a-jog wcomp.2.in input.0.abs-z-position mux2.4.in1
net a-knob-active not.2.out and2.7.in1
net a-knob-inactive wcomp.2.out not.2.in and2.6.in1
net a-select and2.8.in0 and2.7.out
net a-set flipflop.3.set and2.8.out
net angular_motion or2.4.out mux2.0.sel
net any-buttons-active mux4.0.sel0 or2.8.out
net az-buttons-active or2.3.out or2.8.in1 or2.9.in0
net az-reset flipflop.2.reset and2.6.out flipflop.3.reset
net button-crawl scale.4.out mux4.0.in3
net button-fast scale.2.out mux4.0.in1 scale.4.in
net jog-crawl toggle.0.out mux4.0.sel1
net jog-speed halui.jog-speed mux4.0.out
net knob-crawl mux4.0.in2 scale.3.out
net knob-fast mux4.0.in0 scale.1.out scale.3.in
net n_1 constant.10.out mux2.0.in0
net n_2 and2.0.in0 input.0.btn-top2
net n_3 and2.0.in1 input.0.btn-base
net n_4 and2.0.out halui.abort
net n_5 halui.mode.manual input.0.btn-base3
net n_6 wcomp.0.max wcomp.1.max wcomp.2.max wcomp.3.max constant.0.out
net n_7 halui.program.resume input.0.btn-base4
net n_8 wcomp.0.min wcomp.1.min wcomp.2.min wcomp.3.min constant.1.out
net n_9 mux2.0.in1 constant.11.out
net n_10 constant.12.out scale.5.gain scale.6.gain
net n_11 input.0.btn-base5 or2.0.in0
net n_12 input.0.btn-base6 or2.0.in1
net n_13 constant.9.out mux2.1.in0 mux2.2.in0 mux2.3.in0 mux2.4.in0
net n_14 mux2.1.out halui.jog.0.analog
net n_15 toggle.0.in or2.0.out
net n_16 constant.2.out scale.0.gain
net n_17 constant.5.out scale.1.gain
net n_18 constant.3.out scale.2.gain
net n_19 constant.4.out scale.3.gain
net n_20 scale.4.gain constant.6.out
net n_21 halui.jog.1.analog mux2.2.out
net n_22 mux2.2.in1 scale.5.out
net n_23 scale.6.out mux2.3.in1
net n_24 constant.13.out halui.jog-deadband
net n_25 wcomp.4.max constant.7.out wcomp.5.max
net n_26 constant.8.out wcomp.4.min wcomp.5.min
net n_27 mux2.3.out halui.jog.2.analog
net n_28 halui.jog.3.analog mux2.4.out
net n_29 timedelay.0.out and2.9.in1 and2.10.in1 and2.12.in1 and2.11.in1 and2.13.in1 and2.14.in1 and2.16.in1 and2.15.in1
net n_30 and2.9.out halui.jog.0.minus
net n_31 or2.9.out timedelay.0.in
net n_32 constant.14.out timedelay.0.on-delay
net n_33 constant.15.out timedelay.0.off-delay
net n_34 and2.10.out halui.jog.0.plus
net n_35 and2.11.out halui.jog.1.minus
net n_36 halui.jog.1.plus and2.12.out
net n_37 and2.13.out halui.jog.2.minus
net n_38 and2.14.out halui.jog.2.plus
net n_39 and2.15.out halui.jog.3.minus
net n_40 and2.16.out halui.jog.3.plus
net vel-per-minute scale.0.out scale.1.in scale.2.in
net vel-per-second mux2.0.out scale.0.in
net x-buttons-active or2.7.in0 or2.5.out
net x-disable not.4.out and2.4.in1
net x-enable not.4.in flipflop.0.out mux2.1.sel
net x-hat-jog wcomp.4.in input.0.abs-hat0x-position
net x-hat-minus wcomp.4.under or2.5.in1 and2.9.in0
net x-hat-plus or2.5.in0 wcomp.4.over and2.10.in0
net x-jog wcomp.0.in input.0.abs-x-position mux2.1.in1
net x-knob-active not.0.out and2.1.in0
net x-knob-inactive wcomp.0.out not.0.in and2.2.in0 and2.3.in0
net x-set and2.1.out flipflop.0.set
net xy-buttons-active or2.7.out or2.8.in0 or2.9.in1
net xy-reset flipflop.0.reset and2.2.out flipflop.1.reset
net y-buttons-active or2.6.out or2.7.in1
net y-disable not.5.out and2.1.in1
net y-enable flipflop.1.out not.5.in mux2.2.sel
net y-hat-jog input.0.abs-hat0y-position wcomp.5.in
net y-hat-minus wcomp.5.under or2.6.in1 and2.12.in0
net y-hat-plus or2.6.in0 wcomp.5.over and2.11.in0
net y-jog wcomp.1.in input.0.abs-y-position scale.5.in
net y-knob-active not.1.out and2.3.in1
net y-knob-inactive not.1.in wcomp.1.out and2.2.in1
net y-select and2.4.in0 and2.3.out
net y-set flipflop.1.set and2.4.out
net z-button-minus input.0.btn-thumb or2.1.in0 and2.13.in0
net z-button-plus or2.1.in1 input.0.btn-top and2.14.in0
net z-buttons-active or2.1.out or2.3.in1
net z-disable not.6.out and2.8.in1
net z-enable not.6.in flipflop.2.out mux2.3.sel
net z-jog wcomp.3.in input.0.abs-rz-position scale.6.in
net z-knob-active not.3.out and2.5.in0
net z-knob-inactive not.3.in wcomp.3.out and2.7.in0 and2.6.in0
net z-set and2.5.out flipflop.2.set
Sherline.hal
# Generated by stepconf at Sat Aug 23 12:10:22 2008
# If you make changes to this file, they will be
# overwritten when you run stepconf again
loadrt trivkins
loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD traj_period_nsec=[EMCMOT]SERVO_PERIOD key=[EMCMOT]SHMEM_KEY num_joints=[TRAJ]AXES
loadrt probe_parport
loadrt hal_parport cfg=0xecd8
setp parport.0.reset-time 60000
loadrt stepgen step_type=0,0,0,0
loadrt pwmgen output_type=0
addf parport.0.read base-thread
addf stepgen.make-pulses base-thread
addf pwmgen.make-pulses base-thread
addf parport.0.write base-thread
addf parport.0.reset base-thread
addf stepgen.capture-position servo-thread
addf motion-command-handler servo-thread
addf motion-controller servo-thread
addf stepgen.update-freq servo-thread
addf pwmgen.update servo-thread
net spindle-cmd <= motion.spindle-speed-out => pwmgen.0.value
net spindle-enable <= motion.spindle-on => pwmgen.0.enable
net spindle-pwm <= pwmgen.0.pwm
setp pwmgen.0.pwm-freq 100.0
setp pwmgen.0.scale 1166.66666667
setp pwmgen.0.offset 0.114285714286
setp pwmgen.0.dither-pwm true
net spindle-cw <= motion.spindle-forward
net estop-out => parport.0.pin-01-out
net xdir => parport.0.pin-02-out
net xstep => parport.0.pin-03-out
setp parport.0.pin-03-out-reset 1
setp parport.0.pin-04-out-invert 1
net ydir => parport.0.pin-04-out
net ystep => parport.0.pin-05-out
setp parport.0.pin-05-out-reset 1
setp parport.0.pin-06-out-invert 1
net zdir => parport.0.pin-06-out
net zstep => parport.0.pin-07-out
setp parport.0.pin-07-out-reset 1
net adir => parport.0.pin-08-out
net astep => parport.0.pin-09-out
setp parport.0.pin-09-out-reset 1
net spindle-cw => parport.0.pin-14-out
net spindle-pwm => parport.0.pin-16-out
net xenable => parport.0.pin-17-out
setp stepgen.0.position-scale [AXIS_0]SCALE
setp stepgen.0.steplen 1
setp stepgen.0.stepspace 0
setp stepgen.0.dirhold 60000
setp stepgen.0.dirsetup 60000
setp stepgen.0.maxaccel [AXIS_0]STEPGEN_MAXACCEL
net xpos-cmd axis.0.motor-pos-cmd => stepgen.0.position-cmd
net xpos-fb stepgen.0.position-fb => axis.0.motor-pos-fb
net xstep <= stepgen.0.step
net xdir <= stepgen.0.dir
net xenable axis.0.amp-enable-out => stepgen.0.enable
setp stepgen.1.position-scale [AXIS_1]SCALE
setp stepgen.1.steplen 1
setp stepgen.1.stepspace 0
setp stepgen.1.dirhold 60000
setp stepgen.1.dirsetup 60000
setp stepgen.1.maxaccel [AXIS_1]STEPGEN_MAXACCEL
net ypos-cmd axis.1.motor-pos-cmd => stepgen.1.position-cmd
net ypos-fb stepgen.1.position-fb => axis.1.motor-pos-fb
net ystep <= stepgen.1.step
net ydir <= stepgen.1.dir
net yenable axis.1.amp-enable-out => stepgen.1.enable
setp stepgen.2.position-scale [AXIS_2]SCALE
setp stepgen.2.steplen 1
setp stepgen.2.stepspace 0
setp stepgen.2.dirhold 60000
setp stepgen.2.dirsetup 60000
setp stepgen.2.maxaccel [AXIS_2]STEPGEN_MAXACCEL
net zpos-cmd axis.2.motor-pos-cmd => stepgen.2.position-cmd
net zpos-fb stepgen.2.position-fb => axis.2.motor-pos-fb
net zstep <= stepgen.2.step
net zdir <= stepgen.2.dir
net zenable axis.2.amp-enable-out => stepgen.2.enable
setp stepgen.3.position-scale [AXIS_3]SCALE
setp stepgen.3.steplen 1
setp stepgen.3.stepspace 0
setp stepgen.3.dirhold 60000
setp stepgen.3.dirsetup 60000
setp stepgen.3.maxaccel [AXIS_3]STEPGEN_MAXACCEL
net apos-cmd axis.3.motor-pos-cmd => stepgen.3.position-cmd
net apos-fb stepgen.3.position-fb => axis.3.motor-pos-fb
net astep <= stepgen.3.step
net adir <= stepgen.3.dir
net aenable axis.3.amp-enable-out => stepgen.3.enable
net estop-out <= iocontrol.0.user-enable-out
net estop-out => iocontrol.0.emc-enable-in
loadusr -W hal_manualtoolchange
net tool-change iocontrol.0.tool-change => hal_manualtoolchange.change
net tool-changed iocontrol.0.tool-changed <= hal_manualtoolchange.changed
net tool-number iocontrol.0.tool-prep-number => hal_manualtoolchange.number
net tool-prepare-loopback iocontrol.0.tool-prepare => iocontrol.0.tool-prepared