Cannot get system over ~100rad/s with AS5600 sensor


I’m not able to ever get any motor to a speed over ~100 rad/s in close loop using the AS5600, which is woefully inadequite for my application. Are there any tips on getting this sensor to a higher speed?


  • Increase I2C speed with I2Cone.begin(19, 18, 1000000UL);
  • alternatively use analog mode (requires soldering and signal is noisier)
  • replace it with a SPI sensor (eg. AS5048)

Thanks for that…
I did a separate tacho project with this chip and I had to program a filter register to get RPMs over 1K or so… I’ve not looked at how the sensor classes are achitected but I wonder if I can easily send a separate command to program this filter register? or even setup the register with the standalone AS5600 library before initializing the sensor object?

That should work…

There is also this code:
which is not yet tested… but in theory its a driver which lets you set the config register.

What speed can you get the motors running in open loop? 40 rad/s (~400 rpm) is the max speed for many gimbal motors (and you mentioned you were using a gimbal in another thread). I’m wondering if your inability to go fast is due to the motor.

Also if a motor is rated at 2000rpm at 24V but you only supply 12V then you’ll probably only get about 1200rpm out of it.

The motor I’m working with now goes up to ~600 rad/s (~4-5KRPM) in open loop and with the hall sensor

Ok, I beeped out the little AS5048 board, and for the record, here are the pin functions:

Wire Color, AS5048_PIN, Function
wht, 13, GND
red, 11, VCC
grn, 3, MISO
yel, 4, MOSI
gry, 2, CLK
blk, 1, CS

I’ve sucessfully tested this and I drastically improved the speeds I was able achieve with the AS5600


I finally got some time today and went back to the AS5600 to try and improve the throughput… I found two things which made a significant differnce:

  1. Setting the CONFIG register to “Fast filter”. This greatly improves bandwidth without any negative effects(at least that I’ve seen)

// declare
AS5600 as5600(&Wire); // use default Wire

// in setup()
uint8_t as5600_addr = 0;
int control_reg_0, control_reg_1;
int b = as5600.isConnected();
control_reg_0 = as5600.getConfigure();
as5600.setConfigure(0x1f00); // fast filter
control_reg_1 = as5600.getConfigure();
as5600_addr = as5600.getAddress();
Serial.printf(“AS5600 Connect: %d, addr=0x%x, confb4=0x%x, confaf=0x%x\n”, b, as5600_addr, control_reg_0, control_reg_1);


  1. increase I2c clock to 1Mhz. This had to be done after sensor.init()

Like I said above, without these updates, I’m limited to ~120 rad/s (~1kRPM). AFter the updates, I was aboe to hit 800+ rad/s. Going to try removing the begin/end Transmission if this helps I’ll write back…


Too bad all my AS5600 setups are in angle mode.
But I wonder, if I still see a difference in main-loop time with these changes?

Which MCU did you use for your test? AFAIK, there are several wire.h libs. One for each MCU family. Do they all allow fastFilter?

That’s a function of the AS5600, not the MCU. You can set the filter speed on the AS5600 in its CONF register… 0x1F is setting the slow filter setting to 2x and the fast filter setting to 10 LSBs.

So did a bit more playing around… The good news is that the AS5600 can now read RPMs all the way up into the 20K+ range. I verified by spinning the motor with an ESC but measuring velocity with simpleFOC

The bad news is that I seem to be stuck at around 10KRPM. It works fine right up to 10K, then when I try to go higher the power draw shoots way up (from ~10W to ~80W) and motor runs rough, or stops.

My loop time is ~60us (16000 iterations persec)
I’m using a 7 pole motor, so at 10KRPM so ~1200 electrical cycles/s

Things Ive treid:

-I’m using an 100PPR/400CPR optical encoder, with the optimized ST library, which greatly relieves the CPU load. This should be the ultimate sensor to use.
-I’m using current sense mode (foc_current)
-Motion downsample doesn’t help
-Higher PWM frequency (50Khz).
-O3 compile option to get more cycles, doens’t work.

WIth the ST Sensorless FOC algorithm or 6-step this motor can run up to 25000 RPM easily K-rating is 2500.

It seems, the motor advanced timing is off at higher RPM and you see more and more shoot-through current.
I’ve only experimented with voltage-controlled FOC, but I could easily tune things by changing kV and inductivity in the motor-setup.

I think the problem will be one of the following, or the combination of both:

  • the 16kHz iteration speed vs the 1200kHz electrical revolutions - here you’re only outputting 12-14 iterations per electrical revolution, this may not be enough to produce good commutation.

  • the sensor, which you’ve made work impressively fast, still has some lag, both due to I2C and due to the sensor’s internal filters.

You can try setting the filter settings to the absolute minimum, and see if that helps. And you can try adding a little bit of “field weakening” by slightly shifting the electrical zero forwards when going very fast.

This may get you a bit more speed, but it’s not looking like you’ll reach 25kRPM at the moment, unfortunately. Note that if you switched to a 3PP motor, you might be pretty close to it already…

But as per my first bullet point, even with a shaft-coupled 100line/400cpr encoder there still is still a bottleneck around 10K. Presumably this sensor should be the ultimate in terms of reliability/latency.

Only if used with the zero-overhead STM32HardwareEncoder - not if used with the interrupt-based encoder…

Yes I am using STM32HWEncoder

hmmm, that’s interesting… this means the sensor is not really the limiting factor, if both (accelerated) I2C and ABZ with zero overhead are giving you the same limit…

I assume this is already with using current control and BEMF compensation?

What’s the difference in loop iteration speed between the ABZ version and the I2C version?

Ok found the issue… My encoder is band-limited @ 20Khz, with a pretty hard rolloff. 20Khz corresponds to the exact RPM (~10K) wher I was gettin stuck at.I’ll try to find an encoder with less CPR and give another try.

I assume this is already with using current control and BEMF compensation?

Yes Im using current control (this negates any need for BEMF compensation, right?)

What’s the difference in loop iteration speed between the ABZ version and the I2C version?
-AB quadrature optical encoder: 40us for voltage control and 62us for current control

-AS5600 with 3 optimizations below: 84us voltage control, 106us current control

AS5600 speed/BW optimizations
1- 1Mhz I2c clock
2- Set filter register 0x1f000
3- set angle register only once, not every time

So AS5600 takes about 40us more than the low-overhead quadrature

So that sounds like about half your time is still reading the angle. This bodes quite well for getting some more speed if you can find a high bandwidth ABZ encoder.

The AS5047P claims to go up to 28kRPM, the MA702 claims up to 60kRPM and the MT6835 can supposedly do 100kRPM… these are all magnetic sensors, but they have ABZ outputs as well as SPI.

claims to go up to 28kRPM, the MA702 claims up to 60kRPM and the MT6835 can

Thanks I’ll take a deeper look at these, but latency may be more important with these magnetic sensors than raw bandwidth… My AS600 can measure RPM accurately up into the 20K RPM region, but are not usable in FOC pas 7KRPM or so even with the fastest filter setting, presumably becuase of signaling latnecy