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: PC Tweakage

Remembering which tweaks worked

  • Atom D520: Config Files for Smoother Sherline Stepping

    The dual-core-ness of the D520, as set up there, allows a distinct improvement in the EMC2 BASE_PERIOD setting, which is exactly why I undertook this adventure.

    The 100 µs period I used on the Dell Dimension 4550 ensured the occasional long-latency burps wouldn’t cause much trouble… and they didn’t. The setup used the HAL step generator’s ability to supply a single pulse within one base period, so the maximum stepping rate was 1/100 µs = 10 k steps / second.

    However, that also determines the granularity of speed changes, so the controller can only drive the motors at multiples of the basic 100 µs without interpolating. For example, the four fastest step rates are:

    • 1/100 µs = 10 k step/sec
    • 1/200 µs =5 k step/sec
    • 1/300 µs = 3.3 k step/sec
    • 1/400 µs = 2.5 k step/sec

    The motors have 200 major steps / revolution and run in quarter-step mode: 800 microsteps / revolution. The axes have 20 turn-per-inch leadscrews, thus requiring 16 k step pulses per inch of travel.

    That means the corresponding traverse speeds are (step/sec) / (step/inch):

    • 10 k step/sec -> 0.625 in/sec = 37 in/min
    • 5 k step/sec -> 0.313 in/sec = 18.75 in/min
    • 3.3 k step/sec -> 0.206 in/sec = 12.37 in/min
    • 2.5 k step/sec -> 0.156 in/sec = 9.37 in/min

    Those are fairly large jumps between the speeds, which means the motor acceleration when the step rate changes is fairly high. HAL interpolates by bunching groups of pulses, but higher resolution is better.

    The Atom CPU has latencies under 10 µs, with no large burps that I’ve seen so far, so I set the BASE_PERIOD to 50 µs. However, that required changing the HAL step generator to produce a pulse during two successive periods (one high, one low) to keep the pulses wide enough for the motor controller. That means the highest step rate is still 10 k steps/sec and the top speed is still 37 inch/min.

    However, HAL can now adjust the period in smaller increments with lower acceleration between the jumps. The four fastest rates are now:

    • 1/100 µs = 10 k step/sec -> 0.625 in/sec = 37 in/min
    • 1/150 µs =6.7 k step/sec -> 0.417 in/sec = 25 in/min
    • 1/200 µs = 5 k step/sec -> 0.313 in/sec = 18.75 in/min
    • 1/250 µs = 4 k step/sec -> 0.250 in/sec = 15 in/min

    A stock Sherline CNC milling machine is rated for 22 inch/min (0.37 inch/sec) rapid motion on all three axes. That means the maximum step rate is

    • (0.37 inch/sec) * (16 k step/in) = 5.9 kHz

    Quite some years ago, I rebuilt my Sherline controller box to reduce its electrical and acoustic noise, then did a clean-room reimplementation of the firmware in the PIC microcontrollers. After the dust settled, my firmware could handle 8 k steps / sec, which works out to 0.5 in/sec = 30 in/min.

    That turns out to be slightly more aggressive than the whole lashup can tolerate; I can hear the motors take occasional hits as they miss the odd step at 30 inch/min.

    So I set the overall MAX_LINEAR_VELOCITY = 0.400 inch/sec = 24 inch/min, which is also the MAX_VELOCITY for both X and Y. The Z axis, as always, is happier with a bit slower top speed: 0.333 inch/sec = 20 inch/min. The maximum step rate is 0.4 x 16 k = 6.4 kHz, comfortably under the controller’s upper limit.

    The MAX_ACCELERATION for X and Y = 5.0 in/sec2, with Z at 3.0. STEPGEN_MAXACCEL for each axis is twice that; I have each axis set for a few mils of backlash compensation.

    With all that in mind, the changed configuration files look like this, with the others remaining as described there.

    Sherline.hal, with the new stepgen pulse specs

    # 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="0x378 out"
    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 0
    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 0
    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 0
    net adir => parport.0.pin-08-out
    net astep => parport.0.pin-09-out
    setp parport.0.pin-09-out-reset 0
    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 1
    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 1
    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 1
    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 1
    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
    

    Sherline.ini, with new periods, speeds, and accelerations

    # Ed Nisley - KE4ZNU
    # Just do not run stepconf ever again...
    
    [EMC]
    MACHINE = Sherline-XYZA
    DEBUG = 0
    RS274NGC_STARTUP_CODE = G21 G40 G49 G54 G80 G90 G92.1 G94 G97 G98
    
    [DISPLAY]
    DISPLAY = axis
    EDITOR = gedit
    GEOMETRY = AXYZ
    POSITION_OFFSET = RELATIVE
    POSITION_FEEDBACK = ACTUAL
    MAX_FEED_OVERRIDE = 3.0
    INTRO_GRAPHIC = /home/ed/emc2/configs/Sherline-XYZA/Sherline.gif
    INTRO_TIME = 3
    #PROGRAM_PREFIX = /mnt/bulkdata/
    PROGRAM_PREFIX = ~/emc2/nc_files
    #INCREMENTS = .1in .05in .01in .005in .001in .0005in .0001in
    INCREMENTS = 10 mm, 1 mm, 0.1 mm, 90 deg, 45 deg, 10 deg
    
    [FILTER]
    PROGRAM_EXTENSION = .py Python Script
    py = python
    
    [TASK]
    TASK = milltask
    CYCLE_TIME = 0.010
    
    [RS274NGC]
    PARAMETER_FILE = emc.var
    
    [EMCMOT]
    EMCMOT = motmod
    SHMEM_KEY = 111
    COMM_TIMEOUT = 1.0
    COMM_WAIT = 0.010
    BASE_PERIOD = 50000
    SERVO_PERIOD = 1000000
    
    [HAL]
    HALUI=halui
    HALFILE = Sherline.hal
    HALFILE = custom.hal
    HALFILE = Logitech_Gamepad.hal
    POSTGUI_HALFILE = custom_postgui.hal
    
    [TRAJ]
    AXES = 4
    COORDINATES = X Y Z A
    MAX_ANGULAR_VELOCITY = 45.00
    DEFAULT_ANGULAR_VELOCITY = 36.0
    LINEAR_UNITS = inch
    ANGULAR_UNITS = degree
    CYCLE_TIME = 0.010
    DEFAULT_VELOCITY = 0.400
    MAX_LINEAR_VELOCITY = 0.400
    POSITION_FILE =	lastposition.txt
    NO_FORCE_HOMING = 1
    
    [EMCIO]
    EMCIO = io
    CYCLE_TIME = 0.100
    TOOL_TABLE = Sherline.tbl
    TOOL_CHANGE_AT_G30 = 1
    
    [AXIS_0]
    TYPE = LINEAR
    MAX_VELOCITY = 0.400
    MAX_ACCELERATION = 5.0
    STEPGEN_MAXACCEL = 10.0
    SCALE = 16000.0
    FERROR = 0.05
    MIN_FERROR = 0.01
    MIN_LIMIT = -1.0
    MAX_LIMIT = 9.5
    BACKLASH = 0.003
    HOME_IS_SHARED = 1
    HOME_SEQUENCE = 2
    HOME_SEARCH_VEL = 0.3
    HOME_LATCH_VEL = 0.016
    HOME_FINAL_VEL = 0.4
    HOME_OFFSET = 9.1
    HOME = 4.5
    
    [AXIS_1]
    TYPE = LINEAR
    MAX_VELOCITY = 0.400
    MAX_ACCELERATION = 5.0
    STEPGEN_MAXACCEL = 10.0
    SCALE = 16000.0
    FERROR = 0.05
    MIN_FERROR = 0.01
    MIN_LIMIT = -0.5
    MAX_LIMIT = 4.90
    BACKLASH = 0.003
    HOME_IS_SHARED = 1
    HOME_SEQUENCE = 1
    HOME_SEARCH_VEL = -0.3
    HOME_LATCH_VEL = -0.016
    HOME_FINAL_VEL = 0.4
    HOME_OFFSET = 0.0
    HOME = 4.0
    
    [AXIS_2]
    TYPE = LINEAR
    MAX_VELOCITY = 0.333
    MAX_ACCELERATION = 3.0
    STEPGEN_MAXACCEL = 6.0
    SCALE = 16000.0
    FERROR = 0.05
    MIN_FERROR = 0.01
    MIN_LIMIT = 0.0
    MAX_LIMIT = 6.930
    BACKLASH = 0.005
    HOME_IS_SHARED = 1
    HOME_SEQUENCE = 0
    HOME_SEARCH_VEL = 0.200
    HOME_LATCH_VEL = 0.016
    HOME_FINAL_VEL = 0.3
    HOME_OFFSET = 6.93
    HOME = 6.5
    
    [AXIS_3]
    TYPE = ANGULAR
    ###WRAPPED_ROTARY = 1
    MAX_VELOCITY = 40.0
    MAX_ACCELERATION = 250.0
    STEPGEN_MAXACCEL = 275.0
    SCALE = 160.0
    FERROR = 1
    MIN_FERROR = .25
    MIN_LIMIT = -999999999.9
    MAX_LIMIT =  999999999.9
    HOME_SEARCH_VEL = 0
    HOME_LATCH_VEL = 0
    HOME = 0.0
    

     

     

  • An Atom for the Sherline Milling Machine

    Somewhat against the recommendations of the experts on the EMC2 mailing list, I bought a Foxconn R30-D2 with an Intel Atom D520 from Newegg during a sale: add 2 GB of memory from Crucial, a spare SATA drive from my collection, and it’s ready to go. I also bashed a spare parallel printer port card into the box, although it isn’t really needed right now: unlike the Intel system board, Foxconn brings the on-board parallel port directly to the back panel.

    The Foxconn support site is a nightmare and was, AFAICT, dead for the first few weeks I had the box. The key fact to remember is that the -D2 part of the number specifies the system board / CPU, so the same downloads / BIOS updates apply to the R10, R20, R30, and R40 models. There is no new BIOS available to fix the “fan runs all the time” problem reported by so many people.

    I installed Ubuntu 10.04 LTS from the distro CD, then ran the EMC2 installation script. All that is routine, as described there. You probably want to install the EMC2 Live CD, though, and to get much the same result with less fiddling.

    Turn off Hyperthreading in the BIOS, which seems to make the RTAI real-time hypervisor happier. Under those conditions, the default install has an interrupt latency of about 13 µs.

    The Atom D520 is a dual-core processor and you can devote one core to EMC2’s real-time functions, thus eliminating much of the usual contention and interrupt latency. That works surprisingly well and is completely automagic after you add the isolcpus=1 kernel option to the appropriate line in /boot/grub/grub.cfg. Thusly:

    linux	/boot/vmlinuz-2.6.32-122-rtai root=UUID=57fe2b04-ffe4-4de3-a597-89bd4ed01018 ro  vga=758  noquiet nosplash isolcpus=1
    

    With that done, the latency drops down under 8 µs, which is entirely satisfactory. I can push it to 10 µs by doing stupid things: scrubbing a glxgears window over a Flash video in Firefox, for example.

    The catch is that the wonderful new grub2 bootloader rewrites its boot configuration file on the fly, based on a set of rules that, evidently, cannot apply different kernel configuration parameters to different kernels within the same partition. As a result, you must choose between:

    • Running stock Ubuntu on one core
    • Manually tweaking grub.cfg after every kernel update

    Given that an Atom isn’t exactly a blinding flash and a deafening report in the performance department, I opted for the second method. If Ubuntu was still using Legacy Grub, then I’d just tweak menu.lst and be done with it. This is, I suppose, progress.

    Memo to Self: Adjust grub.cfg every mumble time.

    [Update: There’s now a fix for that, as described in the EMC2 wiki. Go for it!]

  • Peltier Cooler Test

    This Peltier cooler just emerged from a pile o’ stuff on the Electronics Workbench, so I combined it with a scrap CPU heatsink (using plain old water as “thermal grease”) and fired it up to get some quick numbers for future reference.

    Peltier cooler test lashup
    Peltier cooler test lashup

    It draws 3 A (the bench supply’s current limit) at 5 V. The cold side got down to 19 °F with the hot side at 75 °F: ΔT = 56 °F.

    That’s with zero thermal load, other than whatever arrives from plain old air and those two plastic clamps. It looks like a nice one, so it’s maybe 10% efficient and could pump a watt, barely enough to cool a simple circuit.

    Freezes a drop of water just fine, though.

    The I-V curve is nearly bar-straight over the first five volts: call it 620 mΩ. The thing would draw 7.5 A at 12 V, call it 90 W, and could pump maybe a whopping 9 W from the cold side.

    Actually getting good numbers would require some serious work that I’m not up for. In particular, everything has a serious temperature coefficient, so nothing would be the way it looks. I have doubts about the efficiency guesstimate; I’d like to actually measure that sometime.

    But it confirms my opinion of Peltier coolers between hundred-watt CPUs and water-cooled heatsinks: pure delusion.

  • Trust Multimedia Mouse vs xorg.conf

    This is the xorg.conf stanza required for a Trust MI-7700R multimedia mouse to set default left-hand use:

    Section "InputClass"
        Identifier      "Trust MM Mouse"
        MatchProduct    "Trust Mouse 15206"
        Option          "SendCoreEvents" "True"
        Option          "ButtonMapping" "3 2 1 4 5 6 7 8 9 10"
    EndSection
    

    And then it Just Worked, including horizontal scrolling.

    I can’t vouch for the multimedia functions, though.

    Memo to Self: Weirdly, the AA cells are in parallel, not series. Put them in “normally” and you get a dead short across a 3-V battery!

    Maybe that’s why it’s obsolete?

  • Refurb HP w2408h Monitor Factory Menu

    A year or so ago I picked up a refurbished HP w2408h monitor that’s been entirely satisfactory, although the backlight now seems to flicker occasionally. In the course of enabling the backlight sensor to see if that changes anything, I came across this useful bit of information about enabling the Factory Mode menu (lightly edited for clarity):

    1. Make sure you have video on your current input.
    2. Then turn off monitor.
    3. Hold down the “Menu”  and  ” +” keys while turning OFF/ON REAR Power switch. If monitor does not have rear power switch (ex. w2408) then just do with front power switch.
    4. Bring up OSD and scroll up/down to “F” letter at one corner of the OSD window.
    5. Press Menu/select button to enter Factory menu.
    6. Scroll down and turn off BurnIn.
    7. Scroll back up to “Exit” menu.
    8. Cycle power with front power button.

    The menu isn’t particularly useful to mere mortals, although it does show total power-on hours (3700, IIRC) and some other settings. It seems the refurb shop shipped some of the monitors with Burn-In mode enabled, much to the confusion of purchasers.

    Makes you wonder what other Easter Eggs lie in wait, doesn’t it?

  • Microsoft Comfort Curve Keyboard Cleanout

    Pin punch in keycap stem
    Pin punch in keycap stem

    Comes a time in the life of every keyboard when you must simply tear it apart to clean out the crud. I’ve been using a Microsoft Comfort Curve keyboard for several years and it’s worked well, but the grunge finally exceeded even my lax standards.

    A handful of screws secures the bottom cover; the shortest screws run down the middle. Surprisingly, the giant HEALTH WARNING label doesn’t cover any screws. A row of gentle snap latches along the edges holds the covers together; ease them apart with a small screwdriver or your fingernails.

    The lower cover holds the crosspoint matrix under a giant silicone rubber spring mat, with the USB interface board to the upper left. I left those in place, as the top cover captured nearly all the crud.

    The keycaps have stems that slide in guide tubes molded into the top cover, with triangular latches that both secure the stem and prevent it from rotating. I used a small pin punch to push the keycaps out, as shown in the top picture; the punch much be small enough to allow the latches to bend inward as they clear the notches.

    Keycap retaining latches
    Keycap retaining latches

    The larger keys have equalizing wire bails that latch under guides molded into the top cover. They’ll slide right out, but don’t shove the pin punch too far too fast.

    Keycaps with equalizing wires
    Keycaps with equalizing wires

    Many of the keycap stems have ridges along their length to ensure each one fits only in its proper position; the triangular latches also have different orientations. This view shows the numeric pad (from the “screen” side of the keyboard) with a variety of coded guide tubes, wire bail guides, and the surprisingly deep tub underneath the keycaps that may capture much of the inevitable liquid spill and route it out the drain hole near the far edge.

    Keyboard top panel
    Keyboard top panel

    I tossed the keycaps and top cover in the dishwasher, which did a wonderful job of cleaning them out. A dab of silicone grease on the wire bail contact points should keep them sliding freely.

    Reassembly is in reverse order, although I defy you to put all the keycaps back in their proper places without referring to another keyboard…

  • Foxconn R20-D2 Case vs. Optical Drive: Button Padding

    Extended optical drive button
    Extended optical drive button

    So I stuck a CD-RW drive into the Foxconn Atom box and discovered that the pushbutton on the front panel doesn’t move quite far enough to actually hit the corresponding button on the drive.

    Popped another drive off the heap and tried it out, just for grins, with the same result. Evidently the cute little ribbed back on the silvered panel button (near the bottom of the picture) isn’t quite long enough.

    Solution: a bit of rubberized high-traction tape stuck to the drive button (near the top of the picture).

    This is a black-on-black situation, so I pushed the contrast enough that you can actually see it.