Thanks for your input here, I was hoping you’d but in!
So what you are saying is there is no other logic control on the Carbide board other than the GRBL code running/ processing. So it does not know what state its in as in connected or not or whether it has switched on the router or not. It just polls for GRBL code to process and nothing else?
The reason I asked this was because this happened to me while I was cutting MDF (before my CM board flaked out different story) and the cutter stopped moving whilst cutting a slot. I did not realise for maybe a minute or so until the sound difference registered I then hit the emergency stop. It was concerning because of the obvious risk of fire. Other than vigilance is there any other way to mitigate this risk? I love the BitRunner by the way.
I found this gcode M85: Set inactivity shut down timer
Edit: I just checked the Shapeoko gcode wiki and M85 is not listed as supported. But in the same wiki under GRBL code not supported M85 is not listed so does GRBL support M85 but Carbide Motion does not?? or do I just not get it.
Yes. GRBL manages various machines states: Idle, Run, Hold, Jog, Alarm, Door, Check, Home, Sleep. But (again, to the best of my knowledge) it cannot assume that the host computer will continuously send data, not in Idle (because it’s a normal state that the host would do nothing), and not in Run mode because arbitrarily long pauses are allowed, so GRBL cannot just consider that an absence of commands from the host is a problem.
I’m afraid not, not without modifying GRBL.
It could do that, with the caveat mentioned above that it is not easy to know whether the host not communicating/sending commands is abnormal or not. The easiest would be a timeout indeed, but whether this timeout could be set to a relevant value is another question (if the longest valid period with no commands from the host was set to, say, 30 seconds, G-code delays would be limited to 30 seconds (not a big deal), but 30 second could be too long in your “router is rubbing in MDF” scenario.
This seems to be a specific G-code implemented in 3D printer (e.g. Marlin firmware, a remote sibling of GRBL), to shutdown the printer after a job.
The current version of GRBL does not implement it:
Maybe it could be added in the GRBL code, then you would have to either set it to a value large enough that the nominal job can finish (which would make it useless from a protection standpoint, in long jobs), or set it to a small value and keep inserting it every N lines in the G-code file to restart the timer continously. And then you would have to be really cautious about all the false positive detections of inactivity, or people would get mad that they job got interrupted mid-run for no good reason.
So I guess the bottomline is
to try and eradicate USB disconnects instead. There are a number of things that can be done to minimize the occurrence, but I am quite aware that in some setups, for a variety of reasons it is difficult to reach the “no disconnect, ever” state.
keep an ear (if not eye) on the cut (which in my book is best practice anyway). A machine that is not moving/not cutting anymore while the router is still on is easy to recognize by ear.
All that said, I like your idea of some kind of self-detection of disconnects inside GRBL so that it goes to a failsafe state. Hopefully GRBL’s developer (@chamnit) will see this message and share his insights on the matter, which ought to be much better than mine.
Thanks for that in depth analysis. So relying on GRBL as a failsafe is not really practical. In that case some sort of “Keep alive” on the USB/ Serial circuit separate to GRBL, but as we have established there is no other logic on the CM board. This is an important safety issue but I must admit as a programmer its sucking me in.
You could still have GRBL in the loop (I have yet to hear about a GRBL reliability issue), but the question would be how to send it the information that the USB comms went down. If you felt adventurous, and knew your way around the MacOS/Windows USB stack, a possibility could be to have the G-code sender monitor the USB status, detect a loss of comms, and in that case activate a local relay/switch that would trigger the “feedhold” input on the Shapeoko controller: GRBL would detect the feedhold signal activation, and would execute the “safe retract & stop spindle” routine. Interesting week-end hack, but not a practical solution for “regular” users.
There is a ‘SLEEP’ state in the Grbl-Mega version that addresses USB disconnects. Grbl will expect a communication from the host within a fixed time, reset by the last comm. This is often handled by the host by sending ‘?’ status report queries. If Grbl does not receive a communication in time, it’ll automatically go to sleep, by shutting down the spindle/coolant and parking the machine. See config.h comment below on how it works.
It didn’t install this on the standard 328 build, because it wouldn’t fit with certain features enabled.
//Enables and configures Grbl’s sleep mode feature. If the spindle or coolant are powered and Grbl
// is not actively moving or receiving any commands, a sleep timer will start. If any data or commands
// are received, the sleep timer will reset and restart until the above condition are not satisfied.
// If the sleep timer elaspes, Grbl will immediately execute the sleep mode by shutting down the spindle
// and coolant and entering a safe sleep state. If parking is enabled, Grbl will park the machine as
// well. While in sleep mode, only a hard/soft reset will exit it and the job will be unrecoverable.
// NOTE: Sleep mode is a safety feature, primarily to address communication disconnect problems. To
// keep Grbl from sleeping, employ a stream of ‘?’ status report commands as a connection “heartbeat”.
// #define SLEEP_ENABLE // Default disabled. Uncomment to enable. #define SLEEP_DURATION 5.0 // Float (0.25 - 61.0) seconds before sleep mode is executed.
It’s been a couple of years since I installed it. Usually the big flash eaters are the COREXY and PARKING options. The latter is standard on Carbide machines, I think. I would say that there is a small chance it could fit without COREXY.
Ok, just because it sounded like a fun week-end challenge, I had a go at this and merged the SLEEP mode from Grbl-Mega into Grbl, and adapted it to the ATMega328.
Since all timers are already used in the code (the three timers and one watchdog timer), I had to sacrifice something. The three timers are used to control the stepper and PWM signals, so that’s a no-no. I noticed that the watchdog timer is used only for the optional “software debouncing” of the limit switches, which is not enabled in the Shapeoko firmware anyway, so that’s what I hacked.
Luckily the added code fit in the memory when using the Shapeoko configuration, 176bytes short of the 32256 bytes limit. Phew.
Anyway, here’s a first test using that patched firmware, and pulling the USB cable while the spindle (and shopvac…) are running, with SLEEP mode enable and a 5 seconds timeout value
(warning: turn volume down)
The spindle stops and the machine parks upon pulling the cable.
So it works fine when using Carbide Motion (which does send a continuous stream of status queries to the controller, keeping the firmware alive), but that’s when I realized that CNCjs does not, which is a problem for me since I use both (and I don’t feel like patching CNCjs to send commands continuously), so I guess this will remain a fun experiment for now.
This is fantastic well done @Julien. If its doable then I think it should be considered by carbide3d as an important safety update to the system. I’m fitting my replacement board today/ tomorrow so I think this is a must do, especially when using the BitRunner. Again well done. See I said it should be possible, even though I had no idea how I’m going to need to pick your brains to get this into my new board.