Using SimpleFoc as an ebike foc controler


first of all thank you for this impressive lib.
I am quite new to this forum and already impressed by the possibilities of this foc lib (not as simple as the name may suggest !)

Let’s introduce myself : electronics (PIC, ESP32, …) and software enthousiast (android).
You can see a few video on my youtube channel : f2knpw channel. I like “useless” stuff with a lot of neurons inside !
I am not completly noob in motors driving : HDD clock
I also played with quadcopters, IMU, segway like stuff… and brushless guimbals

My first question would be to use this lib as a foc controler for my e-bike. I know that foc control needs at least BEMF (or hall sensors) to work.
I saw that Hall sensors are already implemented. Is there any limitation in using open loop branch of the code to drive a sensored BLDC bike motor ?
What would be the trick to drive the motor “sensorless” ? Startup sequence and then switch to BEMF ? could it work if I’d provide BEMF info to the lib (as an external sensor) ?

I will use the lib with ESP32 boards (I love this MCU). I also have L6234 custom boards, a few regular BLDC and a few BLDC-guimbal ones.
Just laking a few hours to start !

Once again, I am impressed by this lib


You have quite a few ideas!

I too love esp32 and can confirm it works well with this library. I can’t see why this won’t work with an ebike. The tough part will be building or finding a suitable board (driver + power mosfets) that can provide that crazy amount of power.

I wrote the hall sensor code whilst testing a hoverboard motor, i haven’t tested it a great deal but it worked for me.

I can’t see why there would be any problem running a sensored motor sensorless. It is going to be less efficient but should work fine. Switching between open and closed loop whilst moving isn’t something I’ve tried. Might give it a go! The closed loop sensor will either need to be pre-calibrated or self-calibrated

Thank you for this answer!

I have installed the lib and changed the .h file to work with MCPWM ESP32 lib.
So right now it compiles :slight_smile:

Switching from openloop to closed loop works fine (smoothly). Switching the other way might throw you off your bike! It slams backwards or forwards by a random amount (less than 30 degrees). This is because when openloop takes over it isn’t given the current electrical angle. Probably easy to fix.

The only gotcha is motor.loopFOC(). It must be called for closed loop but must not be called for openloop. A code explanation is probably clearer:

