christianermann.dev-hugo

The Hugo source for my website
git clone git://git.christianermann.dev/christianermann.dev-hugo
Log | Files | Refs | Submodules | README

commit 6db462fd21624cce1b3069d31f66ed0a08b24dc4
parent ef6a32b5d6e2ca58b0f892014a096e4ff8017671
Author: Christian Ermann <christianermann@gmail.com>
Date:   Tue, 12 Nov 2024 12:58:30 -0800

Add 'Writing a G-code Interpreter'

Diffstat:
Acontent/posts/gcode-interpreter.md | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+), 0 deletions(-)

diff --git a/content/posts/gcode-interpreter.md b/content/posts/gcode-interpreter.md @@ -0,0 +1,74 @@ +--- +title: "Writing a G-code Interpreter" +date: 2024-10-23T16:29:40-07:00 +tags: [G-Code, Lasers, C] +draft: false +--- + +I'm currently working on a control system for a laser galvanometer (galvo) that +I want to use in a stereolithography (SLA) resin printer. I don't want to write +a custom slicer, as I feel like model slicing can be incredibly complicated and +existing free software (Cura, Slic3r, etc.) has many advanced features I don't +want to reimplement. However, this means my control system needs to understand +G-code, the language that these slicers output. + +As stated on the [reprap wiki](https://reprap.org/wiki/G-code), "G-code is a +list of fields that are separated by white spaces or line breaks. A field can +be interpreted as a command, parameter, or for any other special purpose." For +now, we'll ignore any special purposes. Here is an example of G-code that +describes a movement of the tool/hotend/laser to a specific location: +```gcode + G1 X10.4 Y7.4 Z8.3 +``` +I was able to parse commands with parameters using a two-stage procedure: + + 1. Retrieve the next white-space delimited token. + 2. Accumulate tokens until two separate command tokens are found. + +This second step is important because we can't begin executing a command until +we've found all of its parameters and we don't know if we've found all of its +parameters until we find the next command. + +Once a command and all of its parameters have been parsed, it is passed to the +controller which updates the state of the machine. For each command that the +controller receives, it has to update its internal state, and in the case of +physical movement commands, send the proper signal to the laser galvo. Most +physical movement commands utilize interpolation so a timed control loop is +utilized to ensure the laser follows as close to the intended path as possible. + +## System Diagram +```goat + more params? + .----------------------------. + | | + v | + .-----------. token .-------------. + | tokenizer | --------------> | accumulator | + '-----------' '-------------' + | + command w/ params | + .----------------------------' + | + v +.--------------. ctrl signal .-------------. +| controller | -------------> | laser galvo | +'--------------' '-------------' +``` + +## Source Code +The source code for the G-code interpreter can be found +[here](git.christianermann.dev/gcode-interpreter). You may have issues +accessing the link if your ISP doesn't support IPv6 yet. + +Also, the names in the code are different than what's shown in the diagram, so +here's the mapping to help out with understanding the code: + +| Diagram | Source File | +| :---------- | :---------- | +| tokenizer | token.c | +| accumulator | command.c | +| controller | machine.c | + +I'll try to keep this updated if the mapping changes as I continue to work on +this project. +