New user looking for experts


I need some help implementing something like FOC in my open CNC controller. The goal is a robust system that behaves more like a cobot - stops on collisions, allows push-to-teach, etc. The end goal is an modular, low cost robotic arm.

The board

It’s an STM32F405RTG6 with a TMC2130 driver and an IPS2200 12-bit absolute position sensor. The boards daisy-chain via CANbus to minimize wiring and maintenance troubles.

Progress so far

The individual components are tested over multiple boards, CANbus is working, and a very crude gcode based CNC is working with dead reckoning.

I’m just the right amount of dumb enough to realize that it’s going to take me a year or more to learn and implement this on my own and I would do it much worse than you experts. I’m looking for help to make this baby really sing.

Here’s what I have so far, including the kicad design and the firmware:

Please respond if this interests you or if you know a better place I should be asking.

Thank you!

But what exactly are you asking for? This is an enormous project, there are a ton of things to do here, and there is not much point in most of them. I would use linuxCNC if I wanted to make some kind of open source cobot system i.e. a system which is aware of the force on the joints and gives up if it’s too high. I would also survey existing systems first to see what I can borrow.

SimpleFOC can be used as a module in concocting a serviceable servo drive system. Modularity is important and I would section that off and I would contribute to the next-gen lepton design and then use that to implement a servo driver that makes sense, and then you can interface that to the rest of the system.

What do you mean?


So you’re saying the firmware should have started with the FOC and added the CANbus later? That’s what github branches are for?

This driver only supports step-dir or serial interfaces - not really appropriate for FOC (and not supported by simpleFOC). Are you open to using a different driver?

In the longer term, yes. Stepper motors are what I’m familiar with, not what’s best for the project. What do you suggest?

You can use steppers with FOC! But you need a driver which gives you lower-level control over the half-bridge. You either need something you can drive with a PWM for each phase of the motor (for steppers this is 2 PWM inputs) or with a state for each leg of the phase (4 PWM inputs). You could start with something like DRV8833 or others. There is also some prototype code in the devs library for driving steppers using regular BLDC (3 phase) drivers.

Sorry for being so negative, I’m just tired these days with so much to do and so little getting done. I assume you are doing this for fun, but I encourage you to try to merge the fun and the constructiveness, I personally believe there is much gold to be found when they are in harmony. If you think deeply about what’s fun and why, I believe most people like to play with things that really do work, and see fruit from their labors.

I would back up and survey the tools and systems/modules you have to work with and take it from there.

Why do you want to concoct a cobot? I don’t think any suggestion for actuators is likely to hit the nail on the head unless you share what you are really after here. Are you trying to make and sell low end cobots, contribute to the open source ecology (which would be awesome imo)? I honestly don’t understand why you would undertake such a substantial challenge, but I’m just bummed from recently undertaking to omuch and not getting much fruit out of it, but that doesn’t invalidate my desire to warn others away from the same misfortune.

1 Like

I feel that. Exactly why I’m reaching out for help instead of trying to do it all myself.

I make robots in a pro-am style, selling what I can to continue my hobby. I hope that by making good robots available to everyone I’m helping the open source community. Someone has to take on the job of making consistent, quality machines for everyone else, right? In my case the passion is robot arms, been doing it for over a decade.

The board in question already exists. I have 6 of them on my desk, working together. the root unit (can node 0) is the main controller, keeping the others in sync. if FOC is totally the wrong approach… ok, I’m happy to pivot and do it the right way. Make your case! I’m listening.

FOC has a lot of great benefits, but the complexity comes in hardware and firmware complexity.
I think if you already have a working system, and you are not worried about efficiency, I would probably not redesign the system to use FOC unless you had some very good reason.

Hi there. Welcome to the forum!

Your project looks very interesting, thank you for sharing.

IMO this is probably the only place where you could find something relevant to what you do. Let’s see who else responds.


FOC could be the right approach but not with the TMC stepper drivers. How will you re-program the TMC driver? Of course you can’t, that’s the point.

If you would like to try out The Field Stack, let me know. I’m about to make some more prototypes. Are you working with NEMA23 ?

I had a simple way of push to teach my Hexapod
I just took the motors out of the hobby servos and used their potmeter signal to control the leg in question. I could read out the PWM duty cycles in realtime and thereby had a way to teach the spider to walk.

In your case, I’d build an identical robot arm with position sensors only and let the real robot copy your motion. Sample the sensor data and extract what’s needed.

Well Field Oriented control is imo largely about controlling the magnetic field to be in the optimal orientation relative to the rotor, and also the usual mechanisms that are used to do that. It’s not quite clear what exactly it means. It’s a control scheme, I guess. However it can be implemented in different ways and honestly I never really settled on the difference between sine control and FOC for instance, it is certainly very minor.

All the rest of the servo driver and motor design and gearbox or drivetrain and gcode interpreter is another story.

Ultimately, it increases energy efficiency and increases resistance to lost steps basically, compared to the open loop you are probably using right now.

The trinamic drivers sometimes have a feature, discussed elsehwer on this forum an in the datasheet, that measures how close the motor is to skipping a step. If you leverage that you can get the superb precision and repeatbility of stepper motors and improve your energy efficiency and torque at the same time, with relatively little effort. It can’t be as good as a true well done FOC system, but it can be better than a crummy one.

