Grbl PWM output for spindle control [Fixed in build [1.0c.20160304]



It is OK to program S0; the spindle will not turn if that is done.

In this LinuxCNC web page:

It is OK to program S0, the spindle will not turn if that is done.

Without giving away what I’m doing (like working on a spindle speed project) I would like to get some clarification on the way that grbl is supposed to work.

If I issue an M5 g-code instruction the grbl spindle PWM output is LOW. If I issue an M3 g-code instruction then the grbl spindle PWM output is pulsed HIGH. M3 with S(max rpm) PWM is HIGH. So far, its good.

With 0 defined as the minimum rpm if I issue an S0 with M3 active then the grbl spindle PWM output is not LOW. It is a very narrow pulse.
5/255 = 0.0196 so I would expect this.

[version 0.9j]
Would like to know if this is indeed the way it should work so that I can handle this condition in my project.

Thanks for your help…

You’re right. S0 should turn off the spindle. The math needs to be corrected.

1 Like


I’m not sure that the calculation is wrong. If the requested rpm is equal to the (min rpm) setting then you would want the smallest pulse, but if the requested rpm was 0 (min rpm = 0) then you would not want a pulse.

This might be a better fix.

Current code:
void spindle_set_state(uint8_t state, float rpm)
// Halt or set spindle direction and rpm.
if (state == SPINDLE_DISABLE) {


} else {

Proposed change would be:

void spindle_set_state(uint8_t state, float rpm)
// Halt or set spindle direction and rpm. Halt if rpm request = 0
if ((state == SPINDLE_DISABLE) || (floor(rpm) == 0) ) {


} else {

[Edit] Well it’s not quite that simple. If you made the suggested change there would have to be a way to re-enable PWM if another S command came in to change the rpm to something new.

Ok, on further testing it may be an issue with the use of counter/timer in the 328P.

I made the following change, as a test:
current_pwm = floor( rpm*(PWM_MAX_VALUE/SPINDLE_RPM_RANGE) + 0.5);
current_pwm = 0; /* testing */

When I run this code I get a recurring 500nS pulse on the D11 pin with a frequency of 7.81KHz.

Is this what you would expect?

500nS is 1/256 of 1/7.81kHz, or the minimum 1/256 duty cycle. There just needs to be some code to disable the spindle pwm pin (and allow other conditions to execute too). It’s an easy fix. I’m working on other things are the moment, but I’ll address it soon as a bug fix update to the main repo.

Ok, thanks.

Ok finally got around to it. I updated the code on Grbl’s website. It should work as you’ve outlined. Please test it to make sure it’s working properly. I don’t have much time to do a lot of testing these days and depend on the community to help out.

Thanks. Glad to help. I’ll get to it as soon as I can and let you know the results.


Just tested build[1.0c.20160304]. This works as expected.

Thanks for the fix.