G03 Support and Limitations

I’m writing some gcode to cut a part and used G03 with X,Y and R and it didn’t work. Is there a list somewhere of the supported G codes and any limitations? I may redo the gcode and use IJK, but wanted to check first that there are problems with XY and R on G03


The firmware currently expects IJK for the G2 and G3 codes, the radius mode has not yet been written. CNC_Functions.h around line 883…

1 Like

Hmm, OK, that explains that. I looked at the code to see if G03 was supported, but didn’t look at the details. I’ll rewrite the gcode.


What does the current arc code use for segment size? While the encoder step size would give the smoothest arc I’d guess it’s not practical for no acceleration full stop mode.

Just curious, big arc fan

Uses the same step size as line segments, a function of feed rate and LOOPINTERVAL which is the frequency of the PID loop in microseconds - currently 10000.
LOOPINTERVAL*(MMPerMin/(60 * 1000000));

In round numbers, 5 thou or a tenth of a mm at 25ipm/10.5mm/s, figured from the 10ms interval. I’d guess you could run at full speed on most arcs.

Hmm, I’ve changed the gcode I’m using to generate arc segments at small intervals. This does cause the cutter to move where I want it, but the movement is jerky, which causes what would have been a smooth arc to be quite irregular. I suspect this is due to no look-ahead of the gcode, or some processing hold-up. Does the firmware do look-ahead? By this I mean if it sees a move to X,Y followed by a move to X1,Y2 then X2,Y2, does it move the sled from X,Y to X2,Y2 through X1,Y1 without stopping?
I also rewrote the code to use G03 with I and J parameters, but with a radius of 3400mm it looked like there was overflow somewhere and I got a mismatch between the red and white crosshairs in GC, so the cut didn’t work.

Any suggestions on how I can cut a smooth shallow curve (radius 3400mm) between two points 340mm apart?


No lookahead yet. Maybe try a slower cutting speed?

Yes, I tried that and it did improve things, but I still saw pauses. That was going from a feed of 1000 to 300. It’s really quite slow now. Maybe I can try a longer increment which will result in less command sbeing sent.

1 Like

Longer increments is a good idea. Sending many small lines will slow things down.

This is something I’ve been thinking about taking another look at. While look-ahead would help, the big bottle neck right now is that the firmware finishes running a line, then asks for another, then runs it and there is a substantial lag between asking for a line and getting it. The solution is to have the firmware buffer several lines ahead, and the code for this is written, but we were running into issues where some computers would mess up maybe 1 out of 100 or even 1 out of 1000 lines so everything would be mostly OK, but then occasionally a line would be corrupted and the cutter would go rogue. Because the issue was so hard to debug since it occurs randomly and seemed to depend on the serial hardware in the computer we put it on the back burner. It might be worth revisiting that issue now

Do you do any checksum or CRC checking to see if the received lines are good?

Just speculating, but if you’re buffering ahead while running (as opposed to reading while idle) could you be missing an occasional character? Do/can you check for an overrun? Pretty much all the serial chips I worked with (have to admit it was some time ago) reported an overrun status either with an interrupt or at least a status bit), no idea how the USB to serial devices combined with the 2560’s serial interface handle this, although I see there’s a port.overflow() function to check for it

Isn’t G03 processing done in the firmware, with the arc to line segment processing not needing any more gcode lines through the serial port?

There is no CNC check in the protocol, it’s a pure dump of g-code (and the
protocol can’t really be changed due to compatibility with other CNC systems,
grbl for example)

The serial connection to arduino does not have any flow control available, it’s
just tx/rx lines connected (same thing for grbl systems)

This interface is USB based, which means that data is sent in USB packets, not
byte-by-byte and there is a buffer on the chip that the data is dumped into.

This means that the sender has to know how much data has been sent, how much has
been processed, and avoid overrunning the buffer.

it’s messy.

I’ve spent some time in this part of the code. Things I found useful are:

  • Wireshark will do packet capture of the USB stream, so you can see what leaves GC
  • In the Mega2560, the RX and TX lines on the uP side of the USB chip are available so a TTL-to-SerialUSB can listen in on the traffic arriving
  • the Mega2560 has Serial1 which can be used to echo the characters as they are put into the buffer

I’ll bet there are some of the pertinent parts lurking in the corners of a moose’s workbench… :wink:


Doesn’t the mega2560, unlike the 1280, have a separate usb to serial chip that then pumps a real serial bitstream (async start and stop bits included) into the tax and rx ports on the MCU? On the internal USB interface chips like the 1280/90) serial speeds are irrelevant since it runs at USB speed but with offchip conversion all the usual considerations apply.

I must have been thinking of Repetier-Host’s error checking. I see grbl doesn’t even have an error number, or even a simple nak, to report an overrun (or parity error, but they don’t do that) and trigger a resend. Really don’t like that (think converting 123.45 to 13.45), but that could be 20+ years of programming async and bit/byte synchronous protocols on lots of different hardware.

At least for testing there really should be an overrun check with the grbl preferred full stop if one’s detected, since resend’s not an option. Dropping occasional random characters makes for really weird intermittent bugs.

1 Like


There’s an opportunity for a firmware issue-enhancement :smile:. A very good idea. Use an Advanced setting to turn it on/off, or rely on a compile-time choice?

1 Like

There’s a very nice compile-time variable ‘verboseDebug’ in CNC_Functions.h which when set to 2 outputs ring buffer statistics and contents each time the serial buffer is added to (see readSerialCommands()). Thank you @krkeegan, I believe :smile:.
That would be a troubleshooting tool, as well.

Sounds handy, but wouldn’t that interfere with overrun detection? OTOH, it would be good to do after an overrun detection

I LOVE the “make it a setting” idea. That way we can experiment to find out what works without messing up everyone’s cuts (which is why I’ve been afraid to test it). If I remember right all of the changes are on the Ground Control side so it should be relatively easy to make into a setting


How will the firmware know whether to expect a crc? Whether to use it before stripping the gcode line?