Klipper CNC Spindle RPM

Hello everyone,

I’m looking into using Klipper to control a cnc servo spindle. How do I determine the rpms? And how do I determine them if using gear ratio. Ex: 1:5.

I’ve reviewed the PWM tool documentation and perused the cnc pages on here.

I’m wondering if anyone knows how to setup the config for something like this.

I’m new to Klipper and GCODE etc. I would like to write some macros but I’m unsure how to figure out the rpm’s.

I see configs that look similar to this:

[output_pin TOOL]
pin: !ar9 # use your fan’s pin number
pwm: True
hardware_pwm: True
cycle_time: 0.001
shutdown_value: 0
maximum_mcu_duration: 5
##Default: 0 (disabled)
##Amount of time in which the host has to acknowledge
##a non-shutdown output value.
##Suggested value is around 5 seconds.
##Use a value that does not burn up your stock.
##Please note that during homing, your tool
##needs to be in default speed.

Thank you for your help in advance.

You will have to look up the specifications in the documentation of your spindle driver. The PWM allows to create a pulse with a specified duty factor. How to translate this duty factor into RPM is unrelated to Klipper and totally depends on your driver and motor. It is very well possible that you will not even find a clear specification, in which case you have to help yourself with some estimates. You could e.g. crank up the duty factor until the spindle starts - this is your zero offset (let’s call it xstart). Then you continue cranking up the factor until the speed is no longer increasing and assume this to be the rated RPM of your spindle (let’s call that duty factor xmax). Then you can assume that the relation in between is linear. So the conversion formula would be (with x being the duty factor):

actual_rpm = (x - xstart)/xmax * rated_rpm

or turned around:

x = actual_rpm/rated_rpm * xmax + xstart

I hope this helps you as a starting point.

PS: I have written a small Klipper module to control the spindle speed from GCODE. Note, in my case I have a completely different interface (Modbus-based communication with my inverter). The interesting part might be that it allows to change the spindle speed synchronously with the feed rate modification factor with the M220 GCODE command. This can be very helpful since it allows to reduce/increase speed on the fly during the milling process while keeping the basic milling parameters (pitch - I hope this is the right translation for the German “Zahnvorschub”?) correct. If you want to use it, you will have to modify it quite a bit though, since it does not interface with the PWM at all right now.

I’ve made my own module

@mhier @linuxpaul

Thank you for taking the time to reply to my post. It seems like you two have done a lot of great work. It will take me a little bit to dig into your replies and to get a chance to work with your suggestions. I’ll report back and I’ll also report back if I have anything good to add.

Thank you again. I’m really eager to try these suggestions out.

Quick question:

Would the config file just need to have these variables listed out?

‘power_pin’ (would this just be one of the PWM tool pins? Or could it be one of the stepper power pins?)

‘pwm_pin’ (is thus just the other PWM tool pin? Or the other stepper power pin?)

‘pwm_freq’ (looks like mine is 0-300). Would I put in 300?

‘max_rpm’ (if I have a gear ratio then I would enter in the max for the driving spindle and do the math for the actual tool spindle correct? I.e. driving spindle is 5000 so the tool speed would be 1000. It’s a 1:5 ratio.

I pulled those from here.

    # Read config
    self.power_pin = config.get('power_pin')
    self.pwm_pin = config.get('pwm_pin')
    self.pwm_time = 1 / float(config.getint('pwm_freq'))
    self.max_rpm = config.getint('max_rpm')

Would it need anything else? Would you mind sharing a sample?

Also I found this from my motor.

I’ve a Maffel PV1000 ER connected with this cnc shield. My spindel requires an analog input of 0V -10V and has no direction selector. In your case you shuold get shure to provide 5V signals and you should make an adaption from my code.

This is the config for my Maffel
power_pin: PD4
pwm_pin: PD5
pwm_freq: 8000
max_rpm: 24000


I’m digging into this a little more. I was able to figure out how to insert a module into the extras folder/location. I inserted the spindle.py module.

I could use some help on how to calculate the pwm_freq parameter if you’re willing.

I was able to find a video online of a servo motor that was similar to mine (possibly the same but mine is rebranded).

I learned that there is possibly a linear relationship between KHz and rotation on my servo. Here are some numbers that I was able to grab from a YouTube video.

1 KHz = 75.5 rpms
40,000KHz = 3000 rpms

Two equations used in the video:

Equation 1 is revolutions/Hz
3000 rpms/40000 KHz = 0.075 rev/Hz

Equation 2 is Hz/rev
1/0.075 = 13.333 Hz/rev

Could these numbers help with finding the pwm_freq? I tried some numbers and it seems like 0.075*1000=7500 which comes out close to the 8000 given in your example.

I’ll take a look at your module soon now that I know how to look at them and use them. If you or someone reading could help with the above, I would be most grateful.

Thank you very much for your help.

PWM has a fixed frequency and a various duty cycle.

You need to know at what frequency the PWM is expected by the inverter and what speed your spindle has at a duty cycle of 100%.

What you describe above seems to be how the inverter controls the motor, right?
Unfortunately, I don’t have a spindle with an inverter. If you need help depinding the inverter, then these colleagues are not bad. The group is in German, but I think they can also help in English.

Hi @mhier,

I still working on setting up my configuration etc. I’m now starting to focus on the spindle a little more. I followed your link to your GitHub, which I found on by clicking on your name. Is there a certain config, helper, and kinematics that you are using? Or do you have a module in the extras folder for that GCODE that you mentioned?

As I said, this is highly tailored towards my special setup and in no way generic. I have a Linux shell script which does the actual communication with the inverter. You will have to replace at least that part. There are no Klipper configuration settings, everything is hard coded.

spindle.py is the Klipper module, I have copied this into my extras folder.

1 Like

Thank you, I’ll take a look. I may try Marlin to see if it will suit my needs a little better.

Many thanks to you for your replies and assistance.