Feature request: add klipper MCU input mode

I think you are on to something. The synchronization between the “master” Klipper processor is self-explanatory essential. That is the beat to which the whole thing works. In the Klipper protocol there is a way of doing that. So that should give us a now synced between all sub-MCUs. The really interesting stuff is the ramp I agree. In other words the ramp is the movement to hit the target position in time. If the force to uphold the ramp is somehow shortcoming, the control “algorithm” will apply more torque (up to a limit).

One thing to consider in that regard, now we are at the subject, does it make sense to use another profile then trapezoid, perhaps S-shaped

This I guess is what you mean by tweaking higher level motion planing, under the hood stuff

I have mentioned this before, but because it may proof to be a good source for inspiration, Mark from the OpenPNP community worked on S-curve motion for PNPs. Not sure how exactly, just pinning this :pushpin:

since klipper is doing the planning, and it does trapezoidal moves, that’s that we should plan to implement. I could see us ALSO wanting to implement s-curve moves for other systems, so we should probably consider it when designing new interfaces (for robotics or other less ridged machines, S curves would be a big advantage)

the drawback to s-curves is that it’s a lot more processing to coordinate multiple axis doing complex movements.

It’s common for 3d printers to be able to specify the jerk (derivative of acceleration) and the planner uses that as a limit to the acceleration, but most tend to do that as a series of trapezoids, not as a clean curve.

soapbox = on
I will note that s-curves are really a servo thing, not a stepper thing. with traditional stepper drivers you just have steps and the motor tries to stop after each step. It’s only with FOC on steppers or with servos that talking about acceleration/deceleration and it’s derivative force make sense as you are not dealing with hardware designed for continuous movement.

industrial processes move slowly, CNC machines have not finished the transition from expecting the operator to manually punch in g-code on a big panel at the machine.

3d printing has gotten CNC out into a much bigger world, and driven prices of light CNC brains, drivers, motors, rails, software down and in the process has wildly extended the number of people who understand it and places that it’s used. But it has been based on simple steppers for the most part (with some higher-end machines having ‘servos’ that are mostly steppers with encoders to detect missed steps)

a lot of CAM software (and a lot of gcode interpreters) don’t implement the more complex gcode, they just do linear moves and assume that there is no limit to acceleration (let alone force). They get away with this as the machines are generally light enough and flex enough to absorb the shocks.

but people are now noticing the effects of this in their 3d prints, and as the size, weight, and power of machines increase, these issues are harder to ignore
soapbox = off

Hi @davidelang

Im getting close to the talking to klipper point. Where should we start ?

This is running with the CORDIC for sine/cosine calculations. Using the float, so not ideal regarding loop speed and conversion time.

Running 24v from a regular 15A PSU. The motor and controller is completely cool. Im curios to see how this current sense for steppers turns out?

1 Like


What is this feed_forward story?

Do you think it can direct_drive a 8mm per rotation screw ? 16bit hardware encoder is 65536 ticks per rotation. 8mm / 65536 = 0,000122mm.

I do have the angle control working. Would you just send the angles, and try to achieve those angle as best as possible within the tuning parameters?

This was the TMC2660 drivers on the AZTEEG GT5

What about using easing functions to define the rate of change of position:

There loads of different easing functions that are all mathematically described so could form part of a command. You wouldn’t need to implement them all at once

Ok, right, its about the ramp.

But what if it had current control, then it could also scale the torque based on current reading. That, and the velocity, can be quite powerful hooks for controlling the speed. Maybe the mainframe should have control of some of the core functions.

Something to consider is how the USB should be used. It has several modes.

Not sure if this is useful for this thread but just in case here there is a trapezoidal planner that can be used on top of SimpleFOC to obtain smother movements.

It can be used as a base to implement other profiles of movements like S-Curves.

1 Like

Klipper is in a sense a parsing regime, based on USB (up to 64byte transfers); Source

Message Blocks

All data sent from host to micro-controller and vice-versa are contained in “message blocks”. A message block has a two byte header and a three byte trailer. The format of a message block is:

<1 byte length><1 byte sequence><n-byte content><2 byte crc><1 byte sync>

The length byte contains the number of bytes in the message block including the header and trailer bytes (thus the minimum message length is 5 bytes). The maximum message block length is currently 64 bytes. The sequence byte contains a 4 bit sequence number in the low-order bits and the high-order bits always contain 0x10 (the high-order bits are reserved for future use). The content bytes contain arbitrary data and its format is described in the following section. The crc bytes contain a 16bit CCITT CRC of the message block including the header bytes but excluding the trailer bytes. The sync byte is 0x7e.

The format of the message block is inspired by HDLC message frames. Like in HDLC, the message block may optionally contain an additional sync character at the start of the block. Unlike in HDLC, a sync character is not exclusive to the framing and may be present in the message block content.


Here is the STM32 USB init from Klipper. Do you think it can be fitted to PlatformIO?

klipper/usbfs.c at master · Klipper3d/klipper (github.com)

First thing to do is to establish the connection. Then we can look at commands and what they should and should not do.

klipper/command.c at master · Klipper3d/klipper (github.com)

Im thinking the look ahead feature should handle incoming commands in stages with the primary handle being now();.

In that regard velocity is important. TODO: setup timer as velocity reference to encoder pulses.

From what I remember, from the last time going through the Klipper concept, it sends commands tied to a timestamp or time reference. It can do that, since all the sub_drivers or nodes, are synchronized to the mainframe running Klipper on a Pi or PC/Laptop. It also sends what stage in the Trapezoidal move the command is in e.g. accelerating, cruising, de-accelerating.

So, in the context of SFOC we have a command wanting to hit a specific velocity at a specific time. We also know if the next command in line is accelerating, just cruising (same speed) or if it is de-accelerating. Those commands will be coming in really fast with sub millimeter intervals.

Regarding the current sense in all this. The current sense will ensure stable torque control, since we constantly measure the current draw, related to torque.

I guess I will need a hardware serial connection to debug the USB transfers…

I imagine these commands will be parsed into a single or various circular buffers.

When doing the motion planning we then look at the move/command being performed now, the next command in line, and to give us some time-to-react we look at the buffer[10] or the 10th command in line, mainly to check whether the trapezoid state (accel/cruise/de-accel) will change in the foreseeable future. If the motor is sagging behind the commands (this all happens really fast) the controller will apply more current/torque, until a certain limit. Position in time, not to forget will tie the whole apparatus together

This is the link to our beloved Gcode. A.k.a. adaptive clearing.

You can develop an interpreter of Klipper commands making possible to run Klipper on the same microcontroller that you are using for your SimpleFOC instance, effectively creating a “Klipper Node.”
However, in my opinion, this is not in line with the purpose of SimpleFOC, as it operates at a higher layer. If you look at examples such as oDrive, VESC, or Moteus, none of them go beyond basic motion planning for a single axis.

@JorgeMaker lets move this to the proper thread. @Owen_Williams sorry for hijacking.

Ok, so because others do not facilitate multi-axis synchronized motion, SimpleFOC shouldn’t either?

Klipper is essentially a really well written fully functional USB parser, which interpret Gcode and handle all the timings, synchronization etc. what we have to do is teach SFOC how to talk Klipper or maybe even tinker with the mainframe …