After looking into it more, I have code, and a process for opening simplefocstudio that looks like it is communicating with the system.
Board: Due with a simpleFOCminiboard v1
Motor: single pole pair BLDC, ~20W motor
First, the code I’ve had for a while that runs the system at constant velocity (no simpleFOCstudio). I can change the PIDs, or target velocity, and is spins as I would expect. Pulls up to 0.4 amps.
#include <SimpleFOC.h>
// define BLDC motor
// BLDCMotor(int pp, (optional R, KV))
// - pp - pole pair number
// - R - phase resistance value - optional
// - KV - motor KV rating [rpm/V] - optional
BLDCMotor motor = BLDCMotor( 1,1.35,341 );
// BLDCDriver3PWM( int phA, int phB, int phC, int en)
// - phA, phB, phC - A,B,C phase pwm pins
// - enable pin - (optional input)
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 10, 11, 8);
// Encoder(int encA, int encB , int cpr, int index)
// - encA, encB - encoder A and B pins
// - ppr - impulses per rotation (cpr=ppr*4)
// - index pin - (optional input)
Encoder encoder = Encoder(2, 3, 512);
// channel A and B callbacks
void doA(){encoder.handleA();}
void doB(){encoder.handleB();}
// velocity set point variable
// RPM = Rad/s * 9.54
//
//
float target_velocity_RPM = 300; // RPM
float target_velocity = target_velocity_RPM/9.549296; // rad/s
//float target_velocity = 31.4159; // rad/s
// commander interface
Commander command = Commander(Serial);
void onTarget(char* cmd){ command.scalar(&target_velocity, cmd); }
void setup() {
// initialize encoder hardware
encoder.init();
// hardware interrupt enable
encoder.enableInterrupts(doA, doB);
// power supply voltage
// default 12V
driver.voltage_power_supply = 10; // what your external power supply is set to
driver.init();
// link the motor to the driver
motor.linkDriver(&driver);
// set control loop type to be used
motor.controller = MotionControlType::velocity;
// velocity PI controller parameters
// default P=0.2 I = 20
motor.PID_velocity.P = 0.3;
motor.PID_velocity.I = 10;
//default voltage_power_supply
motor.voltage_limit = 10; //The voltage_limit parameter is intended if, for some reason, you wish to limit the voltage that can be sent to your motor.
// velocity low pass filtering
// default 5ms - try different values to see what is the best.
// the lower the less filtered
//motor.LPF_velocity.Tf = 0.01; // orignal value
motor.LPF_velocity.Tf = 0.005;
// link the motor to the sensor
motor.linkSensor(&encoder);
// initialize motor
motor.init();
// align encoder and start FOC
motor.initFOC();
// add target command T
//command.add('T', doTarget, "target velocity");
command.add('M',onTarget,"my motor");
// monitoring port
Serial.begin(115200);
Serial.println("Motor ready.");
Serial.println("Set the target velocity using serial terminal:");
_delay(1000);
}
void loop() {
// iterative foc function
motor.loopFOC();
// iterative function setting and calculating the velocity loop
// this function can be run at much lower frequency than loopFOC function
motor.move(target_velocity);
// user communication
command.run();
}
Starting from the online code generator, the code I have that simpleFOCstudio will communicate with:
#include <SimpleFOC.h>
// BLDC motor instance BLDCMotor(polepairs, (R), (KV))
BLDCMotor motor = BLDCMotor(1, 1.35, 341);
// BLDC driver instance BLDCDriver3PWM(phA, phB, phC, (en))
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 10, 11);
// position / angle sensor instance Encoder(encA, encB , cpr, (index))
Encoder sensor = Encoder(2, 3, 512);
void doA(){sensor.handleA();}
void doB(){sensor.handleA();}
float target_velocity_RPM = 300; // RPM
float target_velocity = target_velocity_RPM/9.549296; // rad/s
// commander instance
Commander command = Commander(Serial);
void doMotor(char* cmd) { command.motor(&motor, cmd); }
void setup() {
// start serial
Serial.begin(115200);
// initialize sensor
sensor.init();
// enable encoder interrupts
sensor.enableInterrupts(doA, doB);
// link sensor to motor
motor.linkSensor(&sensor);
// set power supply voltage
driver.voltage_power_supply = 10;
// set driver voltage limit, this phase voltage
driver.voltage_limit = 10;
// initialize driver
driver.init();
// link driver to motor
motor.linkDriver(&driver);
// set motion control type to velocity
motor.controller = MotionControlType::velocity;
// 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 = .3;
motor.PID_velocity.I = 10;
//motor.PID_velocity.D = 0;
// angle / position P controller
//motor.P_angle.P = ;
// set motor voltage limit, this limits Vq
motor.voltage_limit = 10;
// set motor velocity limit
motor.velocity_limit = 100;
//motor.LPF_velocity.Tf = 0.005;
// link the motor to the sensor
//motor.linkSensor(&sensor);
// initialize motor
motor.init();
// align sensor and start FOC
motor.initFOC();
// add the motor to the commander interface
// The letter (here 'M') you will provide to the SimpleFOCStudio
command.add('M',doMotor,"motor");
// tell the motor to use the monitoring
motor.useMonitoring(Serial);
motor.monitor_downsample = 0; // disable monitor at first - optional
_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();
// real-time monitoring calls
motor.monitor();
// real-time commander calls
command.run();
}
simpleFOCstudio will connect, however:
- it will not spin. I send commands such as “M10”, changing the target velicity to 10, but it does not move. If I spin the shaft by hand the plot changes. The current on the supply is always 0.
- on connecting, it appears to import the parameters from the code, but the integral value is always 0, even though in the code it is 10.
- it looks like unless I change the output ramp and output limit, the current Q does not change (on the screen, the actually current draw is always zero, no movement)
- If i add certain things to the code, like motor.LPF_velocity.Tf, it seems to crash studio.
please advise on what I am missing, on how to get this to spin in studio, and be able to then optimize it (which I think it one of the purposes of simpleFOCstudio…)