Feature request: add klipper MCU input mode

searching through the topics, I see that klipper has been mentioned a few times, but mostly in terms of an example of how to plan, or that the step/dir mode could be used to attach a simleFOC board to a controller running klipper to act as a stepper (just in closed loop mode)

Apologies if I missed something (and if I did, please point me at what I missed)

I would love to see an input module that talks the klipper MCU protocol, where the main klipper brain still thinks it’s driving a stepper, but instead of simpleFOC getting step/dir pulses, it would get serial commands like:
queue_step oid=%c interval=%u count=%hu add=%hi
stepper_get_position oid=%c
(see MCU commands - Klipper documentation and the protocol link)

This is far from an ideal interface, but it’s also far better than having to dedicate a processor board to run the klipper MCU firmware to receive such messages and convert them to step/dir pulses for simpleFOC to then receive and implement.

I’ve tried to talk to the klipper folks about the need for smarter motor drivers to be given higher level information (at the point where klipper decides what the motor moves need to be, before it turns them into pulse streams) but ran into a wall of misunderstanding the last time I tried

I Think USB is faster if done properly. Forget about emulated USB / serial, if you wish to push the bandwidth.

IMHO, USB vs serial vs CANBus vs SPI vs ?? transport options are less important than the message passing that goes over them.

Once we have the ability to talk the klipper MCU protocol (instead of step/direction) we have already gained a huge amount of efficiency and reliability and it’s simple in comparison to add additional transport options.

(as far as I know, not all simpleFOC target boards are going to have any particular transport interface, including USB, although I think most will have serial)

True, I agree. It would in any case be a real step forward.

Regarding the reluctance from Klipper community. It’s fully understandable that they think it is annoying not to use stepper drivers, but actually use FOC (far better) they have a lot of time and hardware invested into it. Also, I’m not sure how exactly, but I think they are sponsored by BigTreeTech (official main board sponsor), which I fully get.

Hey there,

I thought you’d be interested in this thread @Juan-Antonio_Soren_E :slight_smile:

I took a look at the protocol, and this is far beyond what we would put into the core library. But as a separate project “simplefoc-klipper-firmata”, why not?

In terms of what they actually do, I don’t like it. They have a “Firmata” based approach where the micro-controller essentially gets “remote controlled” by the main Klipper CPU. So the MCU publishes its available commands in a “data dictionary”, which the Clipper CPU first loads, and then uses to control the microcontroller through a sequence of commands.

It’s unnecessarily complex and doesn’t really help solving the core problems at hand. Gripe.

Anyway, nonetheless, it should be possible to publish some kind of data dictionary from a SimpleFOC based firmata that contains all the expected commands. Commands we need we would implement in a “SimpleFOC” way, and commands we don’t need just implement dummy responses, so in the end Klipper feels like it is controlling one of its customary MCUs.

My guess is the whole data dictionary and command parsing business will take quite a bit of flash/RAM once its all done, so aim for a driver / MCU with at least 128kB, preferably more, of flash.

Perhaps its something we can try to do on @Juan-Antonio_Soren_E 's new STSPIN32G4 based board, if it works as expected?

1 Like

Yes, exactly what we need for multi-axis machines. How else should we sync the movement. Since Klipper works on a PC or RPi it can in theory be multi-threaded (multi-core). I’m quite excited about it!

Sure, that’s not what I meant. Of course the aim is always to effect coordinated movements via the target MCUs.

I meant that in the Firmata approach, the MCU exposes resources like pins and timers to the controlling CPU. I don’t like that approach. I would prefer a well-defined protocol that expresses intent - where each side knows what’s going on based on the intent of the protocol message. In this approach, only one side understands the intent… in my opinion this will be more complicated - at least for us now, because we’re trying to “re-interpret” the incoming commands to make them work with SimpleFOC.

Anyway, like I said, I was griping.

@runger yes, that’s exactly the approach I was thinking. And I agree that it’s far from optimal, but I will argue that it’s far better than the step/dir listener would be.

