platformio.ini
monitor_speed = 115200
lib_archive = false
main.cpp
#include <SimpleFOC.h>
// MagneticSensorSPI(int cs, float _cpr, int _angle_register)
// cs - SPI chip select pin
// bit_resolution - magnetic sensor resolution
// angle_register - (optional) angle read register - default 0x3FFF
// D13 - sck
// D12 - cipo
// D11 - copi
// D10 - ss
MagneticSensorSPI sensor = MagneticSensorSPI(10, 14, 0x3FFF);
void setup(){
...
// spi mode (phase/polarity of read/writes) i.e one of SPI_MODE0 | SPI_MODE1 (default) | SPI_MODE2 | SPI_MODE3
sensor.spi_mode = SPI_MODE0;
// speed of the SPI clock signal - default 1MHz
sensor.clock_speed = 500000;
sensor.init();
...
}
AS5047
// instance of AS5047/AS5147 sensor
MagneticSensorSPI sensor = MagneticSensorSPI(10, AS5147_SPI);
Test AS5047
#include <SimpleFOC.h>
// MagneticSensorSPI(int cs, float _cpr, int _angle_register)
// cs - SPI chip select pin
// bit_resolution - sensor resolution
// angle_register - (optional) angle read register - default 0x3FFF
// MagneticSensorSPI as5047u = MagneticSensorSPI(10, 14, 0x3FFF);
// or quick config
MagneticSensorSPI as5047 = MagneticSensorSPI(AS5147_SPI, 10);
void setup() {
// monitoring port
Serial.begin(115200);
// initialise magnetic sensor hardware
as5047.init();
Serial.println("as5047 ready");
_delay(1000);
}
void loop() {
// IMPORTANT - call as frequently as possible
// update the sensor values
as5047.update();
// display the angle and the angular velocity to the terminal
Serial.print(as5047.getAngle());
Serial.print("\t");
Serial.println(as5047.getVelocity());
}
- test
#include <SimpleFOC.h>
// magnetic sensor instance - SPI
MagneticSensorSPI sensor = MagneticSensorSPI(AS5147_SPI, 10);
// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);
// commander interface
Commander command = Commander(Serial);
void onMotor(char* cmd){ command.motor(&motor, cmd); }
void setup() {
// 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 driver
motor.linkDriver(&driver);
// set control loop type to be used
motor.controller = MotionControlType::torque;
// contoller configuration based on the control type
motor.PID_velocity.P = 0.2;
motor.PID_velocity.I = 20;
motor.PID_velocity.D = 0;
// default voltage_power_supply
motor.voltage_limit = 12;
// velocity low pass filtering time constant
motor.LPF_velocity.Tf = 0.01;
// angle loop controller
motor.P_angle.P = 20;
// angle loop velocity limit
motor.velocity_limit = 50;
// use monitoring with serial for motor init
// monitoring port
Serial.begin(115200);
// comment out if not needed
motor.useMonitoring(Serial);
// initialise motor
motor.init();
// align encoder and start FOC
motor.initFOC();
// set the inital target value
motor.target = 2;
// define the motor id
command.add('A', onMotor, "motor");
// Run user commands to configure and the motor (find the full command list in docs.simplefoc.com)
Serial.println(F("Motor commands sketch | Initial motion control > torque/voltage : target 2V."));
_delay(1000);
}
void loop() {
// iterative setting FOC phase voltage
motor.loopFOC();
// iterative function setting the outter loop target
// velocity, position or voltage
// if tatget not set in parameter uses motor.target variable
motor.move();
// user communication
command.run();
}
- command
?
ME0 - enable motor
MC # get motion control mode
MC0 - torque # set to torque mode
1 - velocity
2 - angle
3 - velocity_openloop
4 - angle_openloop
M1 # target torque1V for voltage mode or 1A for foc_current or dc_current
# target velocity 1rad/s
# target angle 1rad/s
DRV8301
- Testing the sensor: AS5047
#include <SimpleFOC.h>
// MagneticSensorSPI(int cs, float _cpr, int _angle_register)
// cs - SPI chip select pin
// bit_resolution - sensor resolution
// angle_register - (optional) angle read register - default 0x3FFF
// MagneticSensorSPI as5047u = MagneticSensorSPI(10, 14, 0x3FFF);
// or quick config
MagneticSensorSPI as5047 = MagneticSensorSPI(AS5047_SPI, D8);
void setup() {
// monitoring port
Serial.begin(115200);
// initialise magnetic sensor hardware
as5047.init();
Serial.println("as5047 ready");
_delay(1000);
}
void loop() {
// IMPORTANT - call as frequently as possible
// update the sensor values
as5047.update();
// display the angle and the angular velocity to the terminal
Serial.print(as5047.getAngle());
Serial.print("\t");
Serial.println(as5047.getVelocity());
}
- Testing the driver + motor combination - open-loop
// Open loop motor control example
#include <SimpleFOC.h>
#include <DRV8301.h>
// Motor instance
BLDCMotor motor = BLDCMotor(6);
BLDCDriver3PWM driver = BLDCDriver3PWM(D4, D5, D6);
// DRV8301 gate_driver = DRV8301(MOSI, MISO, SCLK, CS, EN_GATE, FAULT);
DRV8301 gate_driver = DRV8301(D11, D12, D13, D10, PB9, PB8);
// MagneticSensorSPI as5047 = MagneticSensorSPI(AS5147_SPI, D8);
void serialReceiveUserCommand();
void setup()
{
// driver config
// power supply voltage [V]
driver.voltage_power_supply = 9;
driver.init();
gate_driver.begin(PWM_INPUT_MODE_3PWM);
// link the motor and the driver
motor.linkDriver(&driver);
// limiting motor movements
motor.voltage_limit = 0.2; // [V]
motor.velocity_limit = 5; // [rad/s]
// open loop control config
motor.controller = MotionControlType::velocity_openloop;
// init motor hardware
motor.init();
Serial.begin(115200);
Serial.println("Motor ready!");
_delay(1000);
}
float target_velocity = 0; // [rad/s]
void loop()
{
// open loop velocity movement
// using motor.voltage_limit and motor.velocity_limit
motor.move(target_velocity);
// receive the used commands from serial
serialReceiveUserCommand();
}
// utility function enabling serial communication with the user to set the target values
// this function can be implemented in serialEvent function as well
void serialReceiveUserCommand()
{
// a string to hold incoming data
static String received_chars;
while (Serial.available())
{
// get the new byte:
char inChar = (char)Serial.read();
// add it to the string buffer:
received_chars += inChar;
// end of user input
if (inChar == '\n')
{
// change the motor target
target_velocity = received_chars.toFloat();
Serial.print("Target velocity ");
Serial.println(target_velocity);
// reset the command buffer
received_chars = "";
}
}
}
// MagneticSensorSPI(int cs, float _cpr, int _angle_register)
// cs - SPI chip select pin
// bit_resolution - sensor resolution
// angle_register - (optional) angle read register - default 0x3FFF
// MagneticSensorSPI as5047u = MagneticSensorSPI(10, 14, 0x3FFF);
// or quick config