AS5048B Magnetic Encoder with SimpleFOC board for Position Control

We are using following components for building the Position control of BLDC Motor

  1. SimpleFOC board received last week
  2. iPower GM2804 BLDC Motor
  3. AS5048B Magnetic Encoder

The magnetic encoder is connected through I2C ports and modified the file angle_control file to establish I2C communication, Pole pairs, bit resolution, Memory map.

#include <SimpleFOC.h>

// magnetic sensor instance - SPI
//MagneticSensorSPI sensor = MagneticSensorSPI(10, 14, 0x3FFF);
// magnetic sensor instance - MagneticSensorI2C
MagneticSensorI2C sensor = MagneticSensorI2C(0x40, 14, 0xFE, 8);
// magnetic sensor instance - analog output
// MagneticSensorAnalog sensor = MagneticSensorAnalog(A1, 14, 1020);

// BLDC motor instance
BLDCMotor motor = BLDCMotor(9, 10, 6, 7, 8);
// Stepper motor instance
//StepperMotor motor = StepperMotor(9, 5, 10, 6, 50, 8);

void setup() {

  // initialise magnetic sensor hardware
  // link the motor to the sensor

  // power supply voltage
  // default 12V
  motor.voltage_power_supply = 12;
  // choose FOC modulation (optional)
  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;

  // set motion control loop to be used
  motor.controller = ControlType::angle;

  // contoller configuration 
  // default parameters in defaults.h

  // velocity PI controller parameters
  motor.PID_velocity.P = 0.2;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0;
  // maximal voltage to be set to the motor
  motor.voltage_limit = 6;
  // velocity low pass filtering time constant
  // the lower the less filtered
  motor.LPF_velocity.Tf = 0.01;

  // angle P controller 
  motor.P_angle.P = 20;
  // maximal velocity of the position control
  motor.velocity_limit = 20;

  // use monitoring with serial 
  // comment out if not needed

  // initialize motor
  // align sensor and start FOC

  Serial.println("Motor ready.");
  Serial.println("Set the target angle using serial terminal:");

// angle set point variable
float target_angle = 0;

void loop() {

  // main FOC algorithm function
  // the faster you run this function the better
  // Arduino UNO loop  ~1kHz
  // Bluepill loop ~10kHz 

  // Motion control function
  // velocity, position or voltage (defined in motor.controller)
  // this function can be run at much lower frequency than loopFOC() function
  // You can also use motor.move() and set the in the code

  // function intended to be used with serial plotter to monitor motor variables
  // significantly slowing the execution down!!!!
  // motor.monitor();
  // user communication

When we provide angle command(in degree) through serial command, it just rotate continuously with vibration. Please provide the solution for this.

Hi, I haven’t completely checked your code, but by default angles are in radians in the SimpleFOC environment. So I would give that a go first.
About the vibrations: this could be caused by controller parameters that are not optimal for your setup. It could also be this issue: SimpleFOCShield routing mistake - v1.3.3 version 11/2020.

motor.PID_velocity.I = 5;
motor.voltage_limit = 4;

You could try commenting out all of the PID and LPF code for now. I got a similar motor working out of the box in angle mode with the default SimpleFOC PID params. When I put in some of the PID params from the example code I had issues.

Also, from my post the other day, make sure your encoder hub/magnet is correctly mounted to your motor (without slipping etc) or else SimpleFOC will get confused - In my case this manifested as constant spinning.

@akashlpatil were you able to resolve your problem.
Please make sure to start with the open loop example, then the voltage control and save the angle control for the last. :smiley:

@Antun_Skuric: Yes it is working after making these changes SimpleFOCShield routing mistake - v1.3.3 version 11/2020

Need to tune the PID values for removing low frequency vibration.

1 Like