Skip to content

Instantly share code, notes, and snippets.

@lixit
Last active July 16, 2023 09:37
Show Gist options
  • Save lixit/bd32d8edcfafb042eb106ae3ebd3510b to your computer and use it in GitHub Desktop.
Save lixit/bd32d8edcfafb042eb106ae3ebd3510b to your computer and use it in GitHub Desktop.

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());
}
  1. 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();
}

  1. 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

  1. 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());
}
  1. 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


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment