It details using both an spi based 3d hall array and an analog linear hall effect sensor for absolute positioning of a motor down to 0.1 degrees of accuracy. The anolog is most interesting to me since its about $0.25 per unit at 1k quantity.
I know that halls are used in sensored BLDC motors but they are used much more like switches than analog position sensors.
Why aren’t these used more often? I’m sure there is a reason but I haven’t personally touched this area of electronics yet.
Hi @Gloppy16 , have you searched our forum on this topic?
There have been two attempts at implementing this, and we have some code for it in GitHub here:
My motor (Robomaster M2006 P36) uses 2 linear hall sensors. I like to call it a sin/cos enocder because the output is a sine and cosine wave. It seems to be really accurate in position sensing, I get an accuracy of around 1 electrical degree.
I think that a linear hall sensor is the best type of sensor for a BLDC motor. It is a shame that almost no motors except the Robomaster ones use this kind of sensor.
Long, long time ago I designed a sensor using 4 ratiometric (aka analog) hall sensors. The computational overhead/penalty was prohibitive so I abandoned the idea.
It’s a nice educational / academic exercise however for a few bucks you can get an absolute angle sensor as5047 that does exactly that (uses 4 ratiometric sensors inside), fully debugged, built in real-time error correction and rpm compensation, etc.
I’m not trying to discourage anyone, only pointing out this is not a production grade solution and works in a very niche use case within a rather large error envelope. Also requires a complex mechanical setup.
With my application, I do think I’d be able to get around this. I’d probably be running my code right off a PI (clone) or maybe the ESP32 P4 when it finally releases. The p4 looks beefy.
Depends in the goal. I want to see just how cheap I can get a multi axis servo setup. A few bucks here and there adds up.
Thats what the calibration in the PDF was for. They brought the error down from 9 degrees to less than 0.1 degrees for the DRV5055 off-axis setup.
Unless I missed something, I’d hardly call the mechincal set up in the PDF “complex”. It was two linear halls of set by 90 degrees and placed around the magnet. Not too much more complex than the typical on axis setup.
I love linear halls. Easier placement than digitals, higher resolution, and they run on 3.3V which is more convenient for STM32-based drivers.
Here’s the thread where Nanoparticle wrote the original code, and I made the final refinements for inclusion in the library 40 cent magnetic angle sensing technique
I ended up leaving the scaling out, mostly to keep the code as simple as possible in the hope that more people would use it if it’s easy to understand how it works. But feel free to add it back in if you’d like.
Performance is good, aside from the STM32 implementation of analogRead being insanely slow. Candas1 is working on a new ADC library, but in the meantime there’s a function ReadLinearHalls that you can override with custom ADC code. On Atmel processors analogRead is fine.
Sine/Cosine outputs are pretty standard on many encoders and resolvers of different types… so I think in general this approach is very validated in industry.
Whether linear halls are the ideal sensing technique I can’t say, but since several people here have had successes with the technique, I’d say its definitely worth a try.
For sensors outputting sine/cosine signals you can get (very expensive!) ICs which convert these signals to SPI or quadrature encoder type signals.
If you roll your own using a MCU and ADCs then I’m with Valentine that its not completely trivial, and very hard to beat the hardware based solutions, I think. Some of the chips have <2us latency, to do this with sampling the ADCs and code computing the atan2 function I think will be slower, or require a very optimized solution.
But you may not need such low latency for your use case, certainly BLDC control is still possible with much higher latencies.
Yeah, most ADC chips I found made this approach sub optimal from a price standpoint. I would have to use a chip with decent inbuilt ADCs. Any idea how the ESP32 series has been doing with their ADCs?
On 64MHz STM32G031, the fast atan2 approximation takes 28 microseconds. It should be next to nothing on STM32G4 with FPU. ADC operations were 7us for single reads, or 13us with 8x oversampling for better signal quality. I don’t think those numbers will improve significantly on other chips, but the ADC can run in parallel with other operations. And you don’t have to spend time on SPI communication, so you might even come out ahead.
I only did a basic offset calibration for each of the sin and cos channels, I did not bother with any gain compensation because in my experience the amplitude of the sin and cos wave were very similar when I measured it with a scope.
I should have been a bit more ckear when I said an error of 1 electrical degree, that is only the error caused by noise in the measurements. Unfortunately I don’t have any way of measuring the absolute error as I don’t have anything accurate enough to measure it with.
The computational overhead of my implementation is minimal. The ADC readings are triggered by a timer, and then offset is subtracted and a scaling factor is applied before feeding into CORDIC atan2 accelerator. Scaling factor is needed otherwise magnitude of raw adc readings is too small to get good results from CORDIC. The output is the electrical angle of the motor which is used in FOC.
I also use an overflow/underflow detector on the electrical angle to count the motor electrical revolutions and track the position.
In my custom FOC code running on STM32G431 (Cortex M4 @ 170MHz), I run FOC at 50KHz, and the motor control loop takes up around 60% CPU time. My code is not even that optimised.
Latency wise I think you are mainly limited by the bandwidth and latency of the hall sensor you use and not by the software.
I’m back to working on this for a bit and have a few questions.
At what point does my angle sampling frequency interfere with the maximum rpm of the motor? The DRV5055 samples at 20khz. I’d be using two to get the sign and cosign signal. Does the sample rate alone give a hard limit to rpm?
Can I have my sensors at a lower frequency while simple foc runs at a much higher frequency? How far can this be pushed before problems arise?
As an aside, I am finishing up my design for a4542 test board for the DRV5055. My first real pcb design. I’ll post it for feedback when I am happy with it.
Yes, it would. The sensor determines the rotor position. So if you read the sensor faster than its sample rate, the value won’t change from the last reading, and the rotor won’t have moved (from the point of view of the sensor).
You can run it faster, but there is no advantage in doing so - with no update to the sensor value, the commutation won’t be advanced either.
The only reason to do this is if you also have current sensing, and this is running at a higher sample rate than the sensor. In that case you would not get updates in terms of the commutation, but you would get finer current control - e.g. the amplitude of the commutation would be updated, but not the angle.
Hmm, I have to think about this a little - perhaps someone here in the forum with a background in control theory has a better answer for you.
But basically it is this:
updating the commutation faster than the sensor sample rate has no benefit because you don’t have new angle data. In theory, using interpolation between samples could help with that.
the commutation has to be updated regularly - basically is has to track the rotation of the motor, so in FOC that means the Q-axis voltage is 90° ahead of the rotor electrical angle. This gives maximum torque and minimum power consumption for that torque.
If you set the commutation at 0° instead of 90°, you won’t produce any torque, and if it is at -90° or 270° you would be putting torque in the opposite direction than you want.
So if your motor is turning so fast that it moves through a large electrical angle between sensor readings, then you won’t have updated the commutation in time, and will be either holding the motor back, or worse, have “skipped” commutation, usually with terrible effect on the performance.
I think control theory people would say that the “phase margin” for control is insufficient or bad if the motor moves too far between sensor readings.
What constitutes too far, numerically? I don’t have a formula on-hand, perhaps others here with a theoretical background in motor control can give a better answer here.
But we can compute the following:
electrical angle a_e moved in time t, given pole pairs of the motor pp and angular velocity v (rad/s):
a_e = v \times pp \times t
In a perfect system, the commutation angle would be perfectly at 90° ahead of the rotor position. In an imperfect system, the angle is less than 90° due to the measurement lag.
So the applied Q-axis current is less than the expected one, depending on the offset in angle. If the angle is less than 90° by an amount a_d then the current is reduced by:
IQ_{act} = IQ_{ideal} \times cos(a_d)
So as your motor turns faster the electrical angle between sensor readings increases, and the efficiency of the commutation decreases.
I think I’ll stop here and give someone with more knowledge a chance to answer
I think you’d want to draw a bode plot to compute the phase margins and gains, and from this could answer numerically, but I’m not confident to get that right…