Hello guys, Rick here
I’m having problem with the closed loop implementation. I was using a Sin/Cos absolute encoder (the RM08 to be precise), but it didn’t seem to work. So I bought a common sensor like the AS5600 (the white module) to try some luck. However, the motor is not running. The tests I made so far:
- Motor is running in velocity open loop, no problems.
- The microcontroller (STM32F4) is reading the sensor, no problems.
- The initialization goes to the loop (no return) and the loop is running fine.
Could it be the PID variable I have to tune to make the algorithm work? I don’t think so, any suggestion is welcome.
Arduino for stm32 code
#include <SimpleFOC.h>
#include <Wire.h>
#include <math.h>
#define USART1_TX PA9
#define USART1_RX PA10
// Create a SoftwareSerial object
HardwareSerial mySerial(USART1_RX, USART1_TX);
#define ADC_COSZ PB0
#define ADC_SINZ PB1
#define ADC_OFFSET (1.55)
//MagneticSensorSineCos sensor = MagneticSensorSineCos(ADC_SINZ, ADC_COSZ, ADC_OFFSET);
// as5600 sensor quick config
TwoWire myWire(PC9, PA8); // SDA, SCL
//myWire.setClock(400000);
MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
#define LPTN_EN PB12
#define DRV_EN PB5
#define FAULT_Z PA7
// ===== BLDC motor & driver configZ ==== //
#define IN1_Z PC6
#define IN2_Z PC7
#define IN3_Z PC8
BLDCMotor motorZ = BLDCMotor(6); // I think our motor has 6 pole pairs
BLDCDriver3PWM driverZ = BLDCDriver3PWM(IN1_Z, IN2_Z, IN3_Z);
uint8_t vtarget_arr[4] = {80, 100, 200, 0};
uint8_t i = 0; // current index
unsigned long lastUpdate = 0; // last time the index was changed
const unsigned long interval = 1000; // 500ms interval
void setup() {
//mySerial.println("Settiung UP!");
mySerial.begin(9600);
pinMode(FAULT_Z, INPUT);
if(digitalRead(FAULT_Z)==LOW){
mySerial.println("FAULT happened!")
}
*/
sensor.init(&myWire);
motorZ.linkSensor(&sensor);
// =============================== //
driverZ.voltage_power_supply = 9;
if(!driverZ.init()){
mySerial.println("DriverZ init failed!");
return;
}
// ============MOTORZ=================== //
motorZ.linkDriver(&driverZ);
motorZ.voltage_limit = 1; // [V]
motorZ.foc_modulation = FOCModulationType::SpaceVectorPWM;
motorZ.controller = MotionControlType::velocity;
// =============CLOSED LOOP=================== //
// controller configuration based on the control type
// velocity PID controller parameters
motorZ.PID_velocity.P = 3.0;
motorZ.PID_velocity.I = 5.0;
motorZ.PID_velocity.D = 0.001;
// jerk control using voltage voltage ramp
// default value is 300 volts per sec ~ 0.3V per millisecond
motorZ.PID_velocity.output_ramp = 1000;
// velocity low pass filtering
// default 5ms - try different values to see what is the best.
// the lower the less filtered
motorZ.LPF_velocity.Tf = 0.01;
// of current
motorZ.current_limit = 2; // Amps - default 0.2Amps
// ============= INITIALIZATION OF MOTORS =============== //
if(!motorZ.init()){
mySerial.println("MotorZ init failed!");
return;
}
// align sensor and start FOC
motorZ.initFOC();
//mySerial.println("Settiung up ended!");
delay(1000);
}
void loop() {
motorZ.loopFOC();
motorZ.move(100);
/*
sensor.update();
mySerial.println(sensor.getVelocity());
motorZ.move(vtarget_arr[i]);
// Check if 500ms have passed
if (millis() - lastUpdate >= interval) {
lastUpdate = millis();
i = (i + 1) % 4; // cycle through 0, 1, 2, 3
}
*/
}
Again, my motor is the 1104 4300KV from here.