It depends a lot on what kind of angular resolution you need, honestly the requirements of a good arm type robot are pretty strict I seem to remember. Very small angular errors lead to considerable errors in effector position due to the large leverages.

To be honest if you want to deliver a robot ina reasonable timeframe I would leverage that feature of the trinamic driver and stick with stepper motors unitil the other details are better worked out. There must be lower hanging fruit.

And again if you want to use SimpleFOC in your project, don’t use you custom boards, contribute to the next generation flagship SimpleFOC board and then use that. Otherwise most of your efforts will never do anybody else any good. A half finished system is not much good to anyone, and it’s a lot of work to really finish something, plus it makes not sense to do it all on your own when there is wisdom and a head start on the subject here in the community.

There is a company making small cobot arms in Montreal, I have seen I think called Mechademic. I had read about them and was stoked to see one at an art show doing paintings one time. They are extremely expensive and the company says it’s partly because the actuators are so expensive. A good robot arm has to have effector positioning repeatability in the range of 25 microns. That’s a lot. They have to use harmonic gears etc, but I think they are probably brushless motors with optical encoders behind that. If you want a more economical system surely you will need a different approach. I honestly think stepper motors with those trinamic drivers are a pretty good option in place of a harmonic gear system like that. The best bet is to write a good driver to harness the coolstep and other features of the driver really well, so you can monitor for lost steps, regulate the field in a way similar to a crude FOC system, etc., and it’s going to be way way cheaper. That would be a significant accomplishment, to make a rotary actuator with really good properties using stepper motors and a nice ass driver.

I don’t know if there are drivers with similar features but higher current capability, that would be good stuff. Perhaps an advanced cooling solution would be good stuff, like submersing it in deionized water or something could get you to 3 amps or so. Larger stepper motors also have much more torque per amp.

1 Like

o_lampe My first bot was a hexapod.

Juan-Antonio_Soren_E Field Stack looks neat. I think I’ve seen it used in ZeroBacklash?

Valentine Thank you, good to be here!

So my impetus for looking at FOC started in a simple place. I am trying to use the system to measure out a fixed length of timing belt so I can manufacture more plotters. I tried:

  • counting the steps blindly (dead reckoning), came up short tho the math for number of steps to make was right.
  • measuring the sensor every step and summing the differences. came up even shorter, probably sensor fluctuations.

I went looking for a more accurate method and found
which eventually led me to FOC.

Dial with detente looks like a great test case for pairing a single motor and sensor. Putting that together to get more accurate distance readings is next. Then doing it for a group of systems so the device can halt on collision and respond to forces.

By far the biggest pain right now is that dumb moment the sensor passes from 359 deg to 0. Y’all clearly have that sorted out. What’s the secret? immediately store it as a 2d vector with cos/sin?

Ugh. cannot mention more than two people. cannot post more than two links. FINE. :slight_smile:

Ours is not great either. The sensor code tracks the angle as a separate 0-2pi and integer full rotations. Sensor.cpp checks for a large delta to detect wraparound if(abs(d_angle) > (0.8f*_2PI) ) full_rotations += ( d_angle > 0 ) ? -1 : 1;
But BLDCMotor and StepperMotor work with the combined angle as a float, which has precision problems with large values, and requires a rather costly function _normalizeAngle to get the 0-2pi portion. It’s been improved recently by better sin/cos functions that don’t need the angle to be in 0-2pi range, but not all of the code has been updated to take advantage of it.

There is a work-in-progress class PreciseAngle in the drivers repository that uses the two component format, but updating the motor code to use it is not straightforward because PID and lowpass use float. And is interpreted differently depending on the control mode, which is already a little confusing, so if we add a separate PreciseAngle target for angle mode it would be even harder for beginners.

I wish I could be more help. I’ve been following your robot arm development for a long time, but the control software is the part that I know the least about. Mostly because I wouldn’t know what to do with a robot arm if I had one.

You’ve heard of it? Awesome! That means a lot to me.

As for what I’d do with it… I make a lot of stuff. My goal is to get these arms to assemble their sisters. That’ll be the last time I make a robot arm by hand. I can’t think of a better demo.

is d_angle adjusted when full_rotations is changed? point me to the code, I’m happy to read it.

First function in Sensor.cpp, Sensor::update

getSensorAngle is a pure virtual function which does the actual sensor polling (or just returns the latest value from sensors that update via interrupts). d_angle is the difference from last update.

Oh…! I was doing almost the same, with an overflow of only PI (where you have 0.8*2PI)

We essentially make the assumption the sensor itself works on 0-360deg, and track the full rotations in the sensor base class update method. This depends on the update method being called very frequently…
Between calls to update, the sensor returns the same values for calls to getangle and getvelocity. This allows the algorithms to work with stable values between the updates.

I think the PreciseAngle code can be considered obsolete… the Sensor itself is now precise, angle and full rotations are tracked with 32 bits each.

It remains to update the motor code to be precise, but this is not trivial, as you say. I think it’s something we might attack in a future major version jump which also involves the needed API changes to make it simple to use.