Sunday, July 28, 2013

Happy Birthday BeagleBoard!

Wow! It's been five years since the introduction of the first Beagle Board, and they just keep getting better! Many thanks and happy birthday wishes to the folks over at BeagleBoard.org. Keep the coolness coming!


Title: BeagleBoard.org celebrates 5 years of enabling Linux DIY hacks
Date: July 28, 2013

BeagleBoard.org launched with support of Digi-Key in 2008 and DIYers quickly adopted BeagleBoard for migrating XBMC to ARM, building GPS accurate down to the centimetereight-legged robots and creating controller hacks. In 2010, Google Summer of Code students contributed numerous projects to help other open source developers, including sniffing USB traffic and XBMC performance optimizations. GSoC students are back at it again in 2013, providing solutions for booting BeagleBone from a Nexus phone, running Arduino sketches and even building new peripherals out of an on-chip microcontroller.

With the introduction of BeagleBoard-xM in 2010, projects accelerated with homemade tablet computersopen graphing calculatorscluster computing in a briefcase,repurposed laptop LCDsremote presence and versatile RC robotsspace camerasUSB killswitches and wearable LED matrices. BeagleBoard-based wearables back in 2010 even provided a strikingly similarity to today's Google Glass.


BeagleBone seemed to find a surprising home in retro computingmimicking PDP11 blinkenlights and saving dot-matrix printers from the dust bin. This seemed to be an inspiration for inventive minds seeking to teach others about the more subtle capabilities the board is packing. The two, small 200MHz 32-bit microcontrollers on-board were used to mimic external peripherals to a discrete 6502 processor, enabling more people to understand the capabilities of these independent units previously demonstrated performing independent generation of VGA signals using a simple resistor ladder.

The tutorials continued with everything from twiddling an LED and running Ubuntu with a full GUI, to extracting video signals and wiring up your own LIDD displays, evenbuilding your own dedicated Pandora radio. This is all before BeagleBone Black launched, boosting performance to 1GHz, adding on-board eMMC and HDMI and dropping the price down to $45.

BeagleBone Black is just getting its legs underneath it in its initial production run of 125,000 units with around half of those shipped so far. Early adopters were able to share some of their creations at Maker Faire, including LED strips being used to display live video. Beyond the obvious and popular lighting solutions, BeagleBone Black has found an early home in manufacturing solutions, especially with makers like Elias Bakken, who created the contest-winning Replicape 3D printer-enabling add-on board and a tiny HDMI display for use with BeagleBone Black, and Charles Steinkuehler, who has created the MachineKit software image containing LinuxCNC and Xenomi real-time Linux kernel. Both Elias and Charles have been steady contributors to the project of late and have helped enable several of the improvements making BeagleBone Black a complete and easy to use solution for all sorts of makers.

As of the recent June 20th software release for BeagleBone Black, significant improvements have been made since launch. Monitor support is greatly improved with better automated resolution setting and a documented process for setting specific resolutions over the command-line or at boot-up, including resolutions up to 1920x1080 at 24fps. The node.js-based BoneScript library, used in such fun things as multi-room physically interactive video games, has several bug fixes and a growing body of interactive wiring examples that work within Chrome and Firefox browsers. Support for the on-board 32-bit microcontrollers called PRUs has been improved with an updated assembler and documentation supporting previously undocumented instructions, including multipliers, and hints have been made at a C compiler being developed, including Pantelis Antoniou's example of using the PRU C compiler to add 32 additional channels of pulse-width modulation (PWM). The value of aggressively chasing the mainline kernel is also being shown with simple command-line statements for enabling UARTs, SPI, I2C, CAN and more peripherals, including improved cape add-on board support.

With an amazing community, stand-out performance and capability, a true open hardware approach that is sustainably profitable but not greedy, continuous demonstrated improvements and a focus on educating aspiring engineers and hobbyists alike, BeagleBoard.org has proven to be a DIY force with which to reckon and an inspiration for makers everywhere. Happy Birthday Boris!

Monday, July 22, 2013

BeBoPr Bridge: Stand-alone Machine Control

UPDATE:  If you buy a small LCD, I suggest getting one with slightly higher resolution.  I am wising in particular I had a bit more vertical resolution when running the Axis GUI for LinuxCNC. 