The main problem that I think it solves for simpleFOC users is a way to coordinate the movement of multiple boards and drive them via g-code. While most machines are cartesian, klipper also support corexy, polar mode machines, and even cable suspended machines.

what are the core problems that you are seeing that it wouldn’t help with?

I also have hope that once a good, open thing like simpleFOC is able to be easily used with klipper (as opposed to rather expensive boards like odrive) it will become popular enough that there will be more potential to shift the sending point a little further up in the stack and make things more efficient.

Very true, but my question is if it’s better than trying to re-interpret step/direction pulses. If it is (and I think it would be), then it’s a win.

they do run the MCUs on rather low end hardware, so there’s a potential for it to not be too big an impact (but we won’t know until someone implements it)

And it doesn’t mean we stop pushing them to let us get hooks a little higher in the stack to provide the intent more clearly.

In talking to them, they imply that they have some ability to talk a higher level protocol to some high-end (i.e. very expensive) commercial servos, but I haven’t been able to understand the code well enough to pull it out.

I’m not sure I understand you here? If you’re asking why I don’t see it in the core library, then its because it is a very problem specific piece of code, useful only to those people who are working on this kind of problem, and want to use Klipper.
The core library should be for the most basic things around FOC motor driving, that almost every user will need.

That’s quite possible, but first you have to show its really better…

A BLDC / or sensored Stepper based approach with SimpleFOC for 3-axis machines will be noticeably more expensive than the cheap sensorless stepper based solutions. So this extra expense will have to be justified by some kind of noticeable improvement in performance…

In terms of getting it done, I think this is mainly a software job, although to collaborate meaningfully during development, and also to popularise the solution with others, it would be good to have a standard hardware to work with that people can actually order and use.

Yes, the goal is to justify it by showing the performance. Most stepper drivers can’t drive 6amp NEMA34’s. That’s a gab we can close, in time.

you said:

so I was asking what the ‘core problems at hand’ were in your view. From your follow-on posts, I think it’s mostly being unhappy at having to derive intent from data points instead of being given the intent. Please add more if I’m missing something

I was thrilled to see all the boards that simpleFOC has been ported to, and have ordered a few.

For 3d printers, you are correct, but as you go up in power requirements, large, powerful steppers (and the stepper drivers to run them) start getting very pricy, where BLDC motors and boards like the powershield (even with it’s PWM speed limitation) or the B-G431B-ESC1 Discovery kit are on par with or cheaper than the high power stepper drivers, while BLDC motors are starting to show up in enough powerful things (even ignoring drones, there are RC vehicles, cordless power tools, e-bikes, scooters, hoverboards, etc) that they are far cheaper than steppers anywhere near their torque levels

Ok, point taken! I don’t know much about this world, but I’m always surprised when I see the price of real CNC gear compared to 3D printer stuff.
I’ll accept there is something that can be done here. But neither the B-G431-ESC1 or the Powershield will be up to it, I’m afraid. But there will be other drivers that are, so I accept this argument.

Yes, along these lines. There are many details to consider, and whoever designed the Klipper protocol should really be given a chance to tout its advantages as well :wink:
But unless we want to get into a deep discussion on protocol design, and without knowing the design goals the Klipper people had in mind, then I think its better to focus on the meat of the problem, and see what actually needs to be done…

I kind of already discussed this with @Juan-Antonio_Soren_E , and unfortunately my time hasn’t become more abundant. I’m happy to chat about it a bit, and happy to provide some guidance to get someone started, but I don’t feel I have the time to really do this effort - it will be a bit larger software project, and I won’t get it done in reasonable time.

The brake_resistor road map / development is already a huge contribution in that regard. In due time it will all come together.

The potential is real world automation and productivity, like industrial laser-cutters, CNCs, so on and so forth.

sounds reasonable.

Klipper’s intent was to be able to separate the high-level work (gcode interpretation, motion planning, kinematics computation) that is most effectively done on a 64bit processor with lots of ram that’s running a non-realtime OS from the bit-banging that requires precise timing and where interruptions cause errors, allowing for much faster and accurate pulse generation to the stepper motor controllers, even using ancient 8 bit processors. Their protocol is built around this split in an all stepper world.

