Sure… Here is the example code I am using. I am also attaching the AS5048A code I have used for testing and its output.
Hardware Setup - I am using a basecam BGC board which uses the ATmega328P microcontroller. The spi lines of the basecam are connected with the AS5048A.
To make the motor move, I type the command - T 200 in the terminal
/***
* Position/angle motion control example
* Steps:
* 1) Configure the motor and magnetic sensor
* 2) Run the code
* 3) Set the target angle (in radians) from serial terminal
* */
#include <SimpleFOC.h>
#include <SPI.h>
// Define the chip select pin
const int CSPin = A4;
// SPI settings for AS5048A
SPISettings AS5048ASettings(1000000, MSBFIRST, SPI_MODE1);
// magnetic sensor instance - SPI (config, chip select pin)
MagneticSensorSPI sensor = MagneticSensorSPI(AS5048_SPI, CSPin);
// magnetic sensor instance - MagneticSensorI2C
//MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
// magnetic sensor instance - analog output
// MagneticSensorAnalog sensor = MagneticSensorAnalog(A1, 14, 1020);
// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(3, 5, 6);
// Stepper motor & driver instance
//StepperMotor motor = StepperMotor(50);
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6, 8);
// angle set point variable
float target_angle = 50;
// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_angle, cmd); }
void setup() {
// use monitoring with serial
Serial.begin(115200);
// enable more verbose output for debugging
// comment out if not needed
SimpleFOCDebug::enable(&Serial);
// initialise magnetic sensor hardware
sensor.init();
// link the motor to the sensor
motor.linkSensor(&sensor);
// driver config
// power supply voltage [V]
driver.voltage_power_supply = 12;
driver.init();
// link the motor and the driver
motor.linkDriver(&driver);
// choose FOC modulation (optional)
motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
// set motion control loop to be used
motor.controller = MotionControlType::angle;
// contoller configuration
// default parameters in defaults.h
// velocity PI controller parameters
motor.PID_velocity.P = 4.0f;
motor.PID_velocity.I = 20;
motor.PID_velocity.D = 3;
// 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.01f;
// angle P controller
motor.P_angle.P = 20;
// maximal velocity of the position control
motor.velocity_limit = 20;
// comment out if not needed
motor.useMonitoring(Serial);
// initialize motor
motor.init();
// align sensor and start FOC
motor.initFOC();
// add target command T
command.add(‘T’, doTarget, “target angle”);
Serial.println(F(“Motor ready.”));
Serial.println(F(“Set the target angle using serial terminal:”));
_delay(1000);
}
void loop() {
// main FOC algorithm function
// the faster you run this function the better
// Arduino UNO loop ~1kHz
// Bluepill loop ~10kHz
motor.loopFOC();
// 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 motor.target in the code
motor.move(target_angle);
// function intended to be used with serial plotter to monitor motor variables
// significantly slowing the execution down!!!
// motor.monitor();
// user communication
command.run();
}
The output for my code is -
MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: Failed to notice movement
MOT: Init FOC failed.
Motor ready.
Set the target angle using serial terminal:
Warn: \r detected!
200.000
The Code which works for my AS5048A is -
#include <SPI.h>
// Define the chip select pin
const int CSPin = A4;
// SPI settings for AS5048A
SPISettings AS5048ASettings(1000000, MSBFIRST, SPI_MODE1);
uint16_t readAS5048A() {
uint16_t angle = 0;
// Start SPI transaction
SPI.beginTransaction(AS5048ASettings);
// Pull CS low to select sensor
digitalWrite(CSPin, LOW);
// Send read command (0xFFFF)
SPI.transfer16(0xFFFF);
// Pull CS high
digitalWrite(CSPin, HIGH);
delayMicroseconds(50);
// Pull CS low again to read data
digitalWrite(CSPin, LOW);
// Read the angle data
angle = SPI.transfer16(0xFFFF);
delay(10);
// Pull CS high
digitalWrite(CSPin, HIGH);
// End SPI transaction
SPI.endTransaction();
// Mask to get only 14-bit data (remove parity and error flag bits)
angle = angle & 0x3FFF;
return angle;
}
void setup() {
Serial.begin(115200);
Serial.println(“AS5048A Angle Reader - SPI”);
delay(100);
// Set the chip select pin as output
pinMode(CSPin, OUTPUT);
digitalWrite(CSPin, HIGH);
delay(500);
// Begin SPI communication
SPI.begin();
}
void loop() {
// Read angle from AS5048A
uint16_t rawAngle = readAS5048A();
// Convert to degrees (14-bit resolution)
float angleDegrees = (float)rawAngle * 360.0 / 16384.0;
Serial.print("Raw: "); Serial.print(rawAngle);
Serial.print(" | Angle: "); Serial.print(angleDegrees, 2); Serial.println(“°”);
delay(100);
}
And the output for this encoder read is -
Raw: 7484 | Angle: 164.44°
Raw: 7484 | Angle: 164.44°
Raw: 7484 | Angle: 164.44°
Raw: 7482 | Angle: 164.40°
Raw: 7482 | Angle: 164.40°
Raw: 7481 | Angle: 164.38°
Raw: 7486 | Angle: 164.49°
Raw: 7478 | Angle: 164.31°
Raw: 7480 | Angle: 164.36°