Closed Loop drives motor in random directions even with

I’m trying to run a linear motor (PMLSM) using the SimpleFOC library. I use an ESP32 and a DRV8305. The angle is determined by two hall sensors offset by 90°. Since the SimpleFOC library does not support this sensor setup, I implemented the calculation as GenericSensor. The result is a very clean angle signal (in radiants). The sensor initialisation also provides reasonable values (zero_electric_angle = 0.12; sensor_direction = 1; motor_status = 4;). In open loop, the setup works perfectly. Changed to “MotionControlType::velocity”, the motor moves in a random direction as soon as I activate the GateEnable signal to the driver (manually, to be on the safe side) with random velocity far above the velocity_limit. Playing around with the PID_velocity settings does not seem to have any impact on the behaviour. Since I am not getting anywhere at this point, I kindly ask you for helpful hints.

The graph shows following signals:
value1 & value2 are the analogRead values of the position sensors (scaled by 0.01 for display purposes),
value3 shows sensor.getAngle(),
value4 shows motor.shaft_velocity.
LPF_velocity.Tf has been set to 0.1 (for testing purposes)
Whenever the GateEnable signal to the driver was activated, the motor started moving, as shown in the graph.

So cool that you’re trying this! I’ve never used such a motor.

Is it driven by exactly the same kind of commutation as a PMSM motor? I guess so, if you say open loop is working!

What determines the number of “pole pairs” for such a motor? It’s important to get this number right, at least BLDCs don’t work if you don’t get this right.

You should try torque-voltage mode before velocity. In this mode, you just set the voltage and the motor goes at whatever speed is normal for that voltage. It uses the sensor to set the commutation optimally based on the motor’s position (FOC).
Your motor isn’t really rotating, it is translating… so I don’t know if this makes a difference in our algorithm. Perhaps you can account for it in your sensor implementation.

Once torque-voltage is working, only then should you try velocity. I think you can try setting the P, I, D values to zero, and raising P just a little to see how sensitive the motor is. Luckily ESP32s are very fast MCUs, so hopefully you should be able to get the motor under control :slight_smile:

Hello runger,

thanks for your answer (and sorry for my late reply)!
Unfortunately, I don’t have the motor available at the moment, as it is currently needed for assembly tests. I will therefore have to wait a few weeks before I can continue with the software development.

I think that I had actually set the number of pole pairs wrong, because this was noted incorrectly in the manufacturer’s description. On the now available winding diagram (see following picture) I clearly identify 2 pole pairs - please confirm or correct my interpretation :slight_smile:

I probably also made a mistake when setting up the controller. I understood the SimpleFOC description to mean that you have to define the torque controller in any case, so I defined both:
motor.torque_controller = TorqueControlType::voltage;
motor.controller = MotionControlType::velocity;
However, as you describe it, only one of the two definitions may be specified. Is that correct? It now appears that the specification of torque control has disabled all settings relating to velocity control. Does that make sense?

Thank you very much for your help, it has already been a step forward for me. As soon as I have further results, I will report them here.

kind regards

Could you please post a link to the motor documentation? This is very interesting. I’ve never seen a linear motor commutated with SimpleFOC. It would be very educations.


Hi Valentine,

as the motor is a customised single unit, there is no documentation available on the internet. However, there is actually not much difference to a rotary motor. The construction is quite clear from the picture in my previous post. The angle is determined by two hall sensors offset by 90°. Everything else is actually just application-specific dimensioning.

kind regards

I’m waiting for a picture.


In principle it looks like a rotary motor that has been cut open and rolled out. The permanent magnets (mounted on a ferromagnetic body) are covered by the stainless steel plate at the bottom.
See also the description here: Linear motor - Wikipedia

best regards


Is yours running in a circle? I don’t see curvature.


There is no curvature. It runs straight ahead or in other words “linear” :wink:


My question is what are the boundaries of the run and how you control it. Obviously it doesn’t go from + to - infinity.


Oh, you wanted to know what limits the run. There are mechanical stops on both sides that should be approached completely. I would initially detect and save the end positions by means of a calibration run. During operation, a certain speed curve is then run depending on sensor.getAngle(). In addition, obstacle (and end position) detection via current measurement is also being considered, but that is still up in the air. :wink:

How do you get angle in a linear motion?