LightBurn & GRBL Interface (Streaming a G-Code Program to Grbl) problem

I have been testing/evaluating LightBurn prior to purchasing . . . I am very impressed with the functionality and ease of use of the software and want to use it for both pen plotting/vinyl cutting and laser engraving/cutting on my CNC machine.

I believe I have identified an issue with how LightBurn interfaces and streams G-Code to the Arduino GRBL controller. I am running an Arduino Nano with GRBL 1.1f on an EleksMaker EleksDraw machine which has a simple RC Servo to raise/lower the pen/cuttter.

The issue I am experiencing is a failure of the Z-Axis RC Servo (pen holder) to reliably retract (using M3/M5 G-Code), when connected directly to and driven by LightBurn . . . however, if I save the G-Code file produced by LightBurn and send it to my EleksMaker with alternative G-Code sender(s), it works perfectly . . . accordingly, I concluded the problem is most likely not with the G-Code generated and/or how it is interpreted by the Arduino/GRBL 1.1f firmware.

I confirmed this assertion by manually sending each line to the EleksMaker CNC using a serial terminal program (Tera Term), which produced the expected and perfect behaviour . . . however, if I copy the 30 or so lines of my simple G-Code from the saved file and paste them (en-mass/all at once) into the serial terminal program, the Z-Axis RC Servo (pen holder) also fails to retract reliably.

The problem is repeatable and appears to be a timing issue related the sending of G-Code to the Arduino Nano/GRBL controller.

