Archive for category Software

Makergear M2 Updates: New Filament Drive Gear with Marlin 1.1.0-RC5

Confronted with a puzzling failure, I decided to perform some long-delayed tweaking…

The folks at Makergear send me (and several others) a new filament drive gear for testing. It has smaller splines / teeth and produces a much finer mark on the filament:

Filament Drive Gear Indentations

Filament Drive Gear Indentations

The obvious stripped section on the right comes from finger-fumbling an absurdly large extrusion distance (something like, mmm, 1450 mm) with a high extrusion speed. Not the fault of the drive gear, that’s for sure!

I remeasured the actual filament length extruded to recompute Marlin’s STEPSPERMM configuration constant. After rediscovering the awkward fact that, when you change that value with an M92 command, Marlin doesn’t recompute the current extruder position, so the next manual extrusion will move a random amount of filament in a random direction, the value eventually converged to 476.9 steps/mm.

I intended to put the M92 in Slic3r’s startup G-Code, but the prospect of random extrusions suggested that now was a great time to update the firmware; again demonstrating that no good idea goes unpunished.

The most recent Marlin version, 1.1.0-RC5 (clearly labeled “Not for production use – use with caution!”), had been released a few hours earlier, so I fetched that and tweaked the configuration files as before.

The firmware now includes thermal runaway / thermistor failure protection for both the bed and hot end. Increasing the two THERMAL_PROTECTION hysteresis values to 6 °C seems to work well.

It also includes a CONTROLLERFAN output that can go active when any stepper is enabled, then off after predetermined time. Setting that to Pin 6 and 30 seconds means the whining fan (it’s a ball bearing replacement in an aerodynamically poor location) in the control box goes off when it’s not needed.

Bumping DEFAULT_STEPPER_DEACTIVE_TIME to 600 seconds means the motors don’t time out while waiting for the platform to reach operating temperature.

Increasing the HOMING_FEEDRATE for the Z-axis to 60*60 mm/min causes it to whack the lever a bit harder and overtravel slightly more. The Z Offset ended up at -2.15 mm, based on the calibration cubes below.

Running a PID calibration on the V4 hot end produced slightly different values: P=17.41, I=1.02, D=74.44. Hardcoding those into the config file does not override the values already stored in EEPROM: you must manually set them with M301, then use M500 to program the EEPROM.

A few Calibration Box iterations settled settled the Extrusion Multiplier at a convenient 1.00 with the new drive gear:

Thinwall hollow boxes - drive gear calibration

Thinwall hollow boxes – drive gear calibration

All in all, that whole process went much more smoothly than I expected.

The config files as GitHub gists:

, , ,


Improved Lipstick and Lip Balm Holder With Text

For reasons that aren’t relevant here, Mary asked me to make four sets of improved lipstick / lip balm / sunscreen holders with five smaller tubes plus the central one and an inscription on the bottom. I ran off one with the last of the cyan PETG and the other three in natural PETG:

Improved Lipstick Holder - on platform

Improved Lipstick Holder – on platform

I embossed the text into the bottom three layers. The tiny spots of detached infill for lowercase letters like a didn’t adhere to the platform, mostly because the retraction settings that work well for larger areas don’t push enough plastic out to bond with the platform before retracting and moving away.

The bridging layer over the text shows Slic3r doing the best it can (clicky for more far more dots). Laying a uniform patch over all the letters in one shot would work better, but I don’t know how you’d define an algorithm that specifies when such a situation occurs:

Lip Balm Holder - text bridge layer - Slic3r preview

Lip Balm Holder – text bridge layer – Slic3r preview

The solid infill layer directly over the Hilbert Curve bottom layer came out grossly severely excessively overstuffed, to the extent that the accumulation reduced the flow of molten plastic and caused the filament drive to strip:

Overfilled layer 2

Overfilled layer 2

Previewing the G-Code show nothing out of the ordinary and, after considerable flailing around, I finally set Slic3r to begin the 3D Honeycomb infill directly atop the Hilbert Curve bottom layer. That provided enough open space to complete the mission, but more debugging was in order.

The OpenSCAD source code as a GitHub gist:



Thinwall and Solid Boxes for 3D Printer Calibration

A revision to my Fundamental Calibration Object adds some variations …

The classic thinwall open box:

Calibration Box - open - 1 thread - solid model

Calibration Box – open – 1 thread – solid model

A solid box:

Calibration Box - solid - solid model

Calibration Box – solid – solid model

A solid box with text embossed on the lower surface:

Calibration Box - solid text - solid model

Calibration Box – solid text – solid model

