Hi All,
I am utilizing a custom board to drive a small BLDC motor with just two current sense lines at A and B.
When using the InlineCurrentSense example I get consistent values at A and B, 0 as expected at C.
When I run the CurrentControl example I get stuck at ErrB as in the subject.
Exploring the code, I notice that this error is thrown inside an if statement, in the case both pins B and C are set.
So I wonder why I get there, since I have not pic C for current sensing, and how to fix the issue.
Many thanks in advance,
Marco
Hey @marcosartore,
Sorry for the delay in answering.
So this message is there to say that when you were applying the voltage to the phase B, the code was not able to identify which one août of the pins B or C is the one measuring the current. I do agree that the off statement is problematic here and this is a bug in the code.
But the problem is real, in your case the current B was not measured.
Which phases are you measuring on the hardware?
Could you show us your code also. It would help.
Also, you can skip the alignment procedure completely if you don’t need it.
Set the current_sense.skip_align=true;
before the motor.initFOC()
.
Thanks Antun for your answer.
Actually I am trying, step by step, to create code for a full-featured FOC control of my motor, as in this picture:
I first successfully read the currents in A and B using this code:
#include <SimpleFOC.h>
// current sensor
// shunt resistor value
// gain value
// pins phase A,B, (C optional)
InlineCurrentSense current_sense = InlineCurrentSense(0.015f, 100.0f, A0, A2);
int triggerPinA = 4;
int triggerPinB = 8;
void setup()
{
pinMode(triggerPinA, OUTPUT);
digitalWrite(triggerPinA, LOW);
pinMode(triggerPinB, OUTPUT);
digitalWrite(triggerPinB, LOW);
// use monitoring with serial
Serial.begin(115200);
// enable more verbose output for debugging
// comment out if not needed
SimpleFOCDebug::enable(&Serial);
// initialise the current sensing
if(!current_sense.init()){
Serial.println("Current sense init failed.");
return;
}
// for SimpleFOCShield v2.01/v2.0.2
// current_sense.gain_b *= -1; ????
Serial.println("Current sense ready.");
}
void loop()
{
PhaseCurrent_s currents = current_sense.getPhaseCurrents();
float current_magnitude = current_sense.getDCCurrent();
Serial.print(currents.a*1000); // milli Amps
Serial.print("\t");
Serial.print(currents.b*1000); // milli Amps
Serial.print("\t");
Serial.print(currents.c*1000); // milli Amps
Serial.print("\t");
Serial.println(current_magnitude*1000); // milli Amps
Serial.println("");
delay(50);
}
Then tried the current control but I got stuck in the ErrB mentioned problem using this code:
#include <SimpleFOC.h>
// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(4);
BLDCDriver3PWM driver = BLDCDriver3PWM(4, 8, 12, 22);
#define SENSOR1_CS 42
// magnetic sensor instance - SPI
MagneticSensorSPI sensor = MagneticSensorSPI(AS5147_SPI, SENSOR1_CS);
// current sensor
InlineCurrentSense current_sense = InlineCurrentSense(0.015f, 100.0f, A0, A2, NOT_SET);
// current set point variable
float target_current = 0;
// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_current, cmd); }
void setup()
{
// use monitoring with serial
Serial.begin(115200);
// enable more verbose output for debugging
// comment out if not needed
SimpleFOCDebug::enable(&Serial);
// initialize encoder sensor hardware
sensor.init();
// link the motor to the sensor
motor.linkSensor(&sensor);
// driver config
// power supply voltage [V]
driver.voltage_power_supply = 12;
// *************** ADDED
driver.voltage_limit = 12;
// ************** VERY IMPORTANT command, missing in the original
motor.voltage_sensor_align = 2;
driver.init();
// link driver
motor.linkDriver(&driver);
// link current sense and the driver
current_sense.linkDriver(&driver);
// current sense init hardware
current_sense.init();
// link the current sense to the motor
motor.linkCurrentSense(¤t_sense);
// set torque mode:
// TorqueControlType::dc_current
// TorqueControlType::voltage
// TorqueControlType::foc_current
motor.torque_controller = TorqueControlType::foc_current;
// set motion control loop to be used
motor.controller = MotionControlType::torque;
// foc currnet control parameters (Arduino UNO/Mega)
//motor.PID_current_q.P = 5;
//motor.PID_current_q.I= 300;
//motor.PID_current_d.P= 5;
//motor.PID_current_d.I = 300;
//motor.LPF_current_q.Tf = 0.01f;
//motor.LPF_current_d.Tf = 0.01f;
// foc currnet control parameters (stm/esp/due/teensy)
motor.PID_current_q.P = 1;
motor.PID_current_q.I= 100;
motor.PID_current_d.P= 1;
motor.PID_current_d.I = 100;
motor.LPF_current_q.Tf = 0.002f;
motor.LPF_current_d.Tf = 0.002f;
// 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 current"); // T0.2 is a GOOD VALUE for RS motor
Serial.println(F("Motor ready."));
Serial.println(F("Set the target current 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 torque (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_current);
// user communication
command.run();
}
Thanks a lot,
Marco