Skip to content

Commit

Permalink
feat(ctrl): voltage control (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
hcd-bdltd authored Feb 8, 2024
2 parents 6a68104 + ad389db commit a468539
Showing 1 changed file with 55 additions and 27 deletions.
82 changes: 55 additions & 27 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
// Open loop motor control example
/**
*
* Torque control example using voltage control loop.
*
* Most of the low-end BLDC driver boards doesn't have current measurement therefore SimpleFOC offers
* you a way to control motor torque by setting the voltage to the motor instead of the current.
*
* This makes the BLDC motor effectively a DC motor, and you can use it in a same way.
*/
#include <SimpleFOC.h>

#define POLE_PAIRS 7
Expand All @@ -7,56 +15,76 @@
BLDCMotor motor = BLDCMotor(POLE_PAIRS);
BLDCDriver6PWM driver = BLDCDriver6PWM(A_PHASE_UH, A_PHASE_UL, A_PHASE_VH, A_PHASE_VL, A_PHASE_WH, A_PHASE_WL);

//target variable
float target_velocity = 0;
// hall sensor instance
HallSensor sensor = HallSensor(A_HALL1, A_HALL2, A_HALL3, POLE_PAIRS);

// Interrupt routine initialisation
// channel A and B callbacks
void doA(){sensor.handleA();}
void doB(){sensor.handleB();}
void doC(){sensor.handleC();}

// voltage set point variable
float target_voltage = 2;
// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); }
void doLimit(char* cmd) { command.scalar(&motor.voltage_limit, cmd); }
void doTarget(char* cmd) { command.scalar(&target_voltage, cmd); }

void setup() {
Serial.begin(115200);
delay(2000);

// initialize hall sensor hardware
sensor.init();
sensor.enableInterrupts(doA, doB, doC);
// link the motor to the sensor
motor.linkSensor(&sensor);

// driver config
// power supply voltage [V]
driver.voltage_power_supply = 12;
// limit the maximal dc voltage the driver can set
// as a protection measure for the low-resistance motors
// this value is fixed on startup
driver.voltage_limit = 6;
driver.init();
// link the motor and the driver
// link driver
motor.linkDriver(&driver);

// limiting motor movements
// limit the voltage to be set to the motor
// start very low for high resistance motors
// current = voltage / resistance, so try to be well under 1Amp
motor.voltage_limit = 3; // [V]

// open loop control config
motor.controller = MotionControlType::velocity_openloop;
// aligning voltage
motor.voltage_sensor_align = 3;

// choose FOC modulation (optional)
motor.foc_modulation = FOCModulationType::SpaceVectorPWM;

// set motion control loop to be used
motor.controller = MotionControlType::torque;

// init motor hardware
motor.init();
// use monitoring with serial
motor.useMonitoring(Serial);

// initialize motor
motor.init();
// align sensor and start FOC
motor.initFOC();

// add target command T
command.add('T', doTarget, "target velocity");
command.add('L', doLimit, "voltage limit");
command.add('T', doTarget, "target voltage");

Serial.println("Motor ready!");
Serial.println("Set target velocity [rad/s]");
Serial.println(F("Motor ready."));
Serial.println(F("Set the target voltage using serial terminal:"));
delay(1000);
}

void loop() {
// open loop velocity movement
// using motor.voltage_limit and motor.velocity_limit
// to turn the motor "backwards", just set a negative target_velocity
motor.move(target_velocity);
// 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_voltage);

// user communication
command.run();
Expand Down

0 comments on commit a468539

Please sign in to comment.