You must consider how the slicer settings interact with the solid model parameters, particularly now that slicers can produce adaptive infill for small gaps between perimeter threads. Previewing the slicer’s output will show you what assumptions it makes and prevent surprising results out there on the platform.

A single-thread wall comes out properly:

Thinwall open box - 0.40 wall - Slic3r

Thinwall open box – 0.40 wall – Slic3r

The results look just like the preview, with firmly bonded layers and no fluff:

Thinwall open box - 1 thread walls

Thinwall open box – 1 thread walls

This wall should be two threads wide, but Slic3r inserts very very thin infill thread:

Thinwall open box - 0.80 wall - Slic3r

Thinwall open box – 0.80 wall – Slic3r

I think that’s a result of forcing the two perimeter threads to sit with their centers exactly one thread width apart, making the (nominal, ideal) inner walls tangent to each other.  Setting the wall to 1.9 mm eliminates the hair-fine infill thread, at the cost of producing an object 0.1 mm smaller than it looks.

Unfortunately, that fine infill doesn’t produce enough plastic flow for a continuous thread. The PET I’m using accumulates on the nozzle until enough of a glob forms to stick on the previous layer, but hair-fine strands connect those globs to each other and the nozzle, producing awful results:

Thinwall open box - 2 thread walls

Thinwall open box – 2 thread walls

A triple-thread wall allows Slic3r to produce a fatter infill thread that works the way you’d expect:

Thinwall open box - 1.20 wall - Slic3r

Thinwall open box – 1.20 wall – Slic3r

The threads bond firmly in all directions:

Thinwall open box - 3 thread walls

Thinwall open box – 3 thread walls

It’s not obvious from that picture, but the bond between successive infill threads produces a glass-clear vertical plastic slab that relays images from the bottom to the top. The perimeter threads are also firmly bonded, albeit with not quite the same optical quality.

To use these boxes:

  • Set the OpenSCAD extrusion parameters to match whatever the slicer will use
  • Set the wall height and thickness to whatever you like
  • Compile-and-render, export the result as a solid model in STL / AMF / whatever
  • Feed the solid model into your favorite slicer and save the G-Code
  • Feed the G-Code into your printer, watch it magically create a little box
  • Measure the printed results and compare with the ideal settings
  • Change the slicing configuration and iterate until satisfied

Verify these measurements before adjusting anything else:

  • Filament diameter: actual vs. nominal will be different
  • Extruder steps per millimeter: mark 100 mm on filament, extrude 100 mm, compare

Then you can verify / adjust some finicky settings:

  • Extrusion multiplier: does the actual single wall width match slicer’s nominal value?
  • Infill density: 100% infill should perfectly fill the solid box
  • Initial Z offset: does actual height match the model setting?
  • Platform alignment: print five boxes at platform center + corners, verify heights
  • First layer adhesion: if these don’t stick, the platform has weak adhesion
  • Minimum time per layer: if the walls slump, you’re printing too fast
  • Extrusion temperature: good bonding and no delamination along any axis

The OpenSCAD source code as a GitHub gist:


1 Comment

Square Chain Mail Armor: Back From The Abyss

After a Slic3r commit fixed the bridging regression, I ran off chain mail patches to celebrate:

Square Chain Mail Armor - 3.3 3.5 4.0 thread bars

Square Chain Mail Armor – 3.3 3.5 4.0 thread bars

Two more Scli3r improvements calculate thin-wall and gap infill based on the available space, then vary the extrusion width to make the answers come out right for a given nozzle diameter. As a result, infill between close-set perimeter walls works much better than before; some of my long-held assumptions became invalid.

The only differences between the sheets: tweaking the BarWidth and SheetSize parameters. The links recalculate themselves around those values.

The OpenSCAD source code as a GitHub gist:


Leave a comment

Raspberry Pi Power Heartbeat LED

