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

  • Homage Tektronix Circuit Computer: Laser Printed Scales

    Homage Tektronix Circuit Computer: Laser Printed Scales

    Given the proper command-line options, GCMC can produce an SVG image and, after some Bash fiddling and a bank shot off Inkscape, the same GCMC program I’ve been using to plot Homage Tektronix Circuit Computer decks can produce laser-printed decks:

    Tek CC - laser - detail
    Tek CC – laser – detail

    Pen-plotting on yellow Astrobrights paper showed how much ink bleeds on slightly porous paper, but laser-printing the same paper produces crisp lines:

    Tek CC - laser - yellow detail
    Tek CC – laser – yellow detail

    Laser printing definitely feels like cheating, but, for comparison, here’s a Genuine Tektronix Circuit Computer:

    Tek CC - genuine - detail
    Tek CC – genuine – detail

    Plotting the decks on hard mode was definitely a learning experience!

    Obviously, my cursor engraving hand remains weak.

  • KeyboardIO Atreus: LED Diffuser

    KeyboardIO Atreus: LED Diffuser

    After staring at the RGB LED I installed in my Atreus keyboard for a while, I converted the stub of a ¼-20 nylon screw into a light diffuser:

    Atreus keyboard - LED diffuser
    Atreus keyboard – LED diffuser

    It stands slightly proud of the surface plate so I can extract it without dismantling the whole keyboard again:

    Atreus keyboard - LED diffuser installed
    Atreus keyboard – LED diffuser installed

    I’ll eventually make a better-looking diffuser from a recently arrived translucent acrylic rod, but this will reduce the accumulation of fuzz inside the keyboard until the matching Round Tuit arrives.

  • Floor Lamp Rebasing

    Floor Lamp Rebasing

    The torchiere floor lamp in the sewing room suffered a catastrophic failure:

    Floor lamp - failed plastic base shell
    Floor lamp – failed plastic base shell

    Contrary to what you might think from seeing the shattered plastic base, we didn’t use the lamp as a club or battering ram. Apparently the designer expected the thin plastic surrounding the hole to withstand all the torque produced by the long pole against the cheap concrete / mortar / grout / whatever lump in the base. As we can recall, this lamp came to us from either a yard sale or a roadside debris harvest, so I suppose the hardware outlasted any reasonable expectation.

    The Basement Laboratory Warehouse disgorged the pole and base from a similar lamp, albeit sporting black paint and a smaller rod connecting its pole to its somewhat larger weight. Not being too fussy about decor, I embiggened the hole in the black base to fit the white lamp’s threaded rod:

    Floor lamp - enlarging replacement base
    Floor lamp – enlarging replacement base

    The dust on the base shows why you shouldn’t stand motionless in the Basement Laboratory for very long.

    The alert reader will have noted the cord passing through a strain relief grommet in the white base. Rather than dismantle the entire lamp, I just cut the cord, ran it through the new base weight, reinstalled the washer + nut, then crimped on a pair of solderless connectors:

    Floor lamp - cord splice
    Floor lamp – cord splice

    The new base doesn’t offer much in the way of attachment points, so I added a cable tie to keep the strain off the connectors:

    Floor lamp - cord strain relief
    Floor lamp – cord strain relief

    A strip of genuine 3M duct tape with double-thick adhesive now traps the cord inside that small channel and, given that the lamps spends most of its time standing quietly in a corner, the cord should be fine for long enough.

  • MTD Snowthrower Throttle Knob: Found!

    MTD Snowthrower Throttle Knob: Found!

    After the snow cleared and we ventured out again, the missing snowthrower throttle knob was sitting on the far reaches of the driveway:

    MTD Snowthrower Throttle Knob - crude repair
    MTD Snowthrower Throttle Knob – crude repair

    It’s a well-meaning, albeit totally ineffectual, expedient repair.

    I put a channel around the slot for the throttle shaft to mimic the original design:

    MTD Snowthrower Throttle Knob - fracture
    MTD Snowthrower Throttle Knob – fracture

    The fracture started at the end and worked its way back, loosening the knob’s grip on the shaft as it went:

    MTD Snowthrower Throttle Knob - pieces
    MTD Snowthrower Throttle Knob – pieces

    Should my replacement survive the next 13 years, it’ll likely outlive the rest of the snowthrower:

    Snowthrower throttle knob - installed
    Snowthrower throttle knob – installed

    If the original MTD choke knob didn’t have that fancy metal insert, I’d replace it just for pretty …

  • KeyboardIO Atreus: RGB LED Installation

    KeyboardIO Atreus: RGB LED Installation

    Having scouted out the territory inside the KeyboardIO Atreus, adding an LED requires taking it completely apart to drill a hole in the aluminum faceplate:

    Atreus keyboard - panel drilling
    Atreus keyboard – panel drilling

    Reattaching the plate to the PCB with only three screws allows marking the hole position on the PCB, which is much easier than pretending to derive the position from first principles:

    Atreus keyboard - LED marking
    Atreus keyboard – LED marking

    Despite appearances, I traced the hole with a mechanical pencil: black graphite turns shiny silvery gray against matte black soldermask. Also, the PCB trace is off-center, not the hole.

    Overlay the neighborhood with Kapton tape to protect the PCB from what comes next:

    Atreus keyboard - Kapton tape

    Snip a WS2812 RGB LED from a strip, stick it in place with eyeballometric alignment over the target, and wire it up:

    Atreus keyboard - LED wiring
    Atreus keyboard – LED wiring

    Despite the terrible reliability of WS2812 RGB LEDs mounted on PCB carriers, a different set on a meter of high-density flex tape have worked reasonably well when not thermally stressed, so I’ll assume this one arrived in good order.

    Aligning the LED directly under the hole required a few iterations:

    Atreus keyboard - LED positioning
    Atreus keyboard – LED positioning

    The iridescent green patch is a diffraction pattern from the controller chip’s internal circuitry.

    The data comes from MOSI, otherwise known as B2, down in the lower left corner:

    Atmel 32U4 - JTAG pins
    Atmel 32U4 – JTAG pins

    Actually lighting the LED now becomes a simple matter of software QMK firmware.

  • Makergear M2: Initial PrusaSlicer Configuration

    Makergear M2: Initial PrusaSlicer Configuration

    After replacing the nozzle and the filament drive body on the M2, I figured I might as well throw all the balls in the air and switch to PrusaSlicer for all my slicing needs. It’s built from the Slic3r project, gaining features used by Prusa’s printers / filaments and a considerably improved UI, with a full-time paid staff working on it:

    PrusaSlicer screenshot
    PrusaSlicer screenshot

    Of course, I immediately turned on Expert mode.

    CAUTION: My heavily customized start_gcode will crash your M2, because you haven’t relocated the Z-axis switch, haven’t calibrated Z=0 at the platform surface, and don’t put the XY=0 origin in the center of the platform.

    You have been warned: consider this as a serving suggestion, not a finished product.

    Because everything I design looks more-or-less like a bracket, I absolutely don’t care about surface finish, and I’m content to use only a few colors of PETG from a single supplier, a single Slic3r configuration has sufficed for nearly everything I print. A few manual tweaks for specific models, perhaps to change the number of perimeters or the infill percentage, handle the remaining cases.

    With all that in mind, here’s the current result of File → Export → Export Config as a GitHub Gist:

    # generated by PrusaSlicer 2.2.0+linux-x64 on 2021-01-01 at 13:33:03 UTC
    avoid_crossing_perimeters = 0
    bed_custom_model =
    bed_custom_texture =
    bed_shape = -100x-125,100x-125,100×125,-100×125
    bed_temperature = 90
    before_layer_gcode =
    between_objects_gcode =
    bottom_fill_pattern = hilbertcurve
    bottom_solid_layers = 3
    bottom_solid_min_thickness = 0
    bridge_acceleration = 0
    bridge_angle = 0
    bridge_fan_speed = 100
    bridge_flow_ratio = 1
    bridge_speed = 50
    brim_width = 0
    clip_multipart_objects = 1
    colorprint_heights =
    complete_objects = 0
    cooling = 1
    cooling_tube_length = 5
    cooling_tube_retraction = 91.5
    default_acceleration = 0
    default_filament_profile = ""
    default_print_profile =
    deretract_speed = 0
    disable_fan_first_layers = 6
    dont_support_bridges = 1
    draft_shield = 0
    duplicate_distance = 6
    elefant_foot_compensation = 0
    end_filament_gcode = "; Filament-specific end gcode \n;END gcode for filament\n"
    end_gcode = ;– PrusaSlicer End G-Code for M2 starts –\n; Ed Nisley KE4NZU – 15 November 2013\nG1 Z160 F2000 ; lower bed\nG1 X135 Y100 F30000 ; nozzle to right, bed front\nM104 S0 ; drop extruder temperature\nM140 S0 ; drop bed temperature\nM106 S0 ; bed fan off\nM84 ; disable motors\n;– PrusaSlicer End G-Code ends –\n\n
    ensure_vertical_shell_thickness = 1
    external_perimeter_extrusion_width = 0
    external_perimeter_speed = 50%
    external_perimeters_first = 0
    extra_loading_move = -2
    extra_perimeters = 1
    extruder_clearance_height = 20
    extruder_clearance_radius = 20
    extruder_colour = ""
    extruder_offset = 0x0
    extrusion_axis = E
    extrusion_multiplier = 0.95
    extrusion_width = 0.4
    fan_always_on = 0
    fan_below_layer_time = 15
    filament_colour = #29B2B2
    filament_cooling_final_speed = 3.4
    filament_cooling_initial_speed = 2.2
    filament_cooling_moves = 4
    filament_cost = 25
    filament_density = 0.95
    filament_deretract_speed = nil
    filament_diameter = 1.72
    filament_load_time = 0
    filament_loading_speed = 28
    filament_loading_speed_start = 3
    filament_max_volumetric_speed = 0
    filament_minimal_purge_on_wipe_tower = 15
    filament_notes = ""
    filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6"
    filament_retract_before_travel = nil
    filament_retract_before_wipe = nil
    filament_retract_layer_change = nil
    filament_retract_length = nil
    filament_retract_lift = nil
    filament_retract_lift_above = nil
    filament_retract_lift_below = nil
    filament_retract_restart_extra = nil
    filament_retract_speed = nil
    filament_settings_id = "M2 Esun PETG"
    filament_soluble = 0
    filament_toolchange_delay = 0
    filament_type = PET
    filament_unload_time = 0
    filament_unloading_speed = 90
    filament_unloading_speed_start = 100
    filament_vendor = (Unknown)
    filament_wipe = nil
    fill_angle = 45
    fill_density = 25%
    fill_pattern = 3dhoneycomb
    first_layer_acceleration = 0
    first_layer_bed_temperature = 90
    first_layer_extrusion_width = 0
    first_layer_height = 0.25
    first_layer_speed = 15
    first_layer_temperature = 250
    gap_fill_speed = 25
    gcode_comments = 0
    gcode_flavor = marlin
    gcode_label_objects = 0
    high_current_on_filament_swap = 0
    host_type = octoprint
    infill_acceleration = 0
    infill_every_layers = 1
    infill_extruder = 1
    infill_extrusion_width = 0
    infill_first = 1
    infill_only_where_needed = 0
    infill_overlap = 15%
    infill_speed = 60
    interface_shells = 0
    layer_gcode =
    layer_height = 0.25
    machine_max_acceleration_e = 10000,5000
    machine_max_acceleration_extruding = 10000,1250
    machine_max_acceleration_retracting = 10000,1250
    machine_max_acceleration_x = 2500,1000
    machine_max_acceleration_y = 2500,1000
    machine_max_acceleration_z = 2500,200
    machine_max_feedrate_e = 10000,5000
    machine_max_feedrate_x = 450,200
    machine_max_feedrate_y = 450,200
    machine_max_feedrate_z = 100,30
    machine_max_jerk_e = 100,50
    machine_max_jerk_x = 25,10
    machine_max_jerk_y = 25,10
    machine_max_jerk_z = 10,5
    machine_min_extruding_rate = 0,0
    machine_min_travel_rate = 0,0
    max_fan_speed = 100
    max_layer_height = 0
    max_print_height = 200
    max_print_speed = 80
    max_volumetric_speed = 0
    min_fan_speed = 100
    min_layer_height = 0.1
    min_print_speed = 10
    min_skirt_length = 25
    notes =
    nozzle_diameter = 0.35
    only_retract_when_crossing_perimeters = 1
    ooze_prevention = 0
    output_filename_format = [input_filename_base].gcode
    overhangs = 1
    parking_pos_retraction = 92
    perimeter_acceleration = 0
    perimeter_extruder = 1
    perimeter_extrusion_width = 0
    perimeter_speed = 50
    perimeters = 3
    post_process =
    print_host =
    print_settings_id = M2 Default
    printer_model =
    printer_notes =
    printer_settings_id = M2 Default
    printer_technology = FFF
    printer_variant =
    printer_vendor =
    printhost_apikey =
    printhost_cafile =
    raft_layers = 0
    remaining_times = 0
    resolution = 0.01
    retract_before_travel = 3
    retract_before_wipe = 0%
    retract_layer_change = 0
    retract_length = 1
    retract_length_toolchange = 10
    retract_lift = 0
    retract_lift_above = 0
    retract_lift_below = 0
    retract_restart_extra = 0
    retract_restart_extra_toolchange = 0
    retract_speed = 60
    seam_position = nearest
    serial_port =
    serial_speed = 250000
    silent_mode = 1
    single_extruder_multi_material = 0
    single_extruder_multi_material_priming = 1
    skirt_distance = 3
    skirt_height = 1
    skirts = 3
    slice_closing_radius = 0.049
    slowdown_below_layer_time = 5
    small_perimeter_speed = 25%
    solid_infill_below_area = 70
    solid_infill_every_layers = 0
    solid_infill_extruder = 1
    solid_infill_extrusion_width = 0
    solid_infill_speed = 75%
    spiral_vase = 0
    standby_temperature_delta = -5
    start_filament_gcode = "; Filament gcode\n"
    start_gcode = ;– PrusaSlicer Start G-Code for M2 starts –\n; Ed Nisley KE4NZU\n; Makergear V4 hot end\n; Origin at platform center, set by MANUAL_X_HOME_POS compiled constants\n; Z-min switch at platform, must move nozzle to X=135 to clear\nG90 ; absolute coordinates\nG21 ; millimeters\nM83 ; relative extrusion distance\nM104 S[first_layer_temperature] ; start extruder heating\nM140 S[first_layer_bed_temperature] ; start bed heating\nM17 ; enable steppers\nG4 P500 ; … wait for power up\nG92 Z0 ; set Z to zero, wherever it might be now\nG0 Z10 F1000 ; move platform downward to clear nozzle; may crash at bottom\nG28 Y ; home Y to clear plate, offset from compiled constant\nG28 X ; home X, offset from M206 X, offset from compiled constant\nG0 X135 Y0 F15000 ; move off platform to right side, center Y\nG28 Z ; home Z to platform switch, offset from M206 Z measured\nG0 Z2.0 F1000 ; get air under switch\nG0 Y-126 F10000 ; set up for priming, zig around corner\nG0 X0 ; center X\nG0 Y-124.5 ; just over platform edge\nG0 Z0 F500 ; exactly at platform\nM190 S[first_layer_bed_temperature] ; wait for bed to finish heating\nM109 S[first_layer_temperature] ; set extruder temperature and wait\nG1 E20 F300 ; prime to get pressure, generate blob on edge\nG0 Y-123 F5000 ; shear off blob\nG0 X15 F15000 ; jerk away from blob, move over surface\nG4 P500 ; pause to attach\nG1 X45 F500 ; slowly smear snot to clear nozzle\nG1 Z1.0 F2000 ; clear bed for travel\n;– PrusaSlicer Start G-Code ends –\n
    support_material = 0
    support_material_angle = 0
    support_material_auto = 1
    support_material_buildplate_only = 0
    support_material_contact_distance = 0.2
    support_material_enforce_layers = 0
    support_material_extruder = 1
    support_material_extrusion_width = 0.31
    support_material_interface_contact_loops = 0
    support_material_interface_extruder = 1
    support_material_interface_layers = 3
    support_material_interface_spacing = 0
    support_material_interface_speed = 100%
    support_material_pattern = rectilinear
    support_material_spacing = 2.5
    support_material_speed = 60
    support_material_synchronize_layers = 0
    support_material_threshold = 0
    support_material_with_sheath = 1
    support_material_xy_spacing = 50%
    temperature = 250
    thin_walls = 1
    threads = 4
    thumbnails =
    toolchange_gcode =
    top_fill_pattern = hilbertcurve
    top_infill_extrusion_width = 0
    top_solid_infill_speed = 50%
    top_solid_layers = 3
    top_solid_min_thickness = 0
    travel_speed = 300
    use_firmware_retraction = 0
    use_relative_e_distances = 0
    use_volumetric_e = 0
    variable_layer_height = 1
    wipe = 0
    wipe_into_infill = 0
    wipe_into_objects = 0
    wipe_tower = 0
    wipe_tower_bridging = 10
    wipe_tower_no_sparse_layers = 0
    wipe_tower_rotation_angle = 0
    wipe_tower_width = 60
    wipe_tower_x = 180
    wipe_tower_y = 140
    wiping_volumes_extruders = 70,70
    wiping_volumes_matrix = 0
    xy_size_compensation = 0
    z_offset = 0

  • American Standard Elite Kitchen Faucet: O-Rings Again

    American Standard Elite Kitchen Faucet: O-Rings Again

    My alleged improvement to the upper bearing ring in our American Standard Elite kitchen faucet didn’t survive nearly as well as I hoped and began leaking through the o-ring seals after the usual year. The 0.4 mm polypropylene shim ring apparently stuck to the nylon bearing ring, wore down to a 0.1 mm thick ribbon against the base, then let the o-ring wear out as usual.

    The black gunk around the top of the upper seal area has the consistency of hard plastic paint, although it’s most likely rubber particles from the o-ring burnished against the bronze base by the sliding PP shim ring:

    American Standard Elite faucet - base
    American Standard Elite faucet – base

    Remember Nisley’s First Rule of Plumbing: Never look inside your water supply pipes.

    As before, the o-rings wear on their inner diameters, indicating that they turn with the spout around the base.

    For lack of anything smarter, I removed as much of the debris as feasible, installed new seals, reassembled the faucet in reverse order, and ordered another set of parts.

    If I hadn’t done such a great job of reinforcing the underside of the sink deck around the mounting rings, to the extent I’m not sure another faucet base else would fit, I’d be far less reluctant to start over.