Hi all, recently i encountered with a bizarre issue with custom STM32 FOC board: the motor calibrates then end up in no reaction
I used 32G431CBU6 so same as the G431 ESC, did bit of changes on pin assignment as: BLDCDriver3PWM driver = BLDCDriver3PWM(PA2, PA3, PA1, PA5); // 3PWM
I experimented couple times as observed that if disabling serial.begin, motor would still calibrate on ESP32 based boards, but not for STM. So i kept serial but due to board layout, i used serial3, this seems no impact. For encoder it seems esp32 boards would calibrate motor no matter i attach it or not, where on stm as long as encoder is off, it will just keep injecting more currents into motor after getting powered on. ---->
I thus set STM32 to use I2C3 pins as designed on my pcb: TwoWire Wire3(PC11, PA8); so now all i got is motor does tried to calibrate, but then output on all 3 phases will be gone i probed with oscilloscope, and its none after calibration.
Im wondering does this library work differently for STM MCUs? or should i only stick to USART1 and I2C1 instead of using alternatives? Many thanks for any help!!
#include <SimpleFOC.h>
#include <Wire.h>
// PID Constants
float current_P = 10;
float velocity_P = 10;
float angle_P = 20;
float angle_I = 0.1;
float angle_D = 0;
// Motor instance
BLDCMotor motor = BLDCMotor(7); // Set accurate pole pairs
BLDCDriver3PWM driver = BLDCDriver3PWM(PA2, PA3, PA1, PA5); // 3PWM
// I2C Sensor Setup (PA8 SCL, PC11 SDA)
TwoWire Wire3(PC11, PA8);
//TwoWire Wire3(PA8, PC11);
MagneticSensorI2C sensor3 = MagneticSensorI2C(AS5600_I2C);
TwoWire Wire3(PC11, PA8);
// Current Sense
LowsideCurrentSense current_sense = LowsideCurrentSense(0.005, 20, PA6, PA7);
// Initialize USART3 (PC10 TX, PC11 RX)
HardwareSerial Serial3(PB10, PB11);
// Commander Interface
Commander command = Commander(Serial3);
void doTarget(char* cmd) { command.scalar(&motor.target, cmd); }
void setup() {
// Initialize USART3
Serial3.begin(115200);
_delay(750);
Wire3.begin();
Wire3.setClock(400000);
sensor3.init(&Wire3);
motor.linkSensor(&sensor3);
// Driver configuration
driver.voltage_power_supply = 12;
driver.init();
motor.linkDriver(&driver);
current_sense.linkDriver(&driver);
// Motor control settings
motor.voltage_sensor_align = 1;
motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
motor.torque_controller = TorqueControlType::foc_current;
motor.controller = MotionControlType::velocity;
motor.motion_downsample = 0;
// PID and Filtering
motor.PID_velocity.P = velocity_P;
motor.PID_velocity.I = 0;
motor.LPF_velocity.Tf = 0.001;
motor.PID_velocity.output_ramp = 50;
motor.P_angle.P = angle_P;
motor.P_angle.I = angle_I;
motor.P_angle.D = angle_D;
motor.LPF_angle.Tf = 0.0;
motor.PID_current_q.P = current_P;
motor.PID_current_q.I = 0.00;
motor.LPF_current_q.Tf = 0.02;
motor.PID_current_d.P = current_P;
motor.PID_current_d.I = 0.00;
motor.LPF_current_d.Tf = 0.02;
// Limits
motor.velocity_limit = 20.0;
motor.voltage_limit = 5;
motor.current_limit = 5;
// Enable Serial Monitoring via USART3
motor.useMonitoring(Serial3);
motor.monitor_variables = _MON_VEL;
motor.monitor_downsample = 0;
// Initialize Motor and Current Sense
motor.init();
current_sense.init();
current_sense.skip_align = true;
current_sense.gain_a *= -1;
current_sense.gain_b *= -1;
current_sense.gain_c *= -1;
motor.linkCurrentSense(¤t_sense);
// Start FOC
motor.initFOC();
motor.enable();
// Initial Target Value
motor.target = 10;
// Register Commands for USART3
command.add(‘T’, doTarget, (char *)“target”);
Serial3.println(“Motor armed, Inline sensing on USART3”);
_delay(1000);
}
void loop() {
// FOC loop
motor.loopFOC();
motor.move();
// Serial Communication via USART3
command.run();
}