One of the few things I don't like about the BeBoPr board is since it pre-dates the BeagleBone Black it conflicts with a bunch of pins that are now reserved for the new on-board HDMI and 2G eMMC.

Fortunately, Bas has released the BeBoPr-Bridge board, which is a set of boards that shuffles around the I/O pin-out and allows an otherwise stock BeBoPr to work with a BeagleBone Black without causing any pin conflicts.  The Bridge board even solves the problem of how to access the serial boot console when using the BeBoPr!

Thanks to the folks at OSH Park, I was able to get three sets of the Bridge board fabricated and shipped to me for a total cost of $23.10 (including shipping), or about $7 each!  Once the boards arrived and I got them built up, it was time to print something stand-alone using the BeagleBone Black and my $79 eBay special HDMI monitor:


If you want to follow along, make sure you're using my latest MachineKit image (with the -bone23 kernel), and do a git pull to grab the latest configuration files from the MachineKit branch of LinuxCNC.  Launch LinuxCNC with the BeBoPr-Bridge configuration, and make sure you have not disabled the HDMIN cape in uEnv.txt.  The latest image comes setup properly by default (HDMI disabled, and HDMIN enabled), but if you have been using a stock BeBoPr board you probably have both versions disabled.

Here are a couple still photos, you can find more on my G+ page.

Complete system with the BeagleBone Black mounted on top of the BeBoPr using the Bridge Board.
Bridge board mounted on my BeagleBone Black with serial cable, USB mouser/KB receiver, and HDMI cable connected.

Friday, July 19, 2013

Multiple ADC Readings

Heated Bed Working

It turns out the BeagleBone ADC "helper" kernel drivers are very particular about exactly how you talk to them.  If you try to read from them too fast, or even worse have two threads trying to read ADC values at the same time, Bad Things happen.  What exactly?  You can get illegal values (outside the 0-4095 range of the ADC), values from the wrong analog input channel, or have your program crash with access errors.  This has been preventing me from getting the heated bed working on my printer, since I initially coded the ADC thermistor HAL component with the idea that each thermistor would be read by it's own thread.

I have re-worked the python code to support reading more than one thermistor, and it seems to be working well.  I managed to finish a print that took a couple hours, and I left the system running overnight and it is still working as expected this morning.  For comparison, with two threads reading thermistor values, one of the threads would die within a couple of minutes.

Configuration should be fairly obvious, refer to the example BeBoPr and BeBoPr-Bridge configurations.  There is a new --num_chan parameter, and the existing --adc and --therm parameters now take a list of values, one for each analog input channel.  Also added is a short-hand notion for the thermistor table, so you can now use "1" (the equivalent Marlin thermistor table number) instead of "epcos_B57560G1104".  Handy if you have 3 thermistors attached!

Wednesday, July 17, 2013

Linear Delta Kinematics

I started working with LinuxCNC when I saw Johann Rocholl's Rostock linear delta printer.  Trying to squeeze reverse kinematics for non-Cartesian movements into an AVR seemed like a fools errand to me, so I turned to LinuxCNC, which has pluggable kinematics.  But someone has to write those kinematics! 

Everything old is new again 

 

Thanks to Viesturs, I found this awesome video of a linear delta robot controlled by LinuxCNC from back in 2011!  Hg5bsd (Jozsef Papp) has provided the lindeltakins.c file used to control his 'bot, and a sketch of the control layout.  If you are lucky enough to have a working linear delta mechanism (mine is currently in-progress), you should try out LinuxCNC with these kinematics and see how it works for you!

"Official" LinuxCNC Support

In similar news, LinuxCNC developer Jeff Eppler has acquired a Rostock Max, and has also written some linear delta kinematics.  Keep up with his delta changes in the jepler/lineardeltakins branch at git.linuxcnc.org.

Monday, July 15, 2013

Custom HDMI Resolution


UPDATE:  If you buy a small LCD, I suggest getting one with slightly higher resolution.  I am wising in particular I had a bit more vertical resolution when running the Axis GUI for LinuxCNC.

