Sin Cos Sensor Magnet Encoder

Good day!

I have a sin cos analog output sensor that I am using with a Kelly Controller (KHS) for bench marking a home made igbt inverter board. I am familiar with this sensor as it comes pre installed on several models of industrial motors that I work with.

I have been running hall sensors on my benchtop igbt inverter (Same igbts that the kelly uses)

I attemped to use hall sensors, but am not very happy with the control scheme. The motor is 16 poles and spends most of its time at 250 - 1000 rpm. I desire to use the magnet encoder / sin cos encoder.

What would be a good strategy to use this sensor with simplefoc?

I see that in the docs there is a sensor analog class for magnet encoders, but it expects a single analog input. I see that you can define two magnet sensors, but I am unsure as to the reason for this ability.

Magnetic sensors are like a sin/cos encoder with an internal ADC and processor to compute the angle, and often have multiple methods of communicating the result (SPI, I2C, ABZ, PWM, analog, etc.). MagneticSensorAnalog is for receiving the angle as an analog value.

A sin/cos encoder is just two linear hall sensors 90 degrees from eachother. Their values can be converted to an angle with atan2 using the LinearHall class. Set pole pairs to 1. Higher numbers are for sensing the rotor magnets rather than a shaft-mounted magnet.

Or for better accuracy you can try this experimental class I wrote when playing with linear hall sensors for a shaft-mounted magnet https://github.com/dekutree64/Arduino-FOC-drivers/tree/dev/src/encoders/CalibratedSinCos
There may or may not be a subtle bug causing a tiny error in the output as it progresses through the various zones. I gave up on it due to not being able to get the ADC noise as low as I wanted, so I never got to the bottom of the small discrepancy I was seeing in the data. It’s only 0.1 degree or something, so can be ignored in most cases.

Hall sensors are generally pretty noisy, so it’s better if you can average a bunch of samples rather than just one call to analogRead per frame. That’s why those classes have a weak function for reading the sensors that you can override with a custom version. And if you’re running on STM32, its implementation of analogRead is ridiculously slow so you pretty much have to write a custom version anyway. But it’s difficult if you also need lowside current sense.

The STM32 is slow? That is a scary thought… This might have contributed as to why my original 3 hall sensors did not perform as I expected or wished. 1/2 a degree is plenty. 0.1 degree more granular than the sensor offers for precision.

I will take a look at the Linear Hall class and begin to digest!

STM32’s ADC is wonderfully fast. The G431 I use can take 2 million samples per second on each of the two ADC units. When configured properly, you can greatly improve the signal quality with a lot of oversampling. It’s just the library implementation of analogRead does a whole startup and calibration process, takes one sample, and then shuts the ADC down for every call. It’s infuriating to read the source code and see the waste, and yet the authors defend that it’s the “right” way to do it for a function that prioritizes compatibility over performance. But in reality it hurts compatibility because it’s unusable as is, so everyone has to write a CPU-specific setup.