Hi,
We’re having issues getting lowside current sense to work.
Current sense init failed!
Code generated with SimpleFOCGenerator
Any obious errors?
#include <SimpleFOC.h>
//HardwareSerial Serial1(USART1);
// BLDC motor instance BLDCMotor(polepairs, (R), (KV))
BLDCMotor motor = BLDCMotor(14);
// BLDC driver instance BLDCDriver3PWM(phA, phB, phC, (en))
BLDCDriver3PWM driver = BLDCDriver3PWM(PB0, PA7, PA6, PA8);
// position / angle sensor instance HallSensor(hallA, hallB , hallC , pole pairs)
HallSensor sensor = HallSensor(PB13, PB14, PB12, 14);
void doA(){sensor.handleA();}
void doB(){sensor.handleB();}
void doC(){sensor.handleC();}
// lowside current sense instance LowsideCurrentSense(R, gain, phA, phB, (phC))
LowsideCurrentSense currentsense = LowsideCurrentSense(0.007, 10, PA0, PA1, PA2);
// commander instance
Commander command = Commander(Serial);
void doTarget(char* cmd){command.motion(&motor, cmd);}
void setup() {
// start serial
Serial.begin(115200);
// USE_EXTERN is default (1k - 5k recommended), change to USE_INTERN if needed
sensor.pullup = Pullup::USE_EXTERN;
// initialize sensor
sensor.init();
// enable Hall effect interrupts
sensor.enableInterrupts(doA, doB, doC);
// link sensor to motor
motor.linkSensor(&sensor);
// set power supply voltage
driver.voltage_power_supply = 12;
// set driver voltage limit, this phase voltage
driver.voltage_limit = 4;
// initialize driver
driver.init();
// link driver to motor
motor.linkDriver(&driver);
// link driver to current sense
currentsense.linkDriver(&driver);
// set torque control type to voltage (default)
motor.torque_controller = TorqueControlType::voltage;
// set FOC modulation type to sinusoidal
motor.foc_modulation = FOCModulationType::SinePWM;
// velocity PID controller
motor.PID_velocity.P = 0.2;
motor.PID_velocity.I = 2;
motor.PID_velocity.D = 0;
// set motor voltage limit, this limits Vq
motor.voltage_limit = 2;
// set motor velocity limit
motor.velocity_limit = 20;
// set motor current limit, this limits Iq
motor.current_limit = 2;
// use monitoring
motor.useMonitoring(Serial);
// initialize motor
motor.init();
// initialize current sensing and link it to the motor
// https://docs.simplefoc.com/inline_current_sense#where-to-place-the-current_sense-configuration-in-your-foc-code
currentsense.init();
if (currentsense.init()) Serial1.println("Current sense init success!");
else{
Serial1.println("Current sense init failed!");
return;
}
motor.linkCurrentSense(¤tsense);
// align sensor and start FOC
motor.initFOC();
// add command to commander
command.add('M', doTarget, "target");
_delay(1000);
}
void loop() {
// main FOC algorithm function
// the faster you run this function the better
motor.loopFOC();
// this function can be run at much lower frequency than loopFOC()
motor.move();
// significantly slowing the execution down
motor.monitor();
// user communication
command.run();
}
What, if you use FOC_current
instead?
Sorry for a very late reply. Had to get the motor working so used trapezoidal commutation, would like to get FOC working.
Don’t see why foc_current would make any difference as many example codes does not use foc_current. Did try and it made no difference.
MCU is STM32F103CBU with DRV8353RH motor driver.
PA0 and PA1 is connected to sense A and sense B on DRV8353RH
Output from terminal below code.
#include <SimpleFOC.h>
HardwareSerial Serial1(USART1);
const int INH_A = PB0;
const int INH_B = PA7;
const int INH_C= PA6;
#define EN_GATE PA8
// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(14);
BLDCDriver3PWM driver = BLDCDriver3PWM(INH_A, INH_B, INH_C, EN_GATE);
// hall sensor instance
HallSensor sensor = HallSensor(PB12, PB13, PB14, 14);
// Interrupt routine intialisation
// channel A and B callbacks
void doA(){sensor.handleA();}
void doB(){sensor.handleB();}
void doC(){sensor.handleC();}
// instantiate the commander
Commander command = Commander(Serial1);
void onMotor(char* cmd){ command.motor(&motor, cmd); }
LowsideCurrentSense cs = LowsideCurrentSense(0.007f, 10.00f, PA0, PA1, _NC);
void setup() {
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 = 48;
driver.pwm_frequency = 15000;
driver.init();
// link the motor and the driver
motor.linkDriver(&driver);
// link current sense and the driver
cs.linkDriver(&driver);
// align voltage
motor.voltage_sensor_align = 5;
// control loop type and torque mode
motor.torque_controller = TorqueControlType::foc_current;
motor.controller = MotionControlType::torque;
motor.motion_downsample = 0.0;
// velocity loop PID
motor.PID_velocity.P = 0.2;
motor.PID_velocity.I = 5.0;
// Low pass filtering time constant
motor.LPF_velocity.Tf = 0.02;
// angle loop PID
motor.P_angle.P = 20.0;
// Low pass filtering time constant
motor.LPF_angle.Tf = 0.0;
// current q loop PID
motor.PID_current_q.P = 3.0;
motor.PID_current_q.I = 100.0;
// Low pass filtering time constant
motor.LPF_current_q.Tf = 0.02;
// current d loop PID
motor.PID_current_d.P = 3.0;
motor.PID_current_d.I = 100.0;
// Low pass filtering time constant
motor.LPF_current_d.Tf = 0.02;
// Limits
motor.velocity_limit = 100.0; // 100 rad/s velocity limit
motor.voltage_limit = 12.0; // 12 Volt limit
motor.current_limit = 2.0; // 2 Amp current limit
// use monitoring with serial for motor init
// monitoring port
Serial1.begin(115200);
// comment out if not needed
motor.useMonitoring(Serial1);
motor.monitor_variables = _MON_CURR_Q | _MON_CURR_D; // monitor the two currents d and q
motor.monitor_downsample = 1000;
// initialise motor
motor.init();
cs.init();
cs.skip_align = true;
// driver 8302 has inverted gains on all channels
//cs.gain_a *=-1;
//cs.gain_b *=-1;
//cs.gain_c *=-1;
motor.linkCurrentSense(&cs);
// align encoder and start FOC
motor.initFOC(4.19, CCW);
// set the inital target value
motor.target = 0;
// define the motor id
command.add('M', onMotor, "motor");
Serial1.println(F("Full control example: "));
Serial1.println(F("Run user commands to configure and the motor (find the full command list in docs.simplefoc.com) \n "));
Serial1.println(F("Initial motion control loop is voltage loop."));
Serial1.println(F("Initial target voltage 2V."));
_delay(1000);
}
void loop() {
// main FOC algorithm function
motor.loopFOC();
// Motion control function
motor.move();
// display the currents
motor.monitor();
// user communication
command.run();
}
17:27:22.942 -> MOT: Monitor enabled!
17:27:22.942 -> MOT: Init
17:27:23.437 -> MOT: Enable driver.
17:27:24.472 -> MOT: Align sensor.
17:27:24.472 -> MOT: Skip dir calib.
17:27:24.472 -> MOT: Skip offset calib.
17:27:24.967 -> MOT: Init FOC error, current sense not initialized
17:27:24.967 -> MOT: Init FOC failed.
17:27:24.967 -> Full control example:
17:27:24.967 -> Run user commands to configure and the motor (find the full command list in docs.simplefoc.com)
17:27:24.967 ->
17:27:24.967 -> Initial motion control loop is voltage loop.
17:27:24.967 -> Initial target voltage 2V.