GRBL Firmware Bug

Look at this:
burn

Yes, my laser cutter went crazy and have burned the base plate.

Am I right blaming GRBL firmware? Well, it is not black and white

Here is the project I made in Inkscape.

Design looks pretty legit in Camotics and in Universal G-Code Platform
So the G-Code I had was correct. Yet, GRBL went crazy. Look at the left picture:

morph

So what went wrong? Inkscape J Tech Photonics plugin generated G-Code with some high-accuracy curves. Some curves had center far away. Some had it as far as 33000 mm away.
But GRBL runs on 8-bit Arduino which could handle 32 bit integers but perhaps GRBL was not designed to do so, or something. It looks like some variable overflow.
The bad thing is – you cannot tell it ahead of time just by looking at rendering of your gcode in viewers (because the viewers can do high accuracy math)

However, as you probably guessed by looking at the right picture, I have found a way to resolve the problem. At least, this time.

Well, I just had opened the g-code file and replaced a few G2 and g3 with G1 and removed I and J. Rationale: when the center of your arc is 33 meters away from the arc, the arc is indistinguishable from a line. So I just replaced it with a line – that simple.

Update:
I have filed a bug report.
In a meantime, I have a fix.
You can either trust me and download a binary package, or do not trust me and compile it from sources.
You will need to pull in 2 C# libraries: one in sources from github (gsGCode) and one through nugets (geometry3Sharp) and build it all together with the following code:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FixGCode
{
class Program
{
static void Main(string[] args)
{
if (args.Length == 0)
{
Console.WriteLine(“Please provide GCode file name”);
return;
}

TextReader input = File.OpenText(args[0]);

gs.GenericGCodeParser parser = new gs.GenericGCodeParser();
gs.GCodeFile f = parser.Parse(input);

foreach (gs.GCodeLine l in f.AllLines())
{
if (l.N == 2 || l.N == 3)
{
bool convert = false;
int idx;
// Check I
idx = gs.GCodeUtil.TryFindParam(l.parameters, “I”);
if (idx > -1)
{
if (l.parameters[idx].doubleValue > 8192 || l.parameters[idx].doubleValue < -8192)
{
Console.WriteLine($"In line {l.lineNumber} I was {l.parameters[idx].doubleValue} changed to G1");
convert = true;
}
}

// Check J
idx = gs.GCodeUtil.TryFindParam(l.parameters, "J");
if (idx > -1)
{
if (l.parameters[idx].doubleValue > 8192 || l.parameters[idx].doubleValue < -8192)
{
Console.WriteLine($"In line {l.lineNumber} J was {l.parameters[idx].doubleValue} changed to G1");
convert = true;
}
}
if (convert)
{
l.code = 1;
l.N = 1; // G1
List plist = new List();
foreach (gs.GCodeParam p in l.parameters)
{
if (p.identifier == “I” || p.identifier == “J”)
{
continue;
}
plist.Add(p);
}
l.parameters = plist.ToArray();
}

}
}

StreamWriter sw = File.CreateText((string)args[0] + “.patched”);

gs.StandardGCodeWriter w = new gs.StandardGCodeWriter();
g3.IOWriteResult result = w.WriteFile(f, sw);
sw.Close();
Console.WriteLine($”Finished. {result.message}”);
}
}
}

If, however, you prefer binaries, please download and unpack this:
FixGCode ZIP archive

Please note, that I do not provide any warranty. I just did not study GRBL sources enough to tell that it will cover all cases.
Please also note that I limit I and J to 16383, not 20194. That’s just for peace of mind. I do not know whether bug limits depend on current position, so I want to play it safe.
However, in my case it makes G-Code generated by Inkscape plugin “J Tech Photonics” safer.

** Update: I re-wrote the code and now replace G2 and G3 with G1 (straight line). I also reduced threshold to 8192.

One more thing. There are 32 bit microcontrollers running GRBL.
You might think, that if you buy 32 bit ARM board, this problem will disappear, since whatever overflows 8 bit microcontroller shall be fine in 32 bits. I have bad news for you. I looked at a couple of STM32 GRBL source repositories and they carried over all those kludged to workaround 8-bit Atmel 328P limitations (nightmare warning: don’t look at that code before going to bed!) I did not give it a try, but very likely 32 bit microcontroller board is susceptible to the same bug :(

Update: I have got an STM32 GRBL from Aliexpress and I confirm that the bug is still there.
I do not confirm that the system is really STM32 though – the microcontroller has a sticker on it – maybe I shall peel it off and see what is under it.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>