void loop() {
  if (motor.controller == ControlType::velocity) {
    motor.loopFOC ();

I’m changing the controller mode in response to key press inside serialReceiveUserCommand()

My closed loop is a magnetic sensor and I know it’s ’zero_electric_angle‘ and ’natural_direction’ so it’s pre-calibrated. These two values can be passed to initFOC in order to skip calibration.

1 Like

thanks for this safety test !

BTW if you are using ESP32, have a look to my latest post regarding micros() function --> the simpleFoclib may work even better :slight_smile:

Another noob’s question :how do you embed code into a post in this forum ?

Do you mean that te lib can already drive a sensorless motor in full open loop ?

I had in mind that 60° switching positions (given by hall or BEMF) was absolutely needed for foc to run. Am I wrong ? (which would be great)

Perhaps my understanding of these terms is different to yours.

Openloop means no feedback. E.g no hall, encoder, magnetic sensor or bemf readings.

I’ve sometimes heard sensorless being used for bemf/current reading system but that is closed loop.

So if you are asking can you take a brushless dc motor which has 3 phase wires and drive it using this library. Then yes. You just ignore any other wires coming out of the motor (e.g. hall sensor wires).

The way openloop works in this library is super simple. Your literally just sending 3 sin waves 120 degrees out of phase to the brushless driver ic. This creates a spinning magnetic field in the stator and the rotor will follow (assuming you’ve given it enough voltage and don’t accelerate too quick).

Yes sensorless in Microchip’s litterature means “without hall sensors” and with current or BEMFmeasurement !

is the Openloop implementation providing similar torque as “hall sensors” closed loop with rectangular switching pattern (classical 6 steps) ?

Openloop can provide the same torque as closed loop, the problem is it doesn’t know when it needs to provide additional torque. Closed loop knows when to use extra torque because of that feedback loop. Closed loop is efficient.

You could run openloop at max voltage all the time. Plenty of torque but your motor would get hot and battery would drain very quickly.

Or you could try to guess the correct voltage but if you go to low then the rotor won’t quite follow the stators rotating magnetic field and the motor will stall or slip.

1 Like

Ok it’s clear now

Hey guys, I would just like to add a bit info to the post of @Owen_Williams.

Open loop control is a type of control that uses no sensors at all and exploits the hardware features of BLDC motors to control the motor position and velocity smoothly. Openloop control of this library is something what is very very similar to a stepper motor with very high mictrostepping resolution. The algorithm is controlling the direction of the electric-magnetic field of the stator and expecting that the rotor will follow, not knowing where it is really.
The same is true for the stepper motors. They just have huge number of pole pairs >100 I think.
Now the problem of this approach, since you are not measuring anything, is that you don’t know where is your rotor placed and you don’t know how much voltage should you apply, how much torque do you need. So you find some number empirically that works well and apply it all the time.
This means that the current passing through the motor pretty much constant the whole time, and not depending on the disturbances and needed effort. And therefore your motor will heat up quiet quickly.

Open-loop torque profile

This opens an additional question about the nature of current of the electrical motor. Motor torque is directly proportional to the current:

T = Ki*I

And electric current is proportional to the voltage V you apply, the back-emf Vbemf and the motor resistance R.

I = (V - Vbemf)/R

Now since back-emf Vbemf is proportional to the velocity w you have an equation:

I = (V - Ke*w)/R

Which basically means that the motor current I will drop as the velocity grows, but together with current the torque will drop as well:

T = Ki  * (V - Ke*w) / R

So the higher the velocity the less torque the motor feels for the same voltage. This is the well known problem for stepper motors.

Open-loop vs closed-loop example

I like to think about it like stator is producing waves, like on a surface of the see. And the rotor is a ball on these waves, or maybe a surfer. :smiley:
The stator waves depend on the current and for the purpose of this example lets consider that it is directly proportional to voltage (that it doesn’t depend on velocity and back-emf).

The open loop control of the BLDC motor would be something similar to this short animation.

Since you don’t know the rotor position you don’t know exact direction where to apply your voltage. So what happens is that you apply certain voltage to your stator (you fix the wave height) and your motor moves in a position to counteract the voltage (the waves) you applied. It moves to the equilibrium position, in between waves. Once when you start moving, you are moving your waves (applied volatge direction) to the right, as on the animation, and your rotor will follow the waves and always try to go back to the equilibrium position.

What you can see from this example is that this way of control is by no means optimal. Even then the rotor (ball) is completely static the waves are still there, the energy is lost, and when you are trying yo move the ball you are using just the small part of your wave to do it, just the lowest slope of your wave.

The closed loop (FOC) control could be depicted like this:

Since in the closed loop control you know exactly there your ball is you can apply the waves in the direction so that the ball is always on the highest possible slope. And you can choose what is the height of your waves you need to apply so that your ball moves with desired velocity.

You can imagine the torque that the rotor feels is proportional to the slope the ball is placed on. The famous 90 degree angle, which you can find in all the literature about FOC, means exactly this, the highest slope.

Now from these animations you can see that in the open loop, you not only use much more energy for doing the same thing but also almost never use the full potential of your waves (highest slope). Which would mean that with closed loop foc control, you will be able to achieve:

  1. Higher torque
  2. Lower currents

This is really the clearest explaination of openloop vs foc I have ever seen.

I have digged a little into foc theory and found this very interesting webinar :

My understanding is that you have already implemented all of the foc control loop but not the “sensorless” one.
Your current status is exactly this one (please correct me if am wrong)

The missing part seems to be the position and speed estimator (sensorless) :


I must admit that I will have to read again and again pages 41 to 50 to get more than just a high level understanding on how it may work :slight_smile: