The Smell of Molten Projects in the Morning

Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.

Category: Machine Shop

Mechanical widgetry

  • HAL Pin Names for a Bone-Stock USB Mouse

    I’ve always wondered what the LinuxCNC HAL pin names would be for an ordinary mouse, particularly nowadays when an Arduino Leonardo can become a USB HID gadget without much effort at all. If one had a Leonardo and l337 programming skillz, one might receive far more interesting data than just fast-twitch muscle movement…

    Logitech Optical Mouse - LinuxCNC box
    Logitech Optical Mouse – LinuxCNC box

    So. We begin…

    From less /proc/bus/input/devices:

    ... snippage ...
    I: Bus=0003 Vendor=046d Product=c077 Version=0111
    N: Name="Logitech USB Optical Mouse"
    P: Phys=usb-0000:00:1d.0-1/input0
    S: Sysfs=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0/input/input10
    U: Uniq=
    H: Handlers=mouse3 event10
    B: EV=17
    B: KEY=ff0000 0 0 0 0 0 0 0 0
    B: REL=143
    B: MSC=10
    

    From ll /dev/input:

    ... snippage ...
    crw-r-----   1 root root 13, 74 2013-02-23 07:46 event10
    ... snippage ...
    crw-r-----   1 root root 13, 35 2013-02-23 07:46 mouse3
    

    Manually beat the permissions into shape, because this is a one-off affair:

    sudo chgrp users /dev/input/event10
    sudo chgrp users /dev/input/mouse3
    sudo chmod g+w /dev/input/event10
    sudo chmod g+w /dev/input/mouse3
    

    Find the USB address from lsusb:

    Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 004 Device 006: ID 06f2:0011 Emine Technology Co. KVM Switch Keyboard
    Bus 004 Device 005: ID 046d:c401 Logitech, Inc. TrackMan Marble Wheel
    Bus 004 Device 004: ID 04d9:1203 Holtek Semiconductor, Inc. MC Industries Keyboard
    Bus 004 Device 003: ID 046d:c216 Logitech, Inc. Dual Action Gamepad
    Bus 004 Device 002: ID 0451:2046 Texas Instruments, Inc. TUSB2046 Hub
    Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 002 Device 002: ID 046d:c077 Logitech, Inc.
    Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    

    Query the attributes with udevadm:

    udevadm info --query=all --attribute-walk --name=/dev/bus/usb/002/002
    ... snippage ...
      looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1':
        KERNEL=="2-1"
        SUBSYSTEM=="usb"
        DRIVER=="usb"
        ATTR{configuration}==""
        ATTR{bNumInterfaces}==" 1"
        ATTR{bConfigurationValue}=="1"
        ATTR{bmAttributes}=="a0"
        ATTR{bMaxPower}==" 98mA"
        ATTR{urbnum}=="13"
        ATTR{idVendor}=="046d"
        ATTR{idProduct}=="c077"
        ATTR{bcdDevice}=="6700"
        ATTR{bDeviceClass}=="00"
        ATTR{bDeviceSubClass}=="00"
        ATTR{bDeviceProtocol}=="00"
        ATTR{bNumConfigurations}=="1"
        ATTR{bMaxPacketSize0}=="8"
        ATTR{speed}=="1.5"
        ATTR{busnum}=="2"
        ATTR{devnum}=="2"
        ATTR{version}==" 2.00"
        ATTR{maxchild}=="0"
        ATTR{quirks}=="0x0"
        ATTR{authorized}=="1"
        ATTR{manufacturer}=="Logitech"
        ATTR{product}=="USB Optical Mouse"
    

    Fire up halrun, load hal_input, and dump the pins:

    halrun
    halcmd: loadusr -W hal_input -KRAL Optical
    halcmd: show all
    Loaded HAL Components:
    ID      Type  Name                                      PID   State
         5  User  hal_input                                  1693 ready
         3  User  halcmd1692                                 1692 ready
    
    Component Pins:
    Owner   Type  Dir         Value  Name
         5  bit   OUT         FALSE  input.0.btn-back
         5  bit   OUT          TRUE  input.0.btn-back-not
         5  bit   OUT         FALSE  input.0.btn-extra
         5  bit   OUT          TRUE  input.0.btn-extra-not
         5  bit   OUT         FALSE  input.0.btn-forward
         5  bit   OUT          TRUE  input.0.btn-forward-not
         5  bit   OUT         FALSE  input.0.btn-middle
         5  bit   OUT          TRUE  input.0.btn-middle-not
         5  bit   OUT         FALSE  input.0.btn-mouse
         5  bit   OUT          TRUE  input.0.btn-mouse-not
         5  bit   OUT         FALSE  input.0.btn-right
         5  bit   OUT          TRUE  input.0.btn-right-not
         5  bit   OUT         FALSE  input.0.btn-side
         5  bit   OUT          TRUE  input.0.btn-side-not
         5  bit   OUT         FALSE  input.0.btn-task
         5  bit   OUT          TRUE  input.0.btn-task-not
         5  s32   OUT             0  input.0.rel-hwheel-counts
         5  float OUT             0  input.0.rel-hwheel-position
         5  bit   IN          FALSE  input.0.rel-hwheel-reset
         5  float IN              1  input.0.rel-hwheel-scale
         5  s32   OUT             0  input.0.rel-wheel-counts
         5  float OUT             0  input.0.rel-wheel-position
         5  bit   IN          FALSE  input.0.rel-wheel-reset
         5  float IN              1  input.0.rel-wheel-scale
         5  s32   OUT             0  input.0.rel-x-counts
         5  float OUT             0  input.0.rel-x-position
         5  bit   IN          FALSE  input.0.rel-x-reset
         5  float IN              1  input.0.rel-x-scale
         5  s32   OUT             0  input.0.rel-y-counts
         5  float OUT             0  input.0.rel-y-position
         5  bit   IN          FALSE  input.0.rel-y-reset
         5  float IN              1  input.0.rel-y-scale
    ... snippage ...
    

    Hmmm, that was interesting…

  • Eagle HAL Configuration: Sherline HAL File

    More hal-config.lbr tweakage produced enough HAL blocks to completely define the Sherline CNC mill’s HAL connections, all wired up in a multi-page schematic (Eagle-LinuxCNC-Sherline.zip.odt) that completely replaces all the disparate *.hal files I’d been using, plus a new iteration of the hal-write-2.5.ulp Eagle-to-HAL conversion script.

    The first sheet (clicky for more dots) defines the manually configured userspace and realtime modules:

    Sherline Schematic - 1
    Sherline Schematic – 1

    That sheet has three types of Eagle devices:

    • Generalized LoadRT – devices like trivkins that require only a loadrt line
    • Dedicated LoadRT – devices like motion that require functions connected to a realtime thread
    • Generalized LoadUsr – devices like hal_input with a HAL device, but no function pins

    The device’s NAME field contains either the module name (for the specialized devices with functions) or a generic MODULE for everything else, preceded by an optional index that imposes an ordering on the output lines. The device’s VALUE field contains the text that will become the loadrt or loadusr line in the HAL file. Trailing underscores act as separators, but are discarded by the conversion script.

    The immensely long line is the VALUE field that plugs a bunch of variables from the Sherline.ini file into the motion controller.

    The conversion script doesn’t do anything special for those devices, other than transfer the VALUE field to the HAL file. Ordinary HAL devices, the ones with functions that don’t require any special setup, must appear in the conversion script’s list of device names, so that it can recognize them and deal with their connections.

    That sheet produces this part of the HAL file:

    ####################################################
    # Load realtime and userspace modules
    loadrt trivkins
    loadrt [EMCMOT]EMCMOT key=[EMCMOT]SHMEM_KEY num_joints=[TRAJ]AXES base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD traj_period_nsec=[EMCMOT]SERVO_PERIOD
    loadrt probe_parport
    loadrt hal_parport cfg="[PARPORT]ADDRESS out"
    loadrt stepgen step_type=0,0,0,0
    loadrt pwmgen output_type=0
    loadusr -W hal_manualtoolchange
    loadusr -W hal_input -KA Dual
    loadrt logic count=1 personality=0x104
    

    The conversion script counts the other schematic devices and automagically produces these lines to load their corresponding modules:

    loadrt constant		count=13
    loadrt and2		count=17
    loadrt conv_float_s32		count=1
    loadrt flipflop		count=4
    loadrt mux2		count=5
    loadrt mux4		count=1
    loadrt not		count=8
    loadrt or2		count=14
    loadrt scale		count=7
    loadrt timedelay		count=1
    loadrt toggle		count=1
    

    Next, the parallel port configuration, which uses the D525’s system board hardware:

    Sherline Schematic - 2
    Sherline Schematic – 2

    The stepconf configuration utility buries the parallel port configuration values in the default HAL file as magic numbers. I moved them to a new stanza in the INI file, although the syntax may not be robust enough to support multiple cards, ports, and configurations. This, however, works for now:

    [PARPORT]
    ADDRESS = 0x378
    RESET_TIME = 10000
    STEPLEN = 25000
    STEPSPACE = 25000
    DIRSETUP = 50000
    DIRHOLD = 50000
    

    That LOGIC block is new and serves as an AND gate that produces a combined enable signal for the parallel port. The stepconf utility uses the X axis enable signal, but, seeing as how the Sherline controller doesn’t use the result, none of that matters on my system.

    The tool height probe and manual tool change wiring:

    Sherline Schematic - 3
    Sherline Schematic – 3

    I’m not convinced the Emergency Stop polarity is correct, but it matches what was in the original HAL file. As before, the Sherline driver box ignores that output, so none of that matters right now.

    Four very similar pages define the XYZA step-and-direction generators. This is the X axis driver:

    Sherline Schematic - 4
    Sherline Schematic – 4

    You can imagine what the next three pages for the YZA logic look like, right? There are also a few blank pages in the schematic, so the numbers jump abruptly.

    The magic part of this is having Eagle manage all the tedious renumbering and counting. If you remember to adjust the name of the first module from, say, AXIS.1 to AXIS.0, then the rest get the proper numbers as you go along.

    The remainder of the schematic implements the Joggy Thing’s logic, much as described there. I discovered, quite the hard way, that copy-and-pasting an entire schematic from elsewhere does horrible things to the device numbering, but I’m not sure how to combine two schematics to limit the damage. In any event, manually adjusting a few pages wasn’t the worst thing I’ve ever had to do; starting with a unified schematic should eliminate that task in the future.

    The miscellaneous buttons:

    Sherline Schematic - 11
    Sherline Schematic – 11

    The joystick and hat values:

    Sherline Schematic - 12
    Sherline Schematic – 12

    The joystick deadband logic now uses the (new with HAL 2.5, I think) input.n.abs-x-flat pins, which eliminated a tangle of window comparator logic.

    The jog speed adjustment logic that sets the fast and crawl speeds:

    Sherline Schematic - 13
    Sherline Schematic – 13

    I should probably put the speed ratios in the INI file, but that’s in the nature of fine tuning.

    The lockout logic that remembers which axis started moving first on a given joystick and locks out the other axis, which greatly simplifies jogging up to an edge without bashing into something else:

    Sherline Schematic - 14
    Sherline Schematic – 14

    Combine all those signals into values that actually tell HAL to jog the axes:

    Sherline Schematic - 15
    Sherline Schematic – 15

    The last page connects all the realtime function pins to the appropriate threads:

    Sherline Schematic - 16
    Sherline Schematic – 16

    The LinuxCNC documentation diverges slightly from the implementation, but a few iterations resolved all the conflicts and had the additional benefit that I had to carefully think through what was actually going on.

    A deep and sincere tip o’ the cycling helmet to the folks making LinuxCNC happen!

    Although the Sherline mill doesn’t have more than a few minutes of power-on time with the new HAL file, the Joggy Thing behaves as it used to and the axes move correctly, so I think the schematic came out pretty close to the original HAL file.

    The next step: draw a new schematic to bring up and exercise a different set of steppers…

  • Eagle HAL Configuration: Nostromo N52 Controller

    Combining some of the pin names generated by hal_input with the recipe for creating HAL devices, here’s a test configuration that hitches an old Nostromo N52 controller to a LinuxCNC system (clicky for more dots):

    Nostromo N52 Controller - HAL config
    Nostromo N52 Controller – HAL config

    The F01 key lights the red LED, the Orange Button lights the green LED, and a oneshot timer pulses the blue LED for half a second after the Button closes. The Thread block defines the connections from the functions to the main timing routine, and the loadrt block defines the thread timing. The hal_input module takes care of its own input sampling in userspace.

    Now, for the classic embedded system “Hello, world!” test:

    Nostromo N52 Controller - F01 test
    Nostromo N52 Controller – F01 test

    It’s amazing how good an LED can make you feel…

    A halscope shot shows the timing relation between the Orange Button (confusingly hitched to the greenkey signal) and the oneshot pulse:

    HalScope - oneshot triggering
    HalScope – oneshot triggering

    That schematic produces this HAL configuration file:

    # HAL config file automatically generated by Eagle-CAD ULP:
    # [/mnt/bulkdata/Project Files/eagle/ulp/hal-write-2.5.ulp]
    # (C) Martin Schoeneck.de 2008
    # Charalampos Alexopoulos 2011
    # Mods Ed Nisley KE4ZNU 2010 2013
    # Path        [/mnt/bulkdata/Project Files/eagle/projects/LinuxCNC HAL Configuration/]
    # ProjectName [Nostromo]
    # File name   [/mnt/bulkdata/Project Files/eagle/projects/LinuxCNC HAL Configuration/Nostromo.hal]
    # Created     [12:28:04 14-Feb-2013]
    
    ####################################################
    # Load realtime and userspace modules
    loadrt threads name1=test-thread period1=1000000
    loadusr -W hal_input -K +Nostromo:0 -KRL +Nostromo:1
    loadrt constant		count=1
    loadrt oneshot		count=1
    
    ####################################################
    # Hook functions into threads
    addf oneshot.0		test-thread
    addf constant.0		test-thread
    
    ####################################################
    # Set parameters
    
    ####################################################
    # Set constants
    setp constant.0.value	0.5
    
    ####################################################
    # Connect Modules with nets
    net bluepulse input.1.led-scrolll oneshot.0.out
    net duration constant.0.out oneshot.0.width
    net greenkey input.0.key-leftalt oneshot.0.in input.1.led-capsl
    net redkey input.0.key-tab input.1.led-numl
    

    A snapshot of the Nostromo.sch, Nostromo.hal, hal_config.lbr, and hal-write-2.5.ulp files is in Nostromo-N52.zip.odt. Rename it to get rid of the ODT suffix, unzip it, and there you go.

  • Garage Hose Faucet Shutoff Valve: Washer Replacement

    After replacing the hose valve in the garage, I promised to repair its leaky upstream shutoff valve:

    Corroded gate valve
    Corroded gate valve

    I shut off the hard water supply, dismantled the valve, and let everything soak in a cup of white vinegar for a few hours. The fizzing was a wonder to behold and the parts came out much cleaner without any effort at all.

    Removing the handle required the handle puller and considerable rapping on the corroded-in-place handle at the tapered shaft. That reddish disk used to be a tin-plated steel data plate, but now it’s just a corroded sheet:

    Shutoff valve - handle puller
    Shutoff valve – handle puller

    Because a shutoff valve will be open nearly all the time, it has a large washer that seals the cap and valve stem in addition to the usual stem packing:

    Shutoff valve - full-open washer
    Shutoff valve – full-open washer

    Attempting to remove the screw from the stem broke the head into two pieces:

    Shutoff valve - broken washer screw
    Shutoff valve – broken washer screw

    Worse, the screw shaft was a soft mass of corroded brass, so I had to drill it out and chase the threads with a 10-32 tap. I replaced the full-open washer with a slightly smaller one from the supply box, which required drilling out the hole to suit, adding some packing string under the main cap, and replacing the packing around the stem. But, eventually, putting everything back together works fine with no leaks at all.

    This turned out to be slightly less horrible than I expected, which probably doesn’t justify procrastinating until the evening before the coldest night of the season.

  • Gratuitous Engine Jeweling

    While pondering whether I should use the carcass of an old Dell PC to house the stepper drivers and control logic for the LinuxCNC M2 project, I bandsawed a scrap of aluminum sheet to about the right size. It had some truly nasty gouges and bonded-on crud, so I chucked up a wire brush cup in the drill press and had at it:

    Machine jeweled baseplate
    Machine jeweled baseplate

    It’s obvious I haven’t done jeweling in a long time, isn’t it? Even a crude engine jeweling job spiffs things right up, though, even if a cough showcase job like this deserves straighter lines and more precise spacing. The aluminum sheet is far too large for the Sherline, which put CNC right out of consideration, and I’m not up for sufficient crank spinning on the big manual mill.

    I match-marked mounting holes directly from the harvested motherboard and drilled them, whereupon I discovered that the aluminum is a dead-soft gummy alloy that doesn’t machine cleanly: it won’t become the final baseplate.

    Memo to Self: Use the shop vacuum with the nozzle spinward of the brush, fool.

  • Eagle 6.4 Schematics for LinuxCNC 2.5 HAL Configuration: Device Creation Checklist

    I’m updating the Eagle-to-HAL script and library I used to get the Joggy Thing working, with the intent of getting a Nostromo N52 working on another LinuxCNC box.

    To that end, here’s a checklist for creating a new Eagle device corresponding to a HAL module.

    Remember: although this process has a tremendous number of moving parts, you do it exactly once when you need a device that doesn’t already exist. After that, you just click to add an existing device to your schematic, wire it up, then the tedious write-only HAL overhead happens automagically.

    Cross-check the documentation with the actual component code!

    The man page lists the names, pins, parameters, and suchlike, but may have typos. This isn’t a criticism, it’s a fact of life.

    Before investing a ton o’ time creating an Eagle device, load the module and find out what’s really there:

    halrun
    halcmd: loadrt conv_float_s32
    halcmd: show all
    Loaded HAL Components:
    ID      Type  Name                                      PID   State
         4  RT    conv_float_s32                                  ready
         3  User  halcmd2395                                 2395 ready
    
    Component Pins:
    Owner   Type  Dir         Value  Name
         4  float IN              0  conv-float-s32.0.in
         4  s32   OUT             0  conv-float-s32.0.out
         4  bit   OUT         FALSE  conv-float-s32.0.out-of-range
    
    ... snippage ...
    
    Parameters:
    Owner   Type  Dir         Value  Name
         4  bit   RW          FALSE  conv-float-s32.0.clamp
         4  s32   RO              0  conv-float-s32.0.time
         4  s32   RW              0  conv-float-s32.0.tmax
    
    ... snippage ...
    
    Exported Functions:
    Owner   CodeAddr  Arg       FP   Users  Name
     00004  fc0a9000  fc0630b8  YES      0   conv-float-s32.0
    ... snippage ...
    

    Achtung!

    • The module name uses underscores as separators: loadrt conv_float_s32
    • The function name uses h-y-p-h-e-n-s as separators: conv-float-s32.0
    • Unlike in the Linux kernel, the two characters are not equivalent

    Add the HAL Module to the Conversion Script

    The hal-write.ulp script contains a table of all the module names, so you must update the script in parallel with the hal-config.lbr Eagle library.

    However, you can create an Eagle device that is not a HAL module by omitting it from the script. In that case, the Eagle device name will become part of the net names that define and interconnect the pins, but the script will not create a statement to load a module. For example, the hal_input userspace program creates a set of pins for each input device that start with input.n, but there’s no corresponding HAL module. I’ll put up an example of all this in a bit.

    Create a Schematic Symbol

    • The name of the symbol is not critical: CONVERT.sym
      • use either dashes or hyphens as you prefer
    • The >NAME string must be on layer 95-Names
    • No need for a >VALUE string, but put it on layer 96-Values if present
    • HAL pins become symbol pins
      • Use the HAL pin name, with hyphens
      • Set Visibility to Pin
      • Set Direction to in / out / io to match the HAL description
      • Set Function to None to indicate an ordinary net connection
    • Verify the pins against the HAL device!

    Create a HAL Schematic Device

    • The new device name must match the HAL module name, with underscores, as entered in the conversion script table
      • CONV_FLOAT_S32.dev
    • Set the Prefix to the HAL function name, plus a trailing period, with hyphens
      • CONV-FLOAT-S32.
    • Create the Description using copy-and-paste from the HTML source: use the man page in the LinuxCNC doc
      • Ctrl-U in Firefox reveals the HTML source, Ctrl-A and Ctrl-C, flip windows, then Ctrl-V
      • Delete all the boilerplate at the top, leave the centered Title, ditch the reference links
    • Add the symbol you created earlier or reuse an existing symbol
      • Set the symbol NAME to a single underscore: _
      • Change the Add level to must
    • Add a PIN_FUNCTION symbol to the device
      • Change the symbol name from G$1 (or whatever) to a single period: .
      • Change the Add Level to must
    • Add PIN_PARAMETER symbols as needed
      • Change the symbol name from G$1 (or whatever) to the parameter name preceded by a single period: .CLAMP
      • Change the Add Level to request
      • Change the Direction as needed
    • Add the DUMMY physical package, then connect all the pins to pads

    Create a non-HAL Schematic Device

    • The new device name may be anything that’s not in the conversion script table
    • The Prefix must match the desired pin names, plus a trailing period. For hal_input pins:
      • INPUT.
    • Create the Description as above
    • Add the symbol you created earlier
      • Set the symbol NAME to a single underscore: _
      • Change the Add level to must
    • Do not add a PIN_FUNCTION symbol, because it has no corresponding module
    • Add PIN_PARAMETER symbols as needed
      • Change the symbol name from G$1 (or whatever) to the parameter name preceded by a single period: .CLAMP
      • Change the Add Level to request
      • Change the Direction as needed
    • Add the DUMMY physical package, then connect all the pins to pads

    Devices may have multiple Symbols, with different Add Level options; can seems appropriate. As nearly as I can tell, you must name each Symbol as a suffix to the full name to differentiate them within the Device; I use a hyphen before the suffix, so that -KEYS generates INPUT.0-KEYS. Those suffixes don’t appear elsewhere in the generated HAL configuration file.

    Save the library, update it in the schematic editor (Library → Update ...), and you’re set.

    Although it’s tempting, do not include a version number in the library file name, because Eagle stores the file name inside the schematic file along with the devices from that file. As a result, when you bump the library version number and use devices from the new library file, the schematic depends on both library files and there’s no way within Eagle to migrate devices from one library to the other; you must delete the existing devices from the schematic and re-place them from the new library. Or you can do like I did: hand-edit the XML fields inside the library file.

    Eagle HAL Device
    Eagle HAL Device

    You’ll almost certainly drive this procedure off the rails, so let me know what I’ve screwed up. It does, in fact, work wonderfully well and, as far as I’m concerned, makes HAL usable, if only because HAL is a write-only language to start with and now you need not read it to modify it.

  • HB-415M Stepper Driver Heatsinking: Lack Thereof

    Just to see what’s inside, I took those HB-415M drivers apart. They’re not all identical inside:

    HB-415M Driver - interior top
    HB-415M Driver – interior top

    The other side shouldn’t come as much of a surprise:

    HB-415M Driver heatsinking
    HB-415M Driver heatsinking

    Now, admittedly, I’ve applied a heatsink to the top of an epoxy package, but that DIP package has thermal tabs that should connect to the heatsink through a low-thermal-resistance path. A dab (!) of heatsink grease and what might be a thermally conductive plastic sheet atop the package seem, well, insufficient.

    The driver chip sports an Allegro A3992 marking that might be genuine. The datasheet goes into some detail as to how you should lay out the PCB; none of its recommendations made it into the finished product. In particular, the hulking current sense resistors surely have more inductance than you’d like.

    The resistor color code seems odd: black red red silver brown.

    HB-415M current sense resisors
    HB-415M current sense resisors

    Using black as the first band is unexpected, but it’s probably the only way to indicate a low-value resistance without printing the numbers: 0.22 Ω ±1%.

    Ah, well, the peak current isn’t as high as they claim, so it all probably works out in the end.