Noisy AS5048A or is it normal?

Hello everyone!
I’m trying to use SimpleFOC to run a GM3506 motor with a AS5048A sensor and the Deng Foc v3 board (which uses an esp32). I cannot tune reliably my PID values for the velocity mode and I think it’s because my sensor is too noisy. I’m using a AS5048A sensor in SPI mode with the MagneticSensorAS5048A class from Arduino-FOF-drivers.

Here’s the graph of the motor velocity I get from motor.monitor() when the motor is completely off and nothing moves:

For reference, here’s my code:

#include <SimpleFOC.h>
#include <SimpleFOCDrivers.h>
#include "encoders/as5048a/MagneticSensorAS5048A.h"

SPIClass SPI_2(VSPI);
MagneticSensorAS5048A sensor0(5);
BLDCMotor motor0 = BLDCMotor(11);
BLDCDriver3PWM driver0 = BLDCDriver3PWM(26, 27, 14, 12);

Commander command = Commander(Serial);
void doMotor0(char *cmd) { command.motor(&motor0, cmd); }

void setup()
{
  Serial.begin(921600);

  SPI_2.begin(18, 19, 23, 5);
  sensor0.init(&SPI_2);
  motor0.linkSensor(&sensor0);
  driver0.voltage_power_supply = 12;
  motor0.voltage_limit = 6;
  driver0.init();
  motor0.linkDriver(&driver0);

  motor0.PID_velocity.P = 0.15;
  motor0.PID_velocity.I = 10;
  motor0.PID_velocity.D = 0;
  motor0.LPF_velocity.Tf = 0.005;
  motor0.P_angle.P = 20;
  motor0.velocity_limit = 50;

  motor0.foc_modulation = FOCModulationType::SpaceVectorPWM;

  motor0.controller = MotionControlType::velocity;

  motor0.monitor_variables = _MON_TARGET | _MON_VOLT_Q | _MON_VEL | _MON_ANGLE; // default _MON_TARGET | _MON_VOLT_Q | _MON_VEL | _MON_ANGLE
  command.decimal_places = 5;

  motor0.useMonitoring(Serial);
  motor0.motion_downsample = 10;
  motor0.monitor_downsample = 100;

  motor0.init();
  motor0.initFOC();

  motor0.target = 5;

  command.add('N', doMotor0, "motor0");

  Serial.println(F("Initialized"));
}

void loop()
{
  motor0.loopFOC();

  motor0.move();

  motor0.monitor();

  command.run();
}

I also checked the diagnostic flags of the sensor and everything is at 0. I’ve been testing a lot of things for a couple of days and I cannot figure out what is the problem. Why can’t I tune reliably my motor? Is this because the sensor is too noisy or is this noise expected and the problem is coming from somewhere else? Can someone help me?

Thanks a lot!

With the motor running and targeting 5 rad/s in velocity mode:

The motor not running and just logging the motor angle:

Could it be that your controller is weak and you are seeing the cogging of your motor here? If I quickly look at the velocity plot I count 11 peaks which corresponds to your pole pairs?

Have you also tried the voltage/torque control example?

Weak in term of loop speed? I’m using an ESP32 and logged the loop time, in average it takes around 0.4ms per loop. The motor definitely has some cogging that I can feel when turning it by hand but can it explain the high velocity changes I experience in my tests?

I wonder what is going on… can you check your loop speed? The ESP32 is a very fast MCU, and velocity calculations have a time-dependent component… perhaps the loop is too fast in this case?

On the other hand, you write you’re getting 400us loop time, about 2.5kHz. That’s actually ok.

For the motor stationary case, the error is <0.002, this also seems a bit high to me. This corresponds more to 12 bit than 14 bit.

What kind of magnitude reading does the sensor give you? Is the magnet a good one, and well centred?

In the past I had problems with an AS5048A in SPI mode. The issue was the jumper wires I was using: once I soldered the SPI wires, it worked fine.

If the motion downsample is set to 10, doesn’t that make the velocity controller loop 4 ms at 250 hz? I’m not sure what bandwidth you can achieve with that kind of frequency?

The cogging disturbance at 5 rad/s is ~8.7 hz.

Btw have you tried changing the low pass filter value or the output ramp?

Or increasing the Kp to increase the stiffness of your controller?

1 Like

Good call, I did not look at the code, I just took the 0.4ms number given.

So then yes, 250Hz is too slow. When we look at the diagram for the “motor not running” does this mean the motor is set to 0 target velocity, or is the motor disabled with motor.disable(), or is the motor electrically disconnected?

I’m thinking that at 250Hz the oscillations you may be seeing are just the controller oscillating back and forth, because it doesn’t get a chance to correct often enough?

But I’m also wondering why you only get 400us loop times on an ESP32? What speed is your SPI bus set to?

I removed motion_downsample and it’s way better now. The loop is running at ~18kHz. I still get some noise in the angle returned by the sensor but it’s possible it’s because the sensor is not well aligned. I’m going to re-print another mount for the sensor.

I’ve logged the magnitude returned by the sensor every 50ms without anything else in the loop, motor not running, while periodically turning the motor shaft by hand:

Does this seems normal?

I’ve never plotted it like this, so I’m unsure, but I don’t think those spikes are good… I would have expected it to be much smoother…

I’ll have to run some plots of my own and get back to you on this…