While looking for something else, I found a reference to the /boot/overlays/README file, wherein it is written:

        act_led_trigger         Choose which activity the LED tracks.
                                Use "heartbeat" for a nice load indicator.
                                (default "mmc")

        act_led_activelow       Set to "on" to invert the sense of the LED
                                (default "off")

        act_led_gpio            Set which GPIO to use for the activity LED
                                (in case you want to connect it to an external
                                (default "16" on a non-Plus board, "47" on a
                                Plus or Pi 2)

... snippage ...

                                As for act_led_*, but using the PWR LED.
                                Not available on Model A/B boards.

Although the power LED isn’t (easily) visible through the Canakit cases I’m using (it’s under the barely visible hole in front of the small hole near the hacked RUN connector), turning it into a heartbeat pulse distinguishes the CPU’s “running” and “halted” states; whether it will also distinguish “crashed” is up for grabs.

It’s not at all clear what other choices you have.

To enable heartbeating, add this to /boot/config.txt:

# turn power LED into heartbeat

I expected a simple 50% duty cycle heartbeat, but it’s an annoying double blink: long off / on / off / on / long off. Fortunately, it still isn’t (easily) visible …

While you have that file open, reduce the GPU memory to the absolute minimum for headless operation:

# minimal GPU memory for headless operation

Some further ideas, including a way to turn off the HDMI interface.



Streaming Player: NFS Program Distribution

With three identical Raspberry Pi streaming players tootling around the house, it finally dawned on me that they should fetch their Python program directly from The Definitive Source, rather than a local copy.

Tweak the auto-startup in /etc/rc.local:

mount -o ro mollusk:/mnt/bulkdata/Project\ Files/Streaming\ Media\ Player/Firmware/ /mnt/part
sudo -u pi python /mnt/part/ &

There’s probably a way to redirect all of the stdout and stderr results to a file for debugging, but the obvious method doesn’t work:

sudo -u pi sh -c "python /mnt/part/ 2>&1 > /tmp/st.log" &

That redirects stdout from the subprocess call to set up the mixer, but doesn’t catch Python’s print output.

Using the Python logging library would get most of the way to the goal, although stdout from things like the mixer would still vanish.

Continuing with the network theme, one could netboot the RPi players, but that requires more sysadmin hackery than I’m willing to do, what with the good being the enemy of the best.



UDEV Rules for Dell AC511 USB Soundbar

A monitor sound bar seems good enough for streaming background music and suchlike, with the benefit of eliminating the external USB audio converter and reducing the cable tangle:

Dell AC511 USB Soundbar - Dell Image 318-2885r3

Dell AC511 USB Soundbar – Dell Image 318-2885r3

That’s a Dell AC511 USB SoundBar (their choice of capitalization); I mooched the image from their description, because I cannot take a good picture of a dead-black device.

Depending on the description you read, it’s good for maybe 1.5 W, which is about all you can get directly from a USB port: 5 V at well under 500 mA. The audio output required no configuration at all: unplug the Behringer USB converter, plug this in, reboot that sucker, and It Just Worked. Sounds pretty good for as little power as it produces, too; organ music will never reach gut-pounding levels.

The far end of the bar sports a headphone output jack and a line-in jack, so apparently it can handle audio input, despite that not appearing in the online doc. Bonus!

The knob on this end spins endlessly while spitting out USB volume control events that, presumably, work seamlessly with an ordinary Windows setup. It’ll take a bit more effort with a headless Raspberry Pi.

So, we begin …

Following the usual recipe gives these results:

cat /proc/bus/input/devices
I: Bus=0003 Vendor=413c Product=a503 Version=0100
N: Name="Dell Dell AC511 USB SoundBar"
P: Phys=usb-3f980000.usb-1.5/input3
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.5/1-1.5:1.3/0003:413C:A503.0002/input/input1
U: Uniq=
H: Handlers=kbd event1
B: EV=13
B: KEY=e0000 0 0 0
B: MSC=10

In this case, the Name field seems reasonably unique, and, seeing as how the collection of devices required to do this thing keeps growing, I renamed the old /etc/udev/rules.d/KeyPad.rules to Streamer.rules and dropped the new rule in there to keep everything together:

ATTRS{name}=="HID 13ba:0001", SYMLINK+="input/keypad"
ATTRS{idVendor}=="062a", ATTRS{idProduct}=="4101", ENV{ID_INPUT_KEYBOARD}=="1", SYMLINK+="input/keypad"

ATTRS{name}=="Dell Dell AC511 USB SoundBar", SYMLINK+="input/volume"

Load the new rule, trigger udev, and it pops up at the right spot:

sudo udevadm control --reload
sudo udevadm trigger
ll /dev/input
total 0
drwxr-xr-x 2 root root      80 Feb 23 16:35 by-id
drwxr-xr-x 2 root root      80 Feb 23 16:35 by-path
crw-rw---- 1 root input 13, 64 Feb 23 19:30 event0
crw-rw---- 1 root input 13, 65 Feb 23 19:30 event1
lrwxrwxrwx 1 root root       6 Feb 23 19:30 keypad -> event0
crw-rw---- 1 root input 13, 63 Feb 23 19:30 mice
lrwxrwxrwx 1 root root       6 Feb 23 19:30 volume -> event1

Now, to make those KEY_VOLUMEUP and KEY_VOLUMEDOWN events change the volume…

Leave a comment