Quadrature encoder doesn't work in closed loop :(

{EDIT: This issue was caused by a bad encoder}

I’m about 0 for 10 with sensors now :frowning: and staring to think I’m just cursed.

Motor: 42BLS02
Sensor: 1024 PPR quadrature optical encoder 5-24V A/B/I quadrature encoder, coupled to front shaft facing motor
Controller: NUCLEO-64, G431RB
Driver+PowerAmp: FOCShield
Mode: Torque (voltage feedback)

-System start starts, find electrical zero.
-Monitor shows that encoder is wired correctly (shows +6.28 rad if I turn the shaft).
-When I command a torque, the motor spins about a half turn, then halts.
-Per above, I have the encoder coupled to the motor output shaft , facing the motor. I tried reversing the A/B phases to no avail
-The motor works (albeit not optimally) with other encoders (Hall, magnetic), and works great in openloop

Code
#include <SimpleFOC.h>
#include “Arduino.h”

Encoder encoder = Encoder(3, 2, 1024, 4);
void doA(){encoder.handleA();}
void doB(){encoder.handleB();}
void doC(){encoder.handleIndex();}

BLDCMotor motor = BLDCMotor(4, 1, 250);
// PHASE A B C En
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);

// commander communication instance
Commander command = Commander(Serial);
// void doMotor(char* cmd) { command.motor(&motor, cmd); }
void doTarget(char* cmd) {command.scalar(&motor.target, cmd);}
void doLimit(char* cmd) {command.scalar(&motor.voltage_limit, cmd);}
void doMotor(char* cmd) { command.motor(&motor, cmd); }

void setup() {
encoder.init();
encoder.enableInterrupts(doA, doB, doC);

// link the motor to the sensor
motor.linkSensor(&encoder);
// driver config
// power supply voltage [V]
driver.voltage_power_supply = 12;
driver.voltage_limit = 12;
driver.init();
// link driver
motor.linkDriver(&driver);
// link current sense and the driver

motor.controller = MotionControlType::torque;
//motor.controller = MotionControlType::velocity;
// default voltage_power_supply
motor.voltage_sensor_align = 4;
motor.voltage_limit = 2;
motor.current_limit = 10;
motor.velocity_limit = 20;
// contoller configuration based on the controll type
motor.PID_velocity.P = 0.1;
motor.PID_velocity.I = 0.0;
motor.PID_velocity.D = 0;
motor.PID_velocity.output_ramp = 100;
motor.PID_velocity.limit = 20;
// angle loop controller
motor.P_angle.P = 20;
motor.LPF_velocity.Tf = 0.2;

// set the inital target value
motor.target = 0;

Serial.begin(921600); // WARNING: low value like 115200 cause distorted FOC
motor.useMonitoring(Serial);
motor.monitor_variables = _MON_TARGET | _MON_VOLT_Q | _MON_VOLT_D | _MON_CURR_Q | _MON_CURR_D | _MON_VEL | _MON_ANGLE; // monitor target velocity and angle

//motor.foc_modulation = SpaceVectorPWM;
// initialise motor
motor.init();
// align encoder and start FOC
motor.initFOC();
// commnads
command.add(‘T’, doTarget, “target”); // ssss space
command.add(‘L’, doLimit, “voltage limit”);
command.add(‘M’,doMotor,“motor”);
_delay(1000);
}

void loop() {

// iterative setting FOC phase voltage
motor.loopFOC();
// iterative function setting the outter loop target
motor.move();
// motor monitoring
motor.monitor();
// user communication
command.run();

}

Sorry please disregard (it was a bad encoder, I should have checked this before posting)

1 Like