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.

Author: Ed

  • Schauer Solid State Battery Charger: Digital Meter Retrofit

    Schauer Solid State Battery Charger: Digital Meter Retrofit

    The Forester’s battery has been on life support from an ancient Schauer “Solid State” charger (which may have Come With The House™) for the last year:

    Schauer battery charger - analog ammeter
    Schauer battery charger – analog ammeter

    A remote Squidwrench session provided an opportunity to replace its OEM ammeter with a cheap volt-amp meter:

    Schauer battery charger - digital meter
    Schauer battery charger – digital meter

    The charger is “solid state” because it contains silicon electronics:

    Schauer battery charger - solid state components
    Schauer battery charger – solid state components

    That’s an SCR implanted in the aluminum heatsink. The other side has a Motorola 18356 house number, a date code that might be 523, and the word MEXICO. The company now known as NXP says Motorola opened its Guadalajara plant in 1969, so they could have built the SCR in either 1973 or 1975; it’s not clear who manufactures what these days.

    The black tubing contains at least one part with enough value to justify the (presumably) Kovar lead; nowadays, it would be a “gold tone” finish. It’s probably a Zener diode setting the trickle-charging voltage, joined to the resistor lead in the crimped block. I don’t know if the glass diode is soldered to the Zener, but I’m reasonably sure if the third lead came from a transistor tucked inside the sleeve, we’d read about it on the charger’s front cover.

    In an ideal world, a digital meter would fit into a matching rectangular hole in the front panel, but that’s not the world we live in. After wrestling my gotta-make-a-solid-model jones to the floor, I got primal on a random slab of soft-ish plastic sheet:

    Schauer battery charger - bezel nibbling
    Schauer battery charger – bezel nibbling

    There’s nothing like some bandsaw / belt sander / nibbler action to jam a square peg into a round hole:

    Schauer battery charger - bezel test fit
    Schauer battery charger – bezel test fit

    It’s actually a firm press fit; whenever something like that happens, you know the project will end well.

    Hot melt glue FTW:

    Schauer battery charger - digital meter wiring
    Schauer battery charger – digital meter wiring

    The new meter’s (heavy) red-black leads go to the same terminals as the old meter’s wires, paying attention to the polarity. I splurged with insulated QD terminals on the old wires where a joint was needed.

    The meter’s thin red lead expects to see a power supply under 50 V with no particular regulation requirements, so I used the same flying-component design as the rest of the charger:

    Schauer battery charger - meter power supply
    Schauer battery charger – meter power supply

    The meter draws basically no current, at least on the scale of an automotive battery charger, so the 220 µf cap holds pretty nearly the peak 18 V half-wave rectified from the center tap by a 1N5819 Schottky diode.

    Those two squares riveted to the back panel are genuine selenium rectifiers, from back in the day when silicon power diodes weren’t cheap and readily available. They also limit the charger’s peak current and have yet to emit their incredibly foul stench upon failure; you always know exactly what died when that happens.

    Selenium rectifiers were pretty much obsolete by the early 1970s, agreeing with a 1973 date code. Schauer might have been working through their stockpile of obsolete rectifiers, which would have been sunk-cost-cheap compared to silicon diodes.

    The meter’s thin black lead goes to the power supply common point, which turns out to be where those rectifiers meet. The larger black wire goes off to the meter’s fat black lead on the other side of the aluminum heatsink, joining it in a new insulated QD terminal.

    The meter’s thin yellow wire is its voltage sense input, which gets soldered directly to the hot lead of the SCR.

    The meter indicates DC voltages and currents, which definitely isn’t the situation in the 100 Ω power resistor shown in the second picture.

    The voltage:

    Schauer battery charger - voltage waveform
    Schauer battery charger – voltage waveform

    And the current at 20 mA/div, showing why silicon replaced selenium:

    Schauer battery charger - current waveform
    Schauer battery charger – current waveform

    Yes, the current does go negative while the rectifiers figure out what to do next.

    The charger seems a little happier out in the garage:

    Schauer battery charger - in use
    Schauer battery charger – in use

    The battery holds the voltage steady at 13.7 V, with the charger producing 85 mV blips every second or so:

    Schauer battery charger - float V pulse
    Schauer battery charger – float V pulse

    Those blips correspond to 3 A pulses rammed into the battery:

    Schauer battery charger - float A pulse - 1 A-div
    Schauer battery charger – float A pulse – 1 A-div

    They’re measured across a 1 Ω series resistor that’s surely limiting the maximum current: 18 V from the transformer minus 13.7 V on the battery minus other IR losses doesn’t leave room for anything more than 3 V across the resistor. I wasn’t going to haul the Tek current probes out to the garage just for the occasion.

    Opening the Forester’s door to turn on all its LED interior lights bumps the meter to about 1 A, although the truth is more complicated:

    Schauer battery charger - loaded A pulse - 1 A-div
    Schauer battery charger – loaded A pulse – 1 A-div

    The average current is, indeed, just under 1 A, but in this situation the meter’s cool blue number seems more like a comfort indicator than anything particularly reliable.

    All I really wanted from the meter was an indication that the trickle charger was trickling, so I disconnected Tiny Scope, declared victory, and closed the garage door.

  • Blog Impulse Response: Water Heater

    Blog Impulse Response: Water Heater

    Somebody posted a Reddit comment linking to my post about a sensibly implemented water heater anode rod, with predictable results:

    Blog Impulse - 2021-03
    Blog Impulse – 2021-03

    Reddit’s New Hotness has a half-life well under a day, although a steady trickle of incoming traffic will continue forever: The Internet Never Forgets.

    Protip: forcing Reddit URLs to old.reddit.com eliminates the user-hostile site layout. Manual tweaking suffices for my very few visits; you can find browser extensions for on-the-fly rewriting.

  • Discrete LM3909 Blue LED: Off at 1.0 V

    Discrete LM3909 Blue LED: Off at 1.0 V

    The blue LED inside the radome got fainter as the alkaline AA cells faded away, but remained visible in a dark room until the discrete LM3909 circuitry stopped oscillating with the battery at 1.0 V. One of the cells had flatlined, with the other supplying what little current was needed.

    The circuitry restarted with a pair of weak alkalines applying 2.4 V across the bus bars:

    LM3909 Blue - 2.4 V alkaline
    LM3909 Blue – 2.4 V alkaline

    The LED waveform shows it needs about 2 V:

    LM3909 Blue - 2.4 V alkaline
    LM3909 Blue – 2.4 V alkaline

    It’s barely visible in normal room light and strikingly bright at night.

  • Tour Easy Rear Fender Bracket: More Cable Clearance

    Tour Easy Rear Fender Bracket: More Cable Clearance

    Most likely due to the fiddling around the larger rear brake noodle, the 3D printed bracket holding the fender to the frame failed:

    Tour Easy Rear Fender Bracket - failed joint
    Tour Easy Rear Fender Bracket – failed joint

    Hey, it lasted for six years.

    Making another one just like the other one, but with a little more clearance for the brake cable fittings, required a few tweaks to the solid model:

    Rear Fender Bracket - more clearance
    Rear Fender Bracket – more clearance

    It’s slightly less chunky and holds the fender a bit closer to the tire:

    Tour Easy Rear Fender Bracket - new vs old clearance
    Tour Easy Rear Fender Bracket – new vs old clearance

    The piece over on the left cupping the fender wasn’t broken, so I scuffed up the mating surfaces, applied a layer of JB Plastic Bonder (my new go-to adhesive for printed stuff), clamped it overnight, and it looked OK.

    While that was curing, I shortened the screw holding the clamp to the bike frame:

    Tour Easy Rear Fender Bracket - cutoff wheel dust collection
    Tour Easy Rear Fender Bracket – cutoff wheel dust collection

    The shop vac nozzle does a great job of collecting all the abrasive dust; highly recommended.

    Because I had a dollop of adhesive left over, I applied a 1.8 mm drill (from a set of metric bits I’d been meaning to buy for far too long) to the screw:

    Tour Easy Rear Fender Bracket - screw drilling
    Tour Easy Rear Fender Bracket – screw drilling

    And glued a snippet of pretty blue PETG filament in the hole:

    Tour Easy Rear Fender Bracket - frame screw PETG insert
    Tour Easy Rear Fender Bracket – frame screw PETG insert

    As far as I can tell, this will have no effect on the screw’s goodness, but it makes me feel better about crunching it onto the frame.

    Installation goes like you’d expect and there’s now enough clearance to keep the brake hardware off the bracket:

    Tour Easy Rear Fender Bracket - installed
    Tour Easy Rear Fender Bracket – installed

    I replaced the boot while installing the larger noodle; perhaps I should have trimmed most of it away.

    The riding season is upon us!

  • Juki JC-001 Foot Control: Resolving Uncommanded Thread Cutting

    Juki JC-001 Foot Control: Resolving Uncommanded Thread Cutting

    Mary’s most recent quilt arranges her color choices in Judy Niemeyer’s Stellar Snowflake pattern:

    Stellar Snowflake Quilt - in progress
    Stellar Snowflake Quilt – in progress

    Her Juki TL-2010Q sewing machine has a built-in thread cutter activated by pressing down on the heel end (to the left) of the foot control:

    Juki JC-001 Foot Control - overview
    Juki JC-001 Foot Control – overview

    The machine had previously performed “uncommanded” thread cuts on other projects, but the many short segments in this pattern triggered far too many cuts. I aimed a camera at her foot on the pedal and she was definitely not pressing down with her heel when the cutter fired.

    In point of fact, the thread cutter fired when she was just starting a new segment, where she was gently pressing down on the toe end (to the right) of the pedal to start at the slowest possible speed.

    For completeness, the underside of the pedal:

    Juki JC-001 Foot Control - bottom
    Juki JC-001 Foot Control – bottom

    There are no screws holding it together. The top cover pivots on a pair of plastic pegs sticking out from the base near the middle of the cable spool. Disassembly requires jamming a pair of husky Prydrivers in there and applying enough brute force to pry both sides outward farther than you (well, I) think they should bend. This will scar the bottom of the case, but nobody will ever notice.

    The foot control cable plugs into the machine through what looks like an ordinary two-conductor coax plug, just like the ones on wall warts delivering power to gadgets around the house. In this day and age, the communications protocol could be anything from a simple resistor to a full-frontal 1-Wire encrypted data exchange.

    Based on the old Kenmore foot pedals, I expected a resistive control and, indeed, a simple test gave these results:

    • Idle = 140 kΩ
    • Heel pressed (cut) = 46 kΩ
    • Toe slight press (slow running) = 20 kΩ
    • Toe full press (fast running) = 0.2 kΩ

    We can all see where this is going, but just to be sure I pried the top off the control to reveal the insides:

    Juki JJC-001 Foot Control - interior
    Juki JJC-001 Foot Control – interior

    The two cylindrical features capture the ends of a pair of stiff compression springs pressing the top of the pedal upward.

    The small, slightly stretched, extension spring in the middle pulls the slider to the left (heelward), with a ramp in the top cover forcing it to the right (toeward) as the speed increases.

    The top cover includes a surprisingly large hunk of metal which may provide enough mass to make the pedal feel good:

    Juki JC-001 Foot Control - top underside
    Juki JC-001 Foot Control – top underside

    The ramp is plastic and the slider has a pair of nylon (-ish) rollers, so there’s not much friction involved in the speed control part of motion. Yes, this is oriented the other way, with the heel end over on the right.

    The metal insert pivots in the serrated plastic section near the middle, with the two husky extension springs visible on the left holding it against the plastic cover. The two rectangular features on the left rest under the plastic flanges on the right of the base to prevent the metal insert from moving upward, so pressing the heel end down pulls the cover away from the insert to let the slider rollers move toward the right end of the ramp, into roughly the position shown in the interior view.

    A closeup look at the slider shows the rollers and the PCB holding all of the active ingredients:

    Juki JC-001 Foot Control - Resistor Slider
    Juki JC-001 Foot Control – Resistor Slider

    I think the trimpot adjusts the starting resistance for the slider’s speed control travel. It is, comfortingly, roughly in the middle of its range.

    A top view shows the fixed 140 kΩ resistor (brown yellow black orange, reading from the right) setting the idle resistance:

    Juki JC-001 Foot Control - PCB top view
    Juki JC-001 Foot Control – PCB top view

    Measuring the resistance while gently teasing the slider showed that it’s possible to produce a resistance higher than 20 kΩ and lower than 140 kΩ, although it requires an exceedingly finicky touch and is completely unstable.

    Before looking inside the pedal, we thought the cutter was triggered by an actual switch closure with the heel end most of the way downward against those stiff springs, which meant the failure came from a switch glitch. Now, we think the earlier and infrequent uncommanded thread cuts trained Mary to start very carefully to be very sure she wasn’t glitching the cutter’s hypothetical switch. Of course, her gradually increasing toe pressure moved the slider very slowly through its idle-to-running transition: she was optimizing her behavior to produce exactly the resistance required to trigger the cutter.

    She now sets the machine’s speed control midway between Turtle and Hare to limit its top speed, presses the pedal with more confidence to minimize the time spent passing through the danger zone, and has had far few uncommanded thread cuts. We think it’s now a matter of retraining her foot to stomp with conviction; there’s no hardware or software fix.

    I’m sure Juki had a good reason to select the resistances they did, but I would have gone for a non-zero minimum resistance at the fast end of travel and a zero-resistance switch to trigger the cutter.

  • Adhesive vs. Concrete: Tenacity Thereof

    Adhesive vs. Concrete: Tenacity Thereof

    Sometimes, sticky labels hold on forever:

    Faded NO PARKiNG sign
    Faded NO PARKiNG sign

    It’s standing near what was once the Red Oaks Mill dam, which continues to disintegrate:

    Red Oaks Mill Dam - 2021-02-25
    Red Oaks Mill Dam – 2021-02-25

    Sixteen years ago, the dam was in better shape:

    Red Oaks Mill Dam - 27 Feb 2005
    Red Oaks Mill Dam – 27 Feb 2005

    Maybe the sign was shiny-new back then?

  • The Joggy Thing vs. LinuxCNC 2.8

    The Joggy Thing vs. LinuxCNC 2.8

    After getting the Sherline mostly working with LinuxCNC 2.8 and the Mesa 5I25 FPGA card, I updated the HAL code turning the Logitech gamepad into The Joggy Thing:

    Sherline Mill - Logitech Gamepad Joggy Thing
    Sherline Mill – Logitech Gamepad Joggy Thing

    This required significantly more effort than I expected, mainly because I can no longer edit the Eagle schematics defining the HAL file. In the intervening years, Autodesk bought the Eagle EE CAD program, converted it into a subscription service, sutured it onto their Fusion 360 package, and priced the result far beyond my toy budget. While they do offer a free tier limited to “individuals for personal, non-commercial use”, schematics with only two sheets pretty much wipes out its value.

    Because the EESchema part of Kicad can export its netlists as XML files, someone experienced in wrangling XSLT, perhaps using Python + lxml, could recreate the function of the Eagle ULP with Kicad schematics / netlists. I am not, however, that person, although it would certainly be a Learning Experience™ of the first water.

    So I updated the automatically generated HAL file on hard mode with a text editor, which, given HAL’s limited debugging support, somewhat resembles juggling a greasy bowling ball, a full-throttle chainsaw, and a squalling baby in a poopy diaper.

    The major conceptual problem was LinuxCNC’s recent separation of “axes” from “joints”, with resulting changes in both nomenclature and control. Eventually, I found some key hints in a very recent update to a LinuxCNC wiki entry describing a similar Logitech gamepad interface.

    The basic Joggy Thing logic remains the same, with “analog” values from the joysticks now presented to both the halui.axis and halui.joint controls. The new trick of holding the pre-startup values (presumably zeros) with feedback around a multiplexer qualifies as a Moby Hack preventing a startup glitch from triggering an error having something to do with an E-stop.

    The machine still runs away on X and Z at full throttle instantly after tapping the Machine-On button for the first time in the morning. Come to find out the gamepad starts up with all four joysticks jammed at -1 until the first activation of any axis or button, which I’m sure it always did, but something in HAL’s bowels now responds differently. More work will be required, although I think the simplest solution will involve holding everything inert until the logic sees a specific gamepad button.

    The LinuxCNC HAL code as a GitHub Gist:

    # HAL for Logitech Joggy Thing
    ####################################################
    # Load realtime and userspace modules
    loadusr -W hal_input -KA Dual
    #loadrt logic count=1 personality=0x104
    loadrt constant count=13
    loadrt and2 count=17
    loadrt conv_float_s32 count=1
    loadrt flipflop count=4
    loadrt mux2 count=1
    loadrt mux4 count=5
    loadrt not count=8
    loadrt or2 count=13
    loadrt scale count=7
    loadrt timedelay count=1
    loadrt toggle count=1
    ####################################################
    # Hook functions into threads
    #addf logic.0 servo-thread
    addf constant.0 servo-thread
    addf constant.1 servo-thread
    addf constant.2 servo-thread
    addf constant.3 servo-thread
    addf constant.4 servo-thread
    addf constant.5 servo-thread
    addf constant.6 servo-thread
    addf constant.7 servo-thread
    addf constant.8 servo-thread
    addf constant.9 servo-thread
    addf constant.10 servo-thread
    addf constant.11 servo-thread
    addf constant.12 servo-thread
    addf and2.0 servo-thread
    addf and2.1 servo-thread
    addf and2.2 servo-thread
    addf and2.3 servo-thread
    addf and2.4 servo-thread
    addf and2.5 servo-thread
    addf and2.6 servo-thread
    addf and2.7 servo-thread
    addf and2.8 servo-thread
    addf and2.9 servo-thread
    addf and2.10 servo-thread
    addf and2.11 servo-thread
    addf and2.12 servo-thread
    addf and2.13 servo-thread
    addf and2.14 servo-thread
    addf and2.15 servo-thread
    addf and2.16 servo-thread
    addf conv-float-s32.0 servo-thread
    addf toggle.0 servo-thread
    addf flipflop.0 servo-thread
    addf flipflop.1 servo-thread
    addf flipflop.2 servo-thread
    addf flipflop.3 servo-thread
    addf timedelay.0 servo-thread
    addf or2.0 servo-thread
    addf or2.1 servo-thread
    addf or2.2 servo-thread
    addf or2.3 servo-thread
    addf or2.4 servo-thread
    addf or2.5 servo-thread
    addf or2.6 servo-thread
    addf or2.7 servo-thread
    addf or2.8 servo-thread
    addf or2.9 servo-thread
    addf or2.10 servo-thread
    addf or2.11 servo-thread
    addf or2.12 servo-thread
    addf not.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 scale.0 servo-thread
    addf scale.1 servo-thread
    addf scale.2 servo-thread
    addf scale.3 servo-thread
    addf scale.4 servo-thread
    addf scale.5 servo-thread
    addf scale.6 servo-thread
    addf mux2.0 servo-thread
    addf mux4.0 servo-thread
    addf mux4.1 servo-thread
    addf mux4.2 servo-thread
    addf mux4.3 servo-thread
    addf mux4.4 servo-thread
    ####################################################
    # Set constants
    setp constant.0.value 0.1
    setp constant.1.value 20
    setp constant.2.value [TRAJ]MAX_LINEAR_VELOCITY
    setp constant.3.value [TRAJ]MAX_ANGULAR_VELOCITY
    setp constant.4.value 60
    setp constant.5.value 0.50
    setp constant.6.value 1.00
    setp constant.7.value 0.10
    setp constant.8.value 0.10
    setp constant.9.value 0.0
    setp constant.10.value -1.0
    setp constant.11.value 0.020
    setp constant.12.value 0.000
    ####################################################
    # Connect Modules with nets
    # both rear top buttons for e-stop, bottom right to reset
    net estop-a input.0.btn-top2 and2.0.in0
    net estop-b input.0.btn-base and2.0.in1
    net n_13 and2.0.out halui.estop.activate
    net reset-estop input.0.btn-base2 halui.estop.reset
    # button to start manual mode (probably not needed with 2.8)
    net manual-mode halui.mode.manual input.0.btn-base3
    net program-resume halui.program.resume input.0.btn-base4
    net n_14 or2.3.in0 input.0.btn-base5
    net n_15 or2.3.in1 input.0.btn-base6
    net n_16 toggle.0.in or2.3.out
    net n_17 conv-float-s32.0.out input.0.abs-x-flat input.0.abs-y-flat input.0.abs-z-flat input.0.abs-rz-flat
    net n_18 constant.1.out conv-float-s32.0.in
    net n_19 constant.4.out scale.0.gain
    net n_20 constant.5.out scale.1.gain
    net n_21 constant.6.out scale.2.gain
    net n_22 constant.7.out scale.3.gain
    net n_23 scale.4.gain constant.8.out
    net n_24 constant.0.out halui.axis.jog-deadband
    net n_42 or2.7.in0 input.0.abs-x-is-pos
    net n_43 or2.7.in1 input.0.abs-x-is-neg
    net n_44 or2.8.in0 input.0.abs-y-is-pos
    net n_45 or2.8.in1 input.0.abs-y-is-neg
    net n_46 or2.9.in0 input.0.abs-z-is-pos
    net n_47 or2.9.in1 input.0.abs-z-is-neg
    net n_48 or2.10.in0 input.0.abs-rz-is-pos
    net n_49 or2.10.in1 input.0.abs-rz-is-neg
    net n_51 constant.10.out scale.5.gain scale.6.gain
    net n_57 and2.1.out halui.axis.x.minus halui.joint.0.minus
    net n_58 and2.2.out halui.axis.x.plus halui.joint.0.plus
    net n_59 and2.3.out halui.axis.y.minus halui.joint.1.minus
    net n_60 and2.4.out halui.axis.y.plus halui.joint.1.plus
    net n_61 and2.5.out halui.axis.z.minus halui.joint.2.minus
    net n_62 and2.6.out halui.axis.z.plus halui.joint.2.plus
    net n_63 and2.7.out halui.axis.a.minus halui.joint.3.minus
    net n_64 and2.8.out halui.axis.a.plus halui.joint.3.plus
    # sort out jog speeds
    net az-buttons-active or2.1.out or2.12.in1
    net xy-buttons-active or2.5.out or2.12.in0
    net any-buttons-active or2.12.out mux4.0.sel0 timedelay.0.in
    net n_54 constant.11.out timedelay.0.on-delay
    net n_55 constant.12.out timedelay.0.off-delay
    net n_56 timedelay.0.out and2.1.in1 and2.2.in1 and2.3.in1 and2.4.in1 and2.5.in1 and2.6.in1 and2.7.in1 and2.8.in1
    net jog-crawl toggle.0.out mux4.0.sel1
    net knob-fast scale.1.out mux4.0.in0 scale.3.in
    net button-fast scale.2.out mux4.0.in1 scale.4.in
    net knob-crawl scale.3.out mux4.0.in2
    net button-crawl scale.4.out mux4.0.in3
    net jog-speed mux4.0.out halui.axis.jog-speed halui.joint.jog-speed
    net angular_motion or2.11.out mux2.0.sel
    net n_25 constant.2.out mux2.0.in0
    net n_26 constant.3.out mux2.0.in1
    net vel-per-second mux2.0.out scale.0.in
    net vel-per-minute scale.0.out scale.1.in scale.2.in
    net az-reset and2.14.out flipflop.2.reset flipflop.3.reset
    net xy-reset and2.10.out flipflop.0.reset flipflop.1.reset
    # hold jog speed unchanged until machine turns on
    # mux S&H from https://wiki.linuxcnc.org/cgi-bin/wiki.pl?Simple_Remote_Pendant
    net jog-mux-enable halui.machine.is-on mux4.1.sel1 mux4.2.sel1 mux4.3.sel1 mux4.4.sel1
    net axis-disabled-value constant.9.out mux4.1.in2 mux4.2.in2 mux4.3.in2 mux4.4.in2
    net x-analog mux4.1.out mux4.1.in0 mux4.1.in1 halui.axis.x.analog halui.joint.0.analog
    net y-analog mux4.2.out mux4.2.in0 mux4.2.in1 halui.axis.y.analog halui.joint.1.analog
    net z-analog mux4.3.out mux4.3.in0 mux4.3.in1 halui.axis.z.analog halui.joint.2.analog
    net a-analog mux4.4.out mux4.4.in0 mux4.4.in1 halui.axis.a.analog halui.joint.3.analog
    #net x-amp-enable logic.0.in-00
    #net y-amp-enable logic.0.in-01
    #net z-amp-enable logic.0.in-02
    #net a-amp-enable logic.0.in-03
    net x-buttons-active or2.4.out or2.5.in0
    net x-disable not.4.out and2.12.in1
    net x-enable flipflop.0.out not.4.in mux4.1.sel0
    net x-hat-minus or2.4.in1 input.0.abs-hat0x-is-neg and2.1.in0
    net x-hat-plus or2.4.in0 input.0.abs-hat0x-is-pos and2.2.in0
    net x-jog input.0.abs-x-position mux4.1.in3
    net x-knob-active or2.7.out not.0.in and2.9.in0
    net x-knob-inactive not.0.out and2.10.in0 and2.11.in0
    net x-set and2.9.out flipflop.0.set
    net y-buttons-active or2.6.out or2.5.in1
    net y-disable not.5.out and2.9.in1
    net y-enable flipflop.1.out not.5.in mux4.2.sel0
    net y-hat-minus or2.6.in1 input.0.abs-hat0y-is-neg and2.4.in0
    net y-hat-plus or2.6.in0 input.0.abs-hat0y-is-pos and2.3.in0
    net y-jog input.0.abs-y-position scale.5.in
    net y-jog-reversed scale.5.out mux4.2.in3
    net y-knob-active not.1.in or2.8.out and2.11.in1
    net y-knob-inactive not.1.out and2.10.in1
    net y-select and2.12.in0 and2.11.out
    net y-set flipflop.1.set and2.12.out
    net z-button-minus or2.2.in0 input.0.btn-thumb and2.5.in0
    net z-button-plus or2.2.in1 input.0.btn-top and2.6.in0
    net z-buttons-active or2.2.out or2.1.in1
    net z-disable not.6.out and2.16.in1
    net z-enable not.6.in flipflop.2.out mux4.3.sel0
    net z-jog input.0.abs-rz-position scale.6.in
    net z-jog-reversed scale.6.out mux4.3.in3
    net z-knob-active not.3.in or2.10.out and2.13.in0
    net z-knob-inactive not.3.out and2.15.in0 and2.14.in0
    net z-set and2.13.out flipflop.2.set
    net a-button-minus or2.0.in0 input.0.btn-joystick and2.7.in0
    net a-button-plus or2.0.in1 input.0.btn-thumb2 and2.8.in0
    net a-buttons-active or2.0.out or2.1.in0 or2.11.in1
    net a-disable not.7.out and2.13.in1
    net a-enable or2.11.in0 flipflop.3.out not.7.in mux4.4.sel0
    net a-jog input.0.abs-z-position mux4.4.in3
    net a-knob-active or2.9.out not.2.in and2.15.in1
    net a-knob-inactive not.2.out and2.14.in1
    net a-select and2.16.in0 and2.15.out
    net a-set flipflop.3.set and2.16.out
    view raw joggy.hal hosted with ❤ by GitHub