grbl/grbl — Issue #48: Form and function of status reporting.
Author: chamnit
Created: 2012-01-23 06:26:42+00:00
State: open
Labels: conversation

Status reporting is a new feature just being built into the grbl/edge v0.8a branch. I'd like to start a discussion on how the status reporting should look like, what should be included, how it works, and answer some other questions like its flexibility in the future or for users that want to hack it. Here are a few things I've been thinking about:

1. For portability and hackability, I'm considering re-organizing and placing the status reporting feature into its own *report.c* source file, instead of its current location as a function in *protocol.c*. Here it should be clear what this source file is, what it's function is, and a place for user to freely hack at it for their own nefarious needs. The required data for reporting would likely need to be re-organized a bit as well, so a user will have direct access to everything they will need.

2. Perhaps the biggest question is what will users need in the status report? Here's a list of things that are minimally required/needed on CNC mill and lathes, but some of these features are not necessarily needed for other machines/robots. To keep with the spirit of grbl, what needs to be there and what doesn't to maintain simplicity? Everything listed here are items that cannot be done off-board by an interface.
* Current XYZ position - This is the real-time position in the work coordinate system (G92) or aka part zero. This is the most important information a user would need and could be supplied in terms of mm, inches, or steps.
* Machine XYZ position/coordinate offset - This differs from the work position as being the absolute real-time position/offset from the machine home position. This needs to be retained so grbl knows where home is and may be used to establish the absolute travel limits of a machine without using physical limit switches. There are not many cases that this information would be needed in real-time, but can be very useful.
* Buffer state/size - The planner buffer state or how many blocks are stored and ready to go in the buffer. This is a great indicator of how grbl is doing when under heavy load or showing if grbl is having buffer starvation problems. Again, not needed for all users, but extremely handy and relatively easy to implement.
* Feed rate (& spindle speed) - The realtime feedrate may used to monitor feed rates through complex curves and acceleration profiles. This would be based on the trapezoid_adjusted_rate value in the stepper module.
* Line number in-process - The problem is what defines the line number. Is it the g-code 'N' line command (not required or consistent) or simply based on an internal count of incoming lines? The latter would be simpler and more accurate. The line number being processed would help a user to directly correlate where a problem is in a g-code program and compute distance to go off-board. Could be fairly easy to implement, but require some memory to track these.
* States - Reports the stepper module state, i.e. cycle start, feed hold, and possibly feed rate override (when integrated).

3. The next question is what should a status report look like? In general, the status report should be kept at a relative minimum to reduce the amount of cycles for each status report, especially for setups that need reporting 10-20 times a second. It should be straight forward and human readable. There is also the consideration that a non-human readable binary format could be included to keep the cycle budget to an absolute minimum, but would need to be used with an external interface to interpret the binary data. The need for a binary format may be debated, but here is an idea for a human readable format.
* `Grbl:Running,Ln:203,Buf:15,Rate:300.0,MPos:[0.00,10.02,4.34],WPos:[-10.00,2.22,5.00]`
* `Grbl:` Lists the current _[Running, Hold, Idle]_ states
* `Ln:` Line number in-process. Reset to zero when buffer empties.
* `Buf:` Number of blocks left in planner buffer
* `Rate:` Real-time feedrate
* `MPos:[x,y,z]` Real-time machine position in mm/inch/steps (or maybe in terms of coordinate offsets?)
* `WPos:[x,y,z]` Real-time work position in mm/inch/steps
* Also, if needed, the reports could be tailored, where certain items in the report can be toggled on or off via some EEPROM settings or bitmask. For example, if the line number, buffer state, and machine position aren't needed, a user can set the EEPROM settings to show instead: `Grbl:Running,Rate:300.0,WPos:[-10.00,2.22,5.00]`

4. The last critical question is how should it work? First, the current implementation allows for some flexibility in how to do this. All that needs to be done is to set a bitmask in a system byte to print the report. This could be done in a number of ways, via the current '?' character, an internal timer, or even some external signal on an I/O pin.
* Right now, when a '?' character is sent to the serial receive buffer, the run-time execution routine will reply nearly instantanously with the status report, regardless of what grbl is doing. For an interface, this would mean that it would need to send '?' characters at some periodic rate. ('?' may be changed to whatever special character, like control characters or extended ascii.) So is this good enough?
* The main problem I can see with the current implementation is how it complicates the grbl streaming interface. If a user is streaming a file, their interface would need to send the '?' command whenever they need a report and then read and process the report in their serial buffer. At some point, I'd like to install XON/XOFF flow control into the serial module to make streaming g-code less of a hassle. Improving/changing the way grbl streams is a whole other conversation, and the way status reporting works should be a consideration with this.

Anyhow, I think most of these functionalities should be integrated into grbl by design, but they do not necessarily have to be implemented. In other words, it should be very simple for a user to 'turn on' these features or whatever they may need without much fuss. Most of the stated report data is already stored in a global struct 'sys', and the others could simply be moved into this.

Simen, Alden, Jens, or anyone else.. What do you think about this?