I’m having an issue with sensor noise. I use an Arduino Uno and AS5600 magnetic sensor. Yes, I know going to an ESP32 and an encoder will fix this. That is not the point. I am purposely using these low-end parts to find problems.
Here is the problem: The torque mode controller with velocity and angle PIDs works about as expected. But the AS5600 is very noisy, and the PID “thinks” the noise is position error and constantly tries to correct it. The result is a strong “buzz” of random movement about the set point. This is not a PID stability issue. It is white noise on the set point.
My proposed solution:
(forgive me if this is already done, would you point out where.)
Currently, (I think?) the PID sees error as “set_point - sensor_reading”. A better solution is to compute error as “set_point - (best_estimate_of_current_shaft_angle)”
So then, how to better estimate the current angle?
A simple method is to ignore sensor data that implies impossible things like 30,000 radians per second squared acceleration from a $4 motor. Replace unexpected values with extrapolation from previous data. It is more likely data bits got flipped than a motor survived some incredible movement.
Over sample the sensor. Read it at a rate that is N times faster than needed. (Combining the points is slightly tricky because with a moving motor we do not expect points read at different times to be the same.)
Use more than one source of information.
Use Kalman filter to track shaft angle. The Kalman filter in effect does all of the above, but I doubt a low-end processor could do this. It is a few matrix multiplies per cycle.
That said, I have better encoders, One experiment I might try is to place my AS5600 on the same shaft as a 2,000 LPR optical encoder and see if I can’t find a way to get better, data from the AS5600. “Better” meaning a low departure from the optical encoder.
Hey @ChrisA ,
Two answers to this:
Before you invest too much more time into the AS5600, consider switching to another sensor. Just do a quick search on AS5600 in our forums - no other sensor has caused so many problems/questions, and while many people do get it working eventually, mostly people upgrade to better sensors. I think you’ll save yourself some time if you take this step immediately rather than spend months on the wrong sensor first.
Sensor models from Semiment or MagnTek have similar price points, but far better performance. I can even send you a couple of finished sensor PCBs with such chips if you’re interested.
Regarding improving the velocity signal. I think your ideas have merit, especially the Kalman filter - it’s been suggested before, and there are some implementation suggestions if you search the forum.
If you were interested in pursuing this, I think we would be interested in making the filter setup more configurable in the future. And while I think a UNO level MCU is already overtaxed without Kalman filtering, I think you can do it on a fast STM32 or ESP32 no problems.
This would be great, but sensor and comms latency is a bummer, and with the AS5600 the maximum speed you can read it is already 10x slower than you would really need. So oversampling this sensor is quite impossible.
SPI or SSI improve on this dramatically, but still have significant latency.
ABZ type interfaces have the lowest latency, and are your best bet if you’re trying to get super-fast control.
But the sensor latency is only one issue. Another is the timer resolution - esp on an UNO, while you can call micros() to get a microsecond timestamp, resolution will not be 1us, and the timestamp itself will come with latency/inaccuracy. Again, using faster MCUs improves this, but be aware that some of the problem comes from timer discretization/inaccuracy too!
Ben Katz also did some very nice research into this whole question, and has a solution based on the STM32 timers to compute precise intervals between the ABZ encoder signals, to get much better velocity - when the motor is moving at a certain speed… For stopped motor noise this won’t help either.
Agreed - we recently introduced a minimum delta-T for velocity computations for reasons along these lines, and there are some other things we can do.
There is also the simple hack of switching the motor off when you want 0 velocity, although of course this isn’t possible in all applications.
On that node, when talking to MagnTech about the MT6835, I kinda got the idea that not all MT6835 has the ABZ interface? That it somehow had to be set up as a feature? That did seem a bit odd to me, so I was like, my focus at the moment is SPI so I will most likely use that, and I mentioned that you already have a driver ready…