According to the documentation on GitHub ([https://github.com/gnea/grbl/wiki/Grbl-v1.1-Interface) GRBL requires one of two inferface strategies . . . either a) Simple Send-Response Streaming Protocol or b) Character-Counting Streaming Protocol.

Using a serial protocol analyser I was able to monitor the interaction between LightBurn and the Arduino Nano/GRBL controller . . . and, from looking at the data stream, I was able to confirm that LightBurn is not using the Simple Send-Response Protocol. What I observed was that LightBurn is transferring multiple lines of G-Code to which multiple ‘OK’ responses arrive back some time later . . . I believe this may be the underlying issue that is causing the unreliable Z-Axis RC Servo retraction issue.

I suspect this synchronisation issue has arisen because of the use of the Z-Axis RC Servo to drive the pen/cutter holder in this use case and the inherent ‘slow’ response to this device (compared to a laser). The problem may if fact be present in all LightBurn/GRBL interface scenarios, but simply not an observable problem/issue as the CNC machine manages to ‘keep pace’ with the transfer of G-Code.

I have two questions;

  1. Has anybody else experienced this problem?
  2. Is anybody able to confirm whether LightBurn has implemented the Character-Counting Streaming Protocol required by GRBL when the Simple Send-Response Streaming Protocol is not used?

LightBurn absolutely uses the character counting, fast streaming protocol, because that gives the best possible performance when doing raster engraving. Servo retraction isn’t a standard feature in GRBL as far as I’m aware. It’s possible there’s something that can be tuned, or changed to allow it to work, like a retraction delay, but you’d have to figure out what it requires.

I have an EleksDraw device here that uses an old version of GRBL, and has servo support, and it works correctly. Where did the version of GRBL you’re using come from?

The version of GRBL I am using is “cprezzi /grbl-servo” (https://github.com/cprezzi/grbl-servo).

In essence there are some very simple variations to the standard 1.1f version;

  • Introduction of “SPINDLE_IS_SERVO” #define into “config.h”
  • Some further #definitions “SPINDLE_PWM_MAX_VALUE” and "SPINDLE_PWM_MIN_VALUE in “cpu_map.h”
  • Some limited additional code driven by “SPINDLE_IS_SERVO” #define in “spindle_control.c”

These all look fairly straight-forward and wouldn’t seem to cause the kind of issue I am experiencing . . . although a prescaler on the 8bit timer has to be adjusted to 1024 to generate 61Hz (as close as one can get from the normal 50Hz for an RC Servo).

I did experiment with introducing “G4 P0.1” delays (dwell time) into the G-Code following the M3/M5 that I ‘bulk pasted’ into Tera Term . . . and that did indeed fix the problem . . . however, I don’t see where I could introduce/configure this behaviour in LightBurn?

Other programs typically have post-processors that can be created/configured for required variation in G-Code generated.

Any suggestion regarding how to address this?

Simple G-Code program that demonstrated the problem (two 20mm square boxes, one 10mm from bottom left and second 10mm above and th the right of that).

; LightBurn 0.8.07
; GRBL-M3 (1.1e or earlier) device profile, absolute coords
G00 G17 G40 G21 G54
G90
; Cut @ 30 mm/sec, 100% power
M9
M5
G0X40Y10
M3
G1Y30S255F1800
G1X60
G1Y10
G1X40
M5
G0X30Y40
M3
G1X10
G1Y60
G1X30
G1Y40
M5
M9
G1S0
; return to user-defined finish pos
G90
G0 X0 Y0
M2

G-Code (from LightBurn generated file) that is ‘bulk pasted’ into Serial Terminal Program and transmitted to EleksDraw;

G00 G17 G40 G21 G54
G90
M9
M5
G0X40Y10
M3
G1Y30S255F1800
G1X60
G1Y10
G1X40
M5
G0X30Y40
M3
G1X10
G1Y60
G1X30
G1Y40
M5
M9
G1S0
G90
G0 X0 Y0
M2

There’s no way at present to do what you’re asking with the GCode system. LightBurn’s GCode emitter does a lot of internal state tracking to produce very compact GCode, so it’s not trivial to make a configurable post processor.

Do you have GRBL set to “laser mode”? If so, that might be the issue, because it won’t pause for spindle speed changes like it normally does.

I hate to punt, but ultimately you’re trying to use LightBurn to do something it isn’t currently designed to do. I intend to add features to support vinyl cutting / plotting in the future, but they aren’t there yet.

Modified G-Code THAT WORKS when ‘bulk pasted’ into Serial Terminal Program and transmitted to EleksDraw (simply introducing “G4P0.1” ‘dwell’ after M3/M5 G-Code fixed the problem).

G00 G17 G40 G21 G54
G90
M9
M5
G4P0.1
G0X40Y10
M3
G4P0.1
G1Y30S255F1800
G1X60
G1Y10
G1X40
M5
G4P0.1
G0X30Y40
M3
G4P0.1
G1X10
G1Y60
G1X30
G1Y40
M5
G4P0.1
M9
G1S0
G90
G0 X0 Y0
M2

I also tried smaller delays (0.05s), but that wasn’t enough to fix the problem.

Thanks for the quick and helpful response . . . I did try various combinations of GRBL/GRBL-M3 together with $32/Laser mode on/off, but non of these fixed the problem. GRBL-M3 gave the best result and $32/laser mode made no difference (to GRBL-M3).

The servo output (on D11) is the same output that drives the PWM for the laser . . . so, using GRBL with $32=1 results in a servo that bobbles up and down’ as it approaches corners and other areas where the travel slows down and the laser strength is modulated by GRBL (not optimal behaviour for a pen or vinyl cutter :grinning:)

I have to say, I am very impressed with LightBurn . . . the tools/features/functions are great . . . and the seamless integration of CAD/CAM with CNC direct interface is slick, efficient and makes using it very easy.

I need to further play with import/export, as my first brief attempts to exchange designs/files with Vectric and Inkscape didn’t quite work as expected (but that may be me).

I think the laser functionality/integration is excellent . . . I like this so much that I wanted to also use it for pen/cutter designs too :thinking:

Exporting to AI or SVG should work fine for Vectric. (I usually use AI there). InkScape doesn’t like the AIs I produce because the format is ancient, and InkScape is looking for PDF/AI, which is the newer (dramatically more complicated) version, but SVGs work there.

Is there any way that a ‘device’ setting could be introduced alongside X & Y size specification that would allow switching on/off addition of a '‘G4P0.1’ delay as part of the M3/M5 G-Code insertion?

This would seem achievable at a low cost/effort without having to significantly modify or refactor the GCode emitter . . . and would fix the issue (and any other associated requirement for timing adjustments following PWM/spindle speed changes).

:heart_eyes::grin:

You might’ve missed this:

So yes, it’s absolutely possible, it just requires time to implement the back end and the UI.

No, I did spot that . . . and great news that I await the release of with some anticipation (on the back of an already great product.)

The only thing I have found that comes close to the integration you have achieved is the Vectric offering . . . but it’s handling and support for direct CNC integration is poor (and even more poorly documented).

Keep up the good work.

When this is ready, please add me to the list of beta testers,

Having identified that the underlying problem appears to be a timing issue in the modified (servo support) version of GRBL 1.1f, I looked for alternative solutions . . .

. . . I discovered that grbl 0.9i (servo support) modified version found here (GitHub - robottini/grbl-servo: grbl 0.9i with Servo motor support) works. This requires LightBurn to be configured in grbl M3 mode.

  • In grbl 9i there is no 'laser mode ($30, $31, $32)
  • M3 is used to lower the pen/servo
  • M5 is used to raise the pen/servo

$$ Settings are;

$0=10 (step pulse, usec)
$1=25 (step idle delay, msec)
$2=0 (step port invert mask:00000000)
$3=0 (dir port invert mask:00000000)
$4=0 (step enable invert, bool)
$5=0 (limit pins invert, bool)
$6=0 (probe pin invert, bool)
$10=3 (status report mask:00000011)
$11=0.010 (junction deviation, mm)
$12=0.002 (arc tolerance, mm)
$13=0 (report inches, bool)
$20=0 (soft limits, bool)
$21=0 (hard limits, bool)
$22=0 (homing cycle, bool)
$23=0 (homing dir invert mask:00000000)
$24=25.000 (homing feed, mm/min)
$25=500.000 (homing seek, mm/min)
$26=250 (homing debounce, msec)
$27=1.000 (homing pull-off, mm)
$100=100.000 (x, step/mm)
$101=100.000 (y, step/mm)
$102=250.000 (z, step/mm)
$110=2500.000 (x max rate, mm/min)
$111=2500.000 (y max rate, mm/min)
$112=2500.000 (z max rate, mm/min)
$120=100.000 (x accel, mm/sec^2)
$121=100.000 (y accel, mm/sec^2)
$122=100.000 (z accel, mm/sec^2)
$130=250.000 (x max travel, mm)
$131=175.000 (y max travel, mm)
$132=1.000 (z max travel, mm)

For this you would just use the GRBL-M3 device driver, instead of GRBL. It uses the M3/M5 pair to enable / disable the laser or pen.

Yes . . . works perfectly

I have created a modified ‘spindle_control.c’ based on the current grbl 1.1g version, which provides full support for an RC Servo on Arduino Pin D11 (GitHub - DWiskow/grbl1-1g-Servo: modified spindle_control.c to introduce RC Servo control into grbl 1.1g).

To use this, download the latest version of grbl (1.1g) from github and replace ‘spindle_control.c’ with the version provided in the above link. You will also need to select/modify SPINDLE_TCCRB_INIT_MASK in ‘cpu_map.h’ to select the appropriate (61Hz) servo frequency rate and, of course, select/modify VARIABLE_SPINDLE in ‘config.h’ . . . all other required #define(s) are contained with the modified ‘spindle_control.c’. All lines of code that have been added to ‘spindle_control.c’ are marked with a comment in column 100 of their respective lines. Apart from these 31 new lines of code (and an additional SPINDLE_TCCRB_INIT_MASK in ‘cpu_map.h’), the rest of the grbl 1.1g source is unchanged.

The #define RC_SERVO_SHORT (15) and RC_SERVO_LONG (31), in the modified ‘spindle_control.c’, set the PWM duty cycle for the RC Servo to 2.05ms and 1.03ms respectively (these are recommended values for standard RC Servos). There is also a #define that allows the servo to be inverted if movement of the arm is in the wrong direction.

Note: the added RC Servo functionality will only operate in ‘non laser’ ($32=0) mode and will be ignored if you have $32 set to 1 (however, the frequency SPINDLE_TCCRB_INIT_MASK set ‘cpu_map.h’ will still be 61Hz rather than the default 0.98kHz used by most diode laser PWM/TTL inputs). To use this functionality use G-Code M3 to turn on the RC Servo and G-Code M5 to turn off the servo. The amount the RC Servo moves is controlled with G-Code S commands in the range 0-255.

M3 S255     (turn servo full on)
M5          (turn servo off)
M3 S125     (turn servo half way)
M3 S0       (turn servo on full off - similar to M5)
1 Like