As follow-up to my post on how to force HDMI Resolution, I recently obtained a small 7" 800x480 LCD display with HDMI input and found I need to not only force a particular resolution, but a resolution that is non-standard as well.

It turns out this is pretty easy once you filter through all the hints that don't work (lots of fbset and xrandr instructions).  If you want a custom display mode, all you have to do is give the kernel your desired resolution and tell it to calculate the cvt timings.  There are some details in the kernel documentation for modedb.txt, and the following uEnv.txt entry (which turns into a kernel command line argument) got my display working properly:
kms_force_mode=video=HDMI-A-1:800x480M@60
Note the "M" after the resolution and before the "@", which is what tells the kernel to calculate timings for this resolution rather than try to find it as a pre-existing standard.  You can specify other details, like reduced blanking or interlaced mode, see the modedb.txt documentation for details.

This setting works with my latest MachineKit Debian image, based on Robert C Nelson's Debian image, with xfce and xdm added for a desktop environment.  The kms_force_mode uEnv.txt variable is supported in Robert's latest images, and the actual kernel command line parameter you want to set is "video=HDMI...".

For those of you still running Angstrom, the above setting only affects the display while the kernel is booting.  Once the system is running, Angstrom's custom version of Gnome takes over, blindly ignores any prior resolution settings, and forces the HDMI output into whatever video mode it considers "best" based on your EDID settings.  This is all well and good for most monitors, but my low-end LCD panel doesn't have it's native resolution listed as any of it's EDID options.  I tried "lying" to the system by crafting a custom EDID and overriding the EDID from the display, which seems like it should work, but absolutely nothing changed.  Probably because the default BeagleBone kernel is compiled with CONFIG_DRM_LOAD_EDID_FIRMWARE disabled.

Here's a screen shot of my BeagleBone Black happily running in 800x480 mode, nicely mapping 1:1 to the native resolution of my $79 eBay HDMI special:


And here's the actual display: 

Sunday, July 14, 2013

Adding Home/Limit Switches

Home switches are especially convenient on 3D printers to return the printer to a known location, to get perfect adhesion from a perfect first layer height.  They're pretty much a requirement for delta 3D printers as well.

This post will walk through the steps to modify the base MachineKit image with LinuxCNC to add a limit switch.  Walking through the steps will take some time, but helps to explain concepts like the HAL and Device Tree.

Getting the Code


In a commit from 7/14, Charles checked in code to export and set up the limit switch inputs, in the MachineKit branch, so to get most of the code needed, do:

cd linuxcnc/src
git pull
make
sudo make setuid

... then follow the instructions and notes below to modify BeBoPr.ini and BeBoPr.hal for your specific printer.

BeBoPr Limit Switches

The BeBoPr board has 6 switch inputs which can be used as limit or home switches.

Our goal is to wire up one input switch to LinuxCNC so that when the X axis starts to home, pressing the NC (inverted-logic) switch causes the axis to stop and detect home.  To do this, we'll modify a bunch of files.

We'll use X-Max, the limit switch closest to the PWM outputs at the edge of the BeBoPr.  According to the BeBoPr manual, the BeagleBone black manual (BBB_SRM.pdf pg 80), and tracing the board traces, the X-max input switch is pin 32 on connector 8 and gpio0.11.

BeBoPr.ini


First, LinuxCNC needs to know that you want to use a limit switch when homing an axis.  The .ini file sets all kinds of config specific to your board and machine.

Setting an axis instance with a homing search velocity causes it go in the specified direction when you click the home button.  Here's a change that enables this:

diff --git a/configs/BeagleBone/BeBoPr/BeBoPr.ini b/configs/BeagleBone/BeBoPr/BeBoPr.ini
index f3b92a5..2bb64f7 100755
--- a/configs/BeagleBone/BeBoPr/BeBoPr.ini
+++ b/configs/BeagleBone/BeBoPr/BeBoPr.ini
@@ -165,8 +165,8 @@ MIN_FERROR = 0.25

 HOME =                  0.000
 HOME_OFFSET =           0.00
-#HOME_SEARCH_VEL =       0.10
-#HOME_LATCH_VEL =        -0.01
+HOME_SEARCH_VEL =       -10.0
+HOME_LATCH_VEL =        10.0
 #HOME_USE_INDEX =        YES
 #HOME_IGNORE_LIMITS =    YES

For more details on homing, see Sec 4, Homing Configuration, in:
http://www.linuxcnc.org/docs/LinuxCNC_Integrator_Manual.pdf

You'll definitely want to make sure that the polarity of HOME_SEARCH_VEL is the right direction for your machine to drive it toward the home axis.

Now when you click the Home button in the LCNC GUI, you'll see the axis move.  Great!  But it has no way to find home, so it'll keep searching forever.

BeBoPr.hal


The HAL in LinuxCNC is the Hardware Abstraction Layer.  It provides a higher-level way to wire up in input to outputs, without having to recompile the LinuxCNC base code.

We also need to wire up a signal in the HAL so that the limit switch pin is connected to the axis homing logic.  home-sw-in is a pre-defined attribute of the axis instance that is meant for this:

diff --git a/configs/BeagleBone/BeBoPr/BeBoPr.hal b/configs/BeagleBone/BeBoPr/BeBoPr.hal
index 2bc5b38..1d9de6f 100755
--- a/configs/BeagleBone/BeBoPr/BeBoPr.hal
+++ b/configs/BeagleBone/BeBoPr/BeBoPr.hal
@@ -91,6 +91,10 @@ setp [PRUCONF](DRIVER).stepgen.00.steppin         0xA2
 # P8.44 PRU1.out4
 setp [PRUCONF](DRIVER).stepgen.00.dirpin          0xA3

+# Example from http://wiki.linuxcnc.org/cgi-bin/wiki.pl?Homing_And_Limit_Switch
+# Connect X-max input to X min input.
+net home-x bb_gpio.p8.in-32 => axis.0.home-sw-in
+setp bb_gpio.p8.in-32.invert 1

 # ################
 # Y [1] Axis

However, this change won't be enough, as the pin is unknown to the HAL. Running this code will cause LCNC to exit:

BeBoPr.hal:96: Pin 'bb_gpio.p8.in-32' does not exist
Shutting down and cleaning up LinuxCNC...

To get one step closer to making the pin accessible, modify this line at the top:

loadrt hal_bb_gpio output_pins=103,105,107,120,121,127,128,129,130,139,140,141,142,143,144,145,146

Add input_pins = 132 to the line.  Why 132?

From ~/linuxcnc/src/hal/drivers/hal_bb_gpio.c, line 191 has this comment:

Valid pins are 101-146 for P8 pins, 201-246 for P9 pins

You'll notice that every component seems to have its own numbering scheme.

Running this then yields:

linuxcnc@arm:~/linuxcnc/configs/BeagleBone/BeBoPr$ LINUXCNC - 2.6.0~pre
...
memmapped gpio port 0 to 0xb6f5c000, oe: 0xb6f5c134, set: 0xb6f5c194, clr: 0xb6f5c190
Waiting for component 'hal_bb_gpio' to become ready................................................................................................
BeBoPr.hal:25: /home/linuxcnc/linuxcnc/bin/rtapi_app exited without becoming ready
BeBoPr.hal:25: insmod failed, returned -1
Shutting down and cleaning up LinuxCNC...

The HAL can only provide access to a pin if the OS knows the pin.  Board-specific pin definitions are in the most recent version of Linux as the Device Tree.  We'll next add the missing pins to the device tree.


Device Tree for BeBoPr Cape


The file ~/linuxcnc/configs/BeagleBone/BeBoPr/BB-LCNC-BEBOPR-00A0.dts contains the device tree for the BeBoPr.  Here are some notes from Charles:

  • Every used I/O pin needs to show up in the dts device tree file, with an appropriate pin mux setting.
  • Any GPIO pin driven by the PRU (ie: Step, Dir, PWM) needs to be exported in setup.sh.
  • Direct PRU I/O pins do *NOT* need to be exported in setup.sh.
  • At least _one_ pin needs to be exported in setup.sh to enable the low-level gpio hardware, or the hal_bb_gpio module will fail.  It is OK to export a pin used by hal_bb_gpio for this...it is just not required that all hal_bb_gpio pins get exported
  • Any GPIO pins not driven by the PRU should be listed in the hal_bb_gpio command line.

The relevant section for the device tree is toward the bottom, and it configures attributes of pins.  The chip in the BeagleBone uses a big pin multiplexer for this:

        fragment@0 {
                target = <&am33xx_pinmux>;
                __overlay__ {
                        foo_pins: foo_pins {
                                pinctrl-single,pins = <
                                        0x18 0x0f       /* p8.3  gpio1_6        */
                                        0x08 0x0f       /* p8.5  gpio1_2        */

For each pin, there are two values:

First Value: The first value is the address offset of the pinmux register (or more specifically, the conf_<module>_<pin> register).  See the TRM section 9.3.51 for details, and table 9.10 for the addresses.  Note in the DTS file that the addresses are offsets from the start of the conf_ register section instead of the start of the control registers, so you have to subtract 0x800 from the listed address.

There's a nice spreadsheet on github that combines all the BeagleBone specific I/O stuff:

https://github.com/selsinork/beaglebone-black-pinmux

...it will save you from having to cross correlate data from 3 or more manuals!  :)

Second Value: The second value is pin usage, which is also defined TRM section 9.3.51.  For example, pru1.r30.13 is to be used in mode 5 ("by the PRU"), and with bit 3 (pullup) disabled, bits 2-0 are 5, making this byte 0xd.  Other GPIO pins are mode 7, so the byte is 0xf.  Pin usage is also defined on page 98 of the BBB SRM.

Now we'll mod the device tree file. As a reminder, gpio0.11 is the X-max input switch, which is pin 32 on connector 8.

Page 80 of the SRM shows this pin to also be called gpmc_a19, lcd_data15, and UART5_RSTN.  Table 9-10 of the TRM shows offset 8DCh for lcd_data15; subtracting the 0x800 base, we get 0xdc for the first value.

The second value will be a bit different, too, because we want to set the RXACTIVE and PULLTYPESEL bits to 1.  These bits make the port an input and enable a pullup. Hence, the second value in the .dts for input pins should be 0x3f, not 0x0f.

diff --git a/configs/BeagleBone/BeBoPr/BB-LCNC-BEBOPR-00A0.dts b/configs/BeagleBone/Be
index 50f1709..67279d2 100644
--- a/configs/BeagleBone/BeBoPr/BB-LCNC-BEBOPR-00A0.dts
+++ b/configs/BeagleBone/BeBoPr/BB-LCNC-BEBOPR-00A0.dts
@@ -20,6 +20,7 @@
                "p8.28",        /* gpio2.24     Z_Ena   */
                "p8.29",        /* pru1.r30.9   Z_Dir   */
                "p8.30",        /* pru1.r30.11  E_Step  */
+               "p8.32",        /* gpio0.11     X_Max   */
                "p8.36",        /* gpio2.16     J4_PWM  */
                "P8.39",        /* pru1.r30.6   Y_Dir   */
                "P8.40",        /* gpio2.13     Y_Ena   */
@@ -36,6 +37,7 @@
                "gpio1_2",
                "gpio2_2",
                "gpio1_31",
+               "gpio0_11",
                "gpio2_24",
                "gpio2_16",
                "gpio2_13",
@@ -57,6 +59,7 @@
                                        0xe8 0x0d       /* p8.28 pru1.r30.10    */
                                        0xe4 0x0d       /* p8.29 pru1.r30.9     */
                                        0xec 0x0d       /* p8.30 pru1.r30.11    */
+                                       0xdc 0x3f       /* p8.32 gpio0_11       */
                                        0xc8 0x0f       /* p8.36 gpio2_16       */
                                        0xb8 0x0d       /* p8.39 pru1.r30.6     */
                                        0xbc 0x0f       /* p8.40 gpio2_13       */

After making these changes, run dtc.sh in the same dir (and possibly reboot):

cd ~/linuxcnc/configs/BeagleBone/BeBoPr/
sudo ./dtc.sh

dtc.sh looks like this:

#!/bin/sh

dtc -O dtb -o BB-LCNC-BEBOPR-00A0.dtbo -b 0 -@ BB-LCNC-BEBOPR-00A0.dts && \
cp BB-LCNC-BEBOPR-00A0.dtbo /lib/firmware/

dtc -O dtb -o BB-LCNC-BEBOPRBR-00A0.dtbo -b 0 -@ BB-LCNC-BEBOPRBR-00A0.dts && \
cp BB-LCNC-BEBOPRBR-00A0.dtbo /lib/firmware/

It's invoking the device tree compiler to form a device tree file for the kernel to load.

There's one more place we need to make some mods.

setup.sh


The next file to mod is ~/linuxcnc/configs/BeagleBone/BeBoPr/setup.sh.  The bottom of this file looks like:

# Export GPIO pins
# This really only needs to be done to enable the low-level clocks for the GPIO
# modules.  There is probably a better way to do this...
while read PIN DIR JUNK ; do
        case "$PIN" in
        ""|\#*)
                continue ;;
        *)
                [ -r /sys/class/gpio/gpio$PIN ] && continue
                sudo -A su -c "echo $PIN > /sys/class/gpio/export" || pin_err
                sudo -A su -c "echo $DIR > /sys/class/gpio/gpio$PIN/direction" || dir_err
                ;;
        esac


done <<- EOF
        38      low     # gpio1.6       P8.3    Enable
        34      high    # gpio1.2       p8.5    Enable_n
        66      high    # gpio2.2       p8.7    Enable_n (ECO location)
        92      out     # gpio2.24      P8.28   Z_Ena
        80      out     # gpio2.16      P8.36   J4.PWM
        77      out     # gpio2.13      P8.40   Y_Ena
        74      out     # gpio2.10      P8.41   X_Ena
EOF

There are several different numbering schemes in use; the gpio numbers
in setup.sh use the kernel pin numbering which is:

Kernel Pin = (<gpio_bank> * 32) + <gpio_pin>

Charles' pin assignments for the PRU are very similar, but off by 32 so that
a value of zero results in no pin being driven:

hal_pru_generic pin = ((<gpio_bank> + 1) * 32) + <gpio_pin>

...or for PRU direct pins:

hal_pru_generic pin = ((4 + 1) * 32) + <PRU_pin>

And you already read about about the hal_bb_gpio pin numbering based on the
P8/P9 pin numbers.

Here were my changes:

diff --git a/configs/BeagleBone/BeBoPr/setup.sh b/configs/BeagleBone/BeBoPr/setup.sh
index 5a3843f..abf8e1a 100755
--- a/configs/BeagleBone/BeBoPr/setup.sh
+++ b/configs/BeagleBone/BeBoPr/setup.sh
@@ -54,6 +54,7 @@ while read PIN DIR JUNK ; do
         esac

 done <<- EOF
+        11      in      # gpio0.11      P9.32   X_Max
        38      low     # gpio1.6       P8.3    Enable
        34      high    # gpio1.2       p8.5    Enable_n
        66      high    # gpio2.2       p8.7    Enable_n (ECO location)

Now linuxcnc should start!  Almost there.

Testing It


First, verify that your limit switch pin is connected.  When you press it, the corresponding light on the BeBoPr should toggle.

Then, verify that Linux sees the same thing:

 sudo cat /sys/kernel/debug/gpio

You should see this:

GPIOs 0-31, gpio:
 gpio-11  (sysfs               ) in  hi

GPIOs 32-63, gpio:
 gpio-34  (sysfs               ) out lo
 gpio-38  (sysfs               ) out hi
 gpio-52  (eMMC_RSTn           ) out lo

GPIOs 64-95, gpio:
 gpio-66  (sysfs               ) out lo
 gpio-74  (sysfs               ) out hi
 gpio-77  (sysfs               ) out hi
 gpio-80  (sysfs               ) out lo
 gpio-92  (sysfs               ) out lo

Then press the switch, and the top line should go low:

GPIOs 0-31, gpio:
 gpio-11  (sysfs               ) in  lo

If that works, go to linuxcnc, toggle e-stop, toggle machine power, and then home the X axis.

Click 'Home X'.  The axis should move until the button is pressed; then it'll reverse until the button is released.

Woo!  You now have a working home switch.

Saturday, July 13, 2013

MachineKit 2013-07-13 Available

I have released an updated version my MachineKit Image for running LinuxCNC on the BeagleBone.

Support has been added for the new BeBoPr Bridge, and HDMI is enabled by default allowing the BeagleBone to run stand-alone.  A remote display is still required to use hardware that requires disabling the HDMI output, such as the original BeBoPr board without the Bridge adapter.

In addition, the kernel has been updated with the latest BeagleBone specific patches, and the LinuxCNC git working copy includes lots of minor fixes and tweaks made over the last month.

Significant changes in this release include:
  • Switch to 3.8.13xenomai-bone23 kernel
  • Leave HDMIN (no audio) enabled by default in uEnv.txt
  • Add xfce desktop and netsurf web browser
  • Remove apache and udhcpd
  • Remove linuxcnc user from admin group to enable existing NOPASSWD setting in sudoers.d to work properly:
      gpasswd -d linuxcnc admin
  • Switch ~/linuxcnc working copy to MachineKit branch:
      cd ~/linuxcnc
      git fetch origin
      git checkout -t origin/MachineKit
      cd src
      make
      sudo make setuid

Saturday, July 6, 2013

Slicing for LinuxCNC

With LinuxCNC running my 3D printer, I have had to tweak my slicing settings to get good results.  I normally use Slic3r, but Johann uses KISSlicer, so I tried both.

EXTRUDER WARNING

If you are printing with LinuxCNC, it is important to note that homing is completely different than with typical Arduino firmware.  This is partly because the Arduino firmware essentially ignored decades of standardized gcode prior art, and partly because controllers like LinuxCNC have multiple coordinate systems (machine, world, part, and joint coordinates, for instance) which are generally all swept into "world" coordinates in most 3D printers.

Anyway, the auto-homing typically inserted at the start of a gcode file generally won't do what you expect, so it is important to make sure you have manually homed the X, Y, and Z axis before your first print, and REHOME THE EXTRUDER AXIS to zero just before printing anything!  If you do not home the extruder axis, the first thing that will happen when you start your print is your extruder will try to 'unwind' all the filament it has extracted and end up ejecting the filament out of the extruder, and you will get to start over again.  I am looking into fixing this with gcode remapping, incremental coordinates, or some other solution, but for now just remember to re-home the A (extruder) axis before each print!

KISSlicer

My issues with KISSlicer mostly related to not having any familiarity with it.  I started with Johann's Rostock config from the settings in his Kossel github repo (my printer uses 3mm filament and a 0.5mm nozzle like his Rostock).  These slicing settings were reasonable, but I couldn't get gcode that worked for LinuxCNC (it still used E for the extruder axis instead of A).  Finally, I found the "Axis" pull-down on the Printers -> Extruders tab, which let me set the axis to A.  Using the "5D - Absolute E" firmware type setting, this got the axis setting fixed up.  Temperature was still not working properly.  M1xx parameters in RS274D/ISO 6983 require P and Q parameters, not S as used in Marlin and friends.  This can be fixed in the Ptr G-code tab under Select Extruder.  While there go ahead and fix the Deselect Extruder temperature setting, and add your personal prefix/postfix gcode.

Slic3r

I default to using Slic3r, which has a straight-forward Mach3/EMC gcode flavor setting under the printer settings tab.  Despite having well tuned slic3r settings for this printer when I had it running via Marlin, I was having a terrible time with blobs and ooze.  Nothing I did with the retraction settings or wipe seemed to fix the problem, although dialing up retraction did seem to help a bit.

It turns out the current version of slic3r (0.9.10b) forces a few settings if you select the Mach3/EMC gcode flavor.  Essentially, selecting this gcode flavor forces retraction to be combined with subsequent travel in a g0 move, and disables wipe entirely.  LinuxCNC performs coordinated g0 moves, so if the travel distance was very far, the retraction wasn't happening fast enough to avoid ooze no matter what I set it to.  And wipe wasn't helping because it was being disabled by my selection of the Mach3/EMC gcode flavor.  I made a small patch that fixes this issue and hopefully it will get resolved in a newer version.

Here's a print from slic3r with my 3mm filament/0.5mm nozzle with 0.2mm layers and 0.4mm infill: