New idea for sensorless drive of a DC motor using artificial neural network (scikit-learn and M2cgen)

Ok. Some people will think this is boring but sensorless motors are easier to get and the community is really having a hard time making sensorless drive work. There are a number of approaches put forth by some forum members and on the Discord channel, flux observers of various kinds, which try to use the mathematical model of the motor to determine the rotor position and from thence actual motor timing (angle between magnetic field produced by stator and the actual position of the rotor, within a cycle of the electrical wave/drive cycle/ i.e. for a 7 pole motor this goes to 2pi and back to zero 7 times per revolution of the motor). They are feed-forward functions that use the output from last time as an input to the next iteration.

Ok, so basically we are having a very hard time finding a function that given say 20 measures of current and voltage along the waveform (only really need 1 complete wave I think? depending on signal to noise ratio), returns the motor timing. The position of the rotor is not the thing, it’s the timing.

If I hop on a graphing calculator and plug in various equations that represent the operation of the motor, I see no easy way to determine even some proxy of motor timing.

However, we can know from current and voltage measurements when the motor is operating at the optimal point, at a given rpm. There is a global minima in the current vs voltage curve. I previously suggested an algorithm that simply searched for this dip and kept the motor operating there, but it was way too slow.

Ok, so neural networks are sometimes described as “universal function approximators”. I could make a system that, for a range of loads and RPMs, plus 20 data points along the current and voltage waveform, determines what the optimal voltage (and current) for run-time is. Take a good range of data across the possible operating region of the motor. You could just use polynomials to approximate everything. There are various algoritms which will take some settings and the data and spit out a bunch of polynomials that try to fit the data.

This is also considered machine learning, however such algorthims don’t tend to fit the data as well as neural networks. That’s all. Also the tools aren’t as handy for the purpose. Also might get complicated when you have like 20 inputs.

Hence the (artificial) neural network.

The system trains just by connecting to the motor and doing the search to collect data (then you have to run the training algorithms on the data on a pc, and produce the neural net function), and it has to be able to change the load on the motor. I would do this with a raspberry pi using micropython, that would be fairly easy to make data I can then use with scikit-learn.

In my case I can have a second fan blowing against the first, so it’s not too hard. It doesn’t actually need to know what the load on the motor is, it just has to have a range. By looking at the voltage and current at the optimal point we can know what the load on the motor is. So you could use a fairly crude apparatus. A second motor with mosfets to short circuit it so it can act as a brake could also work, but then you get the torque ripple and it could get complicated. A large heavy disk and/or spring on the shaft of the brake motor would help.

It’s kinda lazy and kinda dumb, but I think it could work. As long as it’s fast enough I think it will work, and it takes everything into account, whereas when you try to model things there are things like salience which are really a pain to measure for any given motor and mess up the model. You need to measure stuff either way.

That’s what just happened, I ported the flux observer from Odrive into an independent module and tried it out, and it got completely confused by the motor salience. Short of getting a degree in advanced math, or finding someone that has one, I can’t really get it working.

A legit approach is yes to simply take another observer and try to get that working, but it’s a long road in either case and this seems like it’s more likely to work to at least a basic degree. I built a system that used a magnetic angle sensor (calibrated) to determine motor timing and regulate the voltage, and it worked well but was too complicated and expensive. This would do basically the same thing but using the current sensors on the drive board and a neural network, to measure motor timing, then I plug that into the rest of the system.

It’s a bit nuts to bake a thing like this and then roll out a product that it expected to work but I can’t really find a more promising option. As long as the machine learning system is fast enough I think it will work. My fan already works ok just having done this manually, I just plotted voltage v.s. current and then made a polynomial and ramped the voltage. It’s operating in open loop and it’s been fine but obviously such an approach is fragile and inefficent and kind of ridiculous.

This may sound kind of ridiculous, but in a way we are just doing the same thing, take a bunch of data from the waveform, and put it through a function to get the motor timing, then regulate the motor timing. The function can be a mathematical model of the system, which is a great idea, or it can be a neural network.

I would probably regulate voltage rather than RPM to keep the motor timing in a good range, because I want to be able to control RPM precisely. This is a bit slower but I think it should be ok.

I would use M2cGen, which gives you native code with no dependencies which you can run under arduino, then I would interleave motor.move() commands to keep the voltage being fed to the motor glitch free while the neural network runs, because it would probably take a while. Or ideally put it in an interrupt triggered by a timer if I can get away with that (knowing running such long bits of code is usually ill advised in an interrupt).

Another thread about sensorless.
0 feedback about what was done already.


Not to throw a wet blanket on you but I used to do ANN for living and this won’t work.
Better focus on improving the existing technology.


1 Like

Why not? a universal function approximator should work fine to approximate this function?

I did give feedback in the discord channel. I will pursue an observer again if this doesn’t work out, however it’s not going to be any easier to take a second crack at an observer than to try this, from what I am seeing. The code others are sharing is quite hard to use and I don’t see any theoretical underpinnings or other indication they work.

Transplanting the observer from the odrive code base took like a solid week because there is always a dozen crazy problems with data types or infinity errors or compiler flags or something.

I thought it would work with my motor because it is an SM type and the documents indicated that’s the type it works with, but not quite… Some SM types do actually have significant salience. It’s kind of weird, imo that the odrive is incapable of driving other types of motors sensorlessly, I had too much confidence in it’s reputation. I though odrive worked well so I could just use that module and be gravy. Nope.

When I look at the one you posted a while back, which is nice and short, it appears to be doing basically the same thing as the one from odrive which I posted, but with a sort of arbitrary gain and a few other things. It would also have similar problems, unless you have found that it does not?

My next best bet would probably to try to look closely at the vesc firmware and extract the observer they use, if I could look ahead and see if it worked, might buy a vesc and try it even first.

No, it actually works pretty well on seemingly a wide range of motors. From small gimbal motors, large drone outrunners, to Prius AC compressors.

Your use of the phrase feed-forward isn’t quite right, but close enough in concept. These algorithms all work this way because that’s the only thing that really makes sense in this context. You can estimate the error in commutation angle at the current time step and make a change to reduce that on the next iteration.

You mean like fitting a curve or other function? Nobody, to my knowledge, on the discord or forum is trying to do that, and I don’t think that makes much sense to do in the context of sensorless commutation.

I’m not sure what you mean by timing, position of the rotor is what’s important to orienting the field. I think I’ve heard of the word timing being used around 6step drone ESCs, but it’s not really relevant here.

The sensorless algorithms used by us in the discord so far are all based on the same math as what vesc uses. Based on talking to some people on the vesc development discord, it seems my HFI implementation (incl hardware) actually outperforms a typical vesc for small, high inductance, motors. I believe it’s because SNR is better with current sensors sized appropriately to the motor.

Can you link to your specific motor? IIRC you said it’s something like this?

Based on my experience thus far I’d be surprised if it can’t work with normal sensorless algorithms, that motor seems very similar to the gimbal motors I used in my sensorless balance bot.

1 Like

Embedded real-time ANN with that complexity is a very hard problem.


1 Like

So too slow if I just use the dumb approach with scikit or tensorflow lite? I figure if it takes 100 msec to do an inference that’s not so bad for my purposes as long as the voltage wave continues smoothly, load on the motor won’t change very fast. But it’s true then I’m backing myself into corner doing something marginally useful, which I would rather not.

However there are some articles on google scholar that are doing more or less similar things : An Artificial Neural Network Based Rotor Position Estimation for Sensorless Permanent Magnet Brushless DC Motor Drive | IEEE Conference Publication | IEEE Xplore (paper is in sci-hub btw)

Yes, that is the exact motor I am using.

I agree it should work if I can find the right code, I will have another look at the stuff in the discord. It’s very hard to even find the latest and greatest.

The reason I think in terms of motor timing is that if you try to set the electrical angle to be just right, there are a number of regulator loops and so on and it comes to much the same thing. Secondly with a flux observer if you jump the waveform of the voltage around I assume that will mess up the observer or a few cycles, you can’t repeatedly set the electrical angle the way we do with hall sensors or something because the current depends on the voltage and the observer output depends on both, if you plug the output of the observer into the voltage waveform the update rate would have to be low enough for the observer to stabilize every time anyway?

Thus, most of the time the electrical angle just has to keep changing smoothly, then you periodically adjust the phase or frequency to keep the … angle between the magnetic field and the rotor regulated. It’s much the same thing in the end.

In my case, the system has inertial and also I can’t have it glitching or changing rapidly anyway on the millisecond time scape because it would make noise. I assume the frequency of the voltage waveform is ramped for acceleration and otherwise stays fixed. To ensure the angle between the magnetic field and the rotor is reasonable - it is never really 90 degrees anyway in my experience - just adjust the voltage. You could adust the frequency too, different control system style with different properties. But you have to adjust something to regulate that angle one way or another. Maybe with HFI you could just set it repeatedly at high frequency, but that’ can’t work for me because of the noise.

There are even better articles. I’m not arguing with the approach but practicality. IMO commercially it’s a dead end.

Just get a $5 sensor and move on. Unless you want to do research, then by all means I’m curios what the outcome it.


It seems you’re fundamentally misunderstanding how these control systems work. At every point the observer (flux or hfi) estimates the commutation angle error, then we adjust the electrical angle to reduce the error, and reorient the field. Reorienting the field happens at every commutation iteration for all types of control, sensored, sensorless, or open loop.

You can’t adjust “the voltage” to change the orientation of the field, and there’s also no frequency that we’re controlling to run the motor either.

HFI can run WELL outside of hearing range, like torque ripple between 30-60khz. Anyhow, it only really needs to be used at low/zero speed, but your inertia is constant so you could just do an open loop startup routine and have it be very reliable. The flux observer works extremely well once the motor is spinning, you’d have a hard time getting it to lose track by commanding the motor in any way that would be remotely quiet.

It seems like you’re writing off all of the established drive methods without either understanding how they work and why they’re inappropriate, or just trying them. I really think giving the flux observer a shot with open loop startup should give a satisfying result, or at least a direction to go for one, presuming you’ve tuned the current and velocity controllers appropriately.


And I would add to Coppers comments that I don’t think you need a velocity controller for a fan. Perhaps they’re available but no fan I bought ever had a RPM scale - they had settings like 1-3 or min to max…
Avoiding the velocity loop and its PID will definitely eliminate a source of potential noise for you.


Fully agree. Build a load curve with that motor+fan and desirable flow rates, calibrate the voltage/rpm and run open velocity loop. It’s may be a weekend, may be two weekends, effort. Cheap, quick, super quiet. Your challenge will be tabulating the load to voltage/rpm in ms-excel, but at most a quadratic fit will do the trick, perhaps over 100 data points. You can add a 1d kalman to smooth the rpm control signal for a nice s-curve. Your control can be a single rpm potentiometer scaled from min to max rpm, so add another weekend.


1 Like

I agree with most of the points, and have already explored them, but they are right.

I surrender to the idea that I should explore observers further before trying to use an ANN like this, that one from the odrive worked fine except it was just borked from the beginning for me personally because it doesn’t work with motors with salience, which they did tell me I just didn’t realize my motor was like that.

I did learn a lot about how they work and I don’t quite agree, Cooper, that it has to be that way. Adjusting the voltage does change motor timing because the higher current causes the timing to settle at a different equilibrium, assuming the actual shaft torque is the same. I have come to realize there are many different ways to bake motor drivers although probably I should stop trying to invent new things.

I have tried the sensored approach and am trying it again. The first time around I used a magnetic angle sensor, but it got complicated and expensive because of all the extra wires parts connectors, the calibration of the angle sensor, and also waterproofing. Also I didn’t have a good driver board, the G431 board only has pwm and i2c input and that was not really good.

If I had what the qvadrans is aspiring to be I would probably have been fine and been done a long time ago.

That angle sensor system did actually use the system that I describe, simply adjusting voltage to control motor timing, and it worked great. It was energy effiicient, not prone to stall, and accelerated and held a completely rock steady rpm which is important because rpm variations cause distracting changes in noise volume.

It did not set the electrical angle repeatedly based on rotor position. Maybe all the systems other people talk about do that, but not that one. I assumed the voltage frequency/waveform general shape must be as specified anyway for minimal noise, if that doesn’t drive the fan, it is stuck/overloaded and should be shut down.anyway. The only question at any moment was the voltage amplitude, not the details of the electrical angle, that has to continue to change smoothly or it’s borked anyway, for me.

I got motors with hall sensors and will try that next, but longer term I will circle back around to sensorless. I could not find such motors last time I tried, and also had waterproofing concerns. Now, the plan is to open them and paint them with marine dielectric grease. I’ll also test without this grease as they might work fine even when wet or at least not be damaged, I guess.

I should say I was probably a bit partial to the ANN thing because it seems less likely to get mucked up by extra stuff added to the motor drive system for anti cogging. But it’s also less useful for lots of reasons, so yeah I’ll shelve it.

I have tried the open loop with polynomial, and indeed a machine was running all winter with two fans with that control strategy, to test the other aspects of the system and I got away with it, however it does make the motors hotter and is more fragile and can stall if there is a srtrong wind. My system detected such stall and shut down, but still I would not feel comfortable shipping something designed in such a way. Secondly the excess heat shortens bearing life seriously.