They are just starting to acknowledge that there is a world beyond that, and since most servo implementations can simulate stepper drivers (the step/dir interface), they are able to stick their heads in the sand and pretend that everything is good

so, @Juan-Antonio_Soren_E to talk implementation details.

There are three parts that I see

  1. the communication with klipper to receive the info
  2. convert the ‘execute X steps with timing Y in direction Z’ instructions that we will get from klipper into movement commands that make sense from simpleFOC
  3. execute the converted commands at the right time (since klipper sends the commands ahead of time for the MCU to queue so that it never stalls waiting to get the next movement)

The first seems reasonably straightforward to me (just a lot of digging through code to pull out the right info from klipper)
I don’t know enough about simpleFOC to even start on the other two steps.

Right, as @Antun_Skuric has pointed out, derivs_limiter could be the bridge between SFOC and the Klipper commands. Look here:

That thread talks about the need for motion planning, instead of just changing the desired position. That should be less of an issue with klipper integration, because klipper is doing the motion planning, including acceleration planning and limits.

The problem is that instead of giving us that info, it’s giving us the step pattern to implement the resulting movement and we need to derive position, speed, and acceleration from what it’s providing. We are better off than step/direction in that we get this info ahead of time, rather than having to just chase the position the way step/dir does

I can understand the math to derive these from the info that klipper provides, but what’s the best way to have simplefoc know what is intended?

In an ideal world, what we want is a ‘at time T1 you should be at position P1 speed S1, move to position P2, accelerating at A2 to speed S2, which should take you to time T2’ followed by ‘at time T2 you should be at position P2 going speed S2, move to position P3, accelerating at A3 to speed S3 which should take you to time T3’, etc.
with the most important points being hitting the position and time (and should raise a flag if it deviates too much from the acceleration/speed requests. I believe that the acceleration is all going to be at a constant (max configured) rate
Since klipper is doing trapezoidal movement planning, we should be able to reverse engineer this and get acceleration sections and constant speed sections.
per that thread, it sounds like the acceleration data won’t be used by simpleFOC right now.

Hmm, I think you are on to something. I must say, my focus has been the PCB for a long time, but I’m eager to get down and nitty gritty with the code.

The Klipper kommands are in fact looking ahead, like you point out. Integrating the time factor is the challenge. Something MCUs are really good at, while human brains are like hot-wired for eternity/timeless states of mind. Anyways, I think you are right about the targets, buffering the commands and executing the actual movement. Based on speed?

Maybe we can have T1, T2, T3 be separate independent functions, extrapolating time in a sense. T1 = 10 milliseconds to now. T2 = 100 milliseconds to now, etc. pinpointing the datapoints, in the future so to speak. Always ahead of now, unpacking the relevant information.

Based on position and speed, deriving the needed torque or power-demand to execute the will of the maker

Acceleration is just a fancy word for going faster or slowing down. Its nice to have, so don’t discard it

re-reading the thread that you pointed me at, the solutions was to define a bunch of time/position pairs and order simpleFOC to move between them.

We can do that trivially, it’s just the step/direction interface with a queue instead of interrupt driven pin responses. But that is again throwing away the intent.

I believe that klipper will have two sorts of intents

  1. near constant speed S, but get to position P at time T
  2. adjust speed to near speed S (in as linear a ramp as you can reasonably do) but get to position P at time T

currently, in position mode we have ‘get to position P but don’t dare to go any faster than speed S and don’t apply any more power than X’ without any consideration of T. So it sounds as if we are going to need another command or two that let us define the movement in terms of time and the desired velocity ramp (as opposed to a torque limit)

then under the covers we can have the pid loops target this, very similar to what we have today, but where the speed and acceleration are strong suggestions, not hard limits (you can violate acceleration to make the speed target, and you can violate the speed target to hit the position on time). It may be that the speed and acceleration are less targets than monitoring settings, ‘warn if you vary from these too much’

does simpleFOC have a simulator mode where you can program in a motor and then run against that, plotting the expected response?

@runger can you see a better interface to use to pass the intent