Step dir interface issue

hello everyone

I am a novice and do not understand code or hardware. The code was shared with me by someone else. Here, I would like to ask a question. I want to use BLDC for my 3D printer, with the interface being step dir. I can control it to rotate forward or backward, but its operating speed is too slow. When I adjust the PID smoothly, its speed is only 3-5 cycles per second. May I make it spin faster?

thank you!

#include <SimpleFOC.h>

// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(14);
BLDCDriver3PWM driver = BLDCDriver3PWM(32,33,25,22);

// encoder instance
MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
TwoWire I2Cone = TwoWire(0);

// StepDirListener( step_pin, dir_pin, counter_to_value)
StepDirListener step_dir = StepDirListener(13, 15, 360.0/200.0); // receive the angle in degrees
void onStep() { step_dir.handle(); }

// inline current sensor instance
// check if your board has R010 (0.01 ohm resistor) or R006 (0.006 mOhm resistor)
InlineCurrentSense current_sense = InlineCurrentSense(0.01, 50.0, 39, 36);

float target_velocity = 0;
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); }

void setup() {
step_dir.init();
// enable interrupts
step_dir.enableInterrupt(onStep);
//step_dir.attach(&motor.target);
I2Cone.begin(19,18, 400000UL);
sensor.init(&I2Cone);
motor.linkSensor(&sensor);
// driver config
// power supply voltage [V]
driver.voltage_power_supply = 12;
driver.init();
// link driver
motor.linkDriver(&driver);

// TorqueControlType::foc_current
// TorqueControlType::voltage TorqueControlType::dc_current
motor.torque_controller = TorqueControlType::foc_current;
// set control loop type to be used
motor.controller = MotionControlType::angle;

// contoller configuration based on the controll type
motor.PID_velocity.P = 0.045;
motor.PID_velocity.I = 0;
motor.PID_velocity.D = 0;
// default voltage_power_supply
motor.voltage_limit = 12;
motor.current_limit = 2;
// velocity low pass filtering time constant
motor.LPF_velocity.Tf = 0.01;

// angle loop controller
motor.P_angle.P = 20;
// angle loop velocity limit
motor.velocity_limit = 20;

// use monitoring with serial for motor init
// monitoring port
Serial.begin(115200);

// current sense init and linking
current_sense.init();
current_sense.gain_b *= -1;
motor.linkCurrentSense(&current_sense);

// initialise motor
motor.init();
// align encoder and start FOC
motor.initFOC();
command.add(‘T’, doTarget, “target velocity”);

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

_delay(1000);
}

void loop() {
Serial.println(step_dir.getValue());
// iterative setting FOC phase voltage
motor.loopFOC();

// iterative function setting the outter loop target
//motor.move(target_velocity);
motor.move(step_dir.getValue()*3.14/180);
//command.run();
}

Are you sure the motor has 28 magnets? The polepair number is #magnets/2

Always use motor.voltage_limit = 0.5* driver.voltage_power_supply

Not sure if that solves your problem, but it’s the right starting point

Dear @tony , welcome to SimpleFOC!

In addition to @o_lampe ‘s comments I would say you can’t print on each loop iteration… this will flood the serial port and cause blocking, slowing down your loop. But this loop has to execute as fast as possible so you can only print every 1000 iterations or so.

I have corrected my mistake, thank you very much for the answer from oulampe

1 Like

Hi Runger, is this the code?
// downsampling
motor.monitor_downsample = 100; // default 10
After adding this code, there was no improvement

No. I guess what @runger meant was adding a loopcounter variable:

[pseudo code]
void loop()
   if loopcounter >1000
      serial.println.......
     loopcounter = 0
  endif
...
...
...
loopcounter +=1

Hi o_lampe, thank you for your help. My motor is now running at high speed. Now it is 360/200=1.8 °/S. How can I set MICROSTEPS if I want to achieve higher accuracy?

You can change this declaration to
StepDirListener step_dir = StepDirListener(13, 15, 360.0/(200.0 * 16.0));
if you want 16 times microstepping. You also have to set the same value in the 3D printer config-file.
I wouldn’t recommend going too high with microstepping; the AS5600 doesn’t have such a high resolution. Maybe try 4 or 8 times microstepping first and see, if it makes a difference.

Thank you for this great open source project. I am still working hard to learn and I want to configure dual motors. I have almost copied a copy of the code. M0 motor can move, M1 motor only self checked and did not rotate. Did I do something wrong?

#include <SimpleFOC.h>

// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(32,33,25,22);
BLDCMotor motor1 = BLDCMotor(7);
BLDCDriver3PWM driver1 = BLDCDriver3PWM(26,27,14,12);

// encoder instance
MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
MagneticSensorI2C sensor1 = MagneticSensorI2C(AS5600_I2C);
TwoWire I2Cone = TwoWire(0);
TwoWire I2Ctwo = TwoWire(1);

// StepDirListener( step_pin, dir_pin, counter_to_value)
StepDirListener step_dir = StepDirListener(13, 15, 360.0/(200.0 * 8.0)); // receive the angle in degrees
StepDirListener step_dir1 = StepDirListener(16, 17, 360.0/(200.0 * 8.0));
void onStep() { step_dir.handle(); }

// inline current sensor instance
// check if your board has R010 (0.01 ohm resistor) or R006 (0.006 mOhm resistor)
InlineCurrentSense current_sense = InlineCurrentSense(0.01, 50.0, 39, 36);
InlineCurrentSense current_sense1 = InlineCurrentSense(0.01, 50.0, 35, 34);
float target_velocity = 0;
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); }

void setup() {
step_dir.init();
step_dir1.init();

// enable interrupts
step_dir.enableInterrupt(onStep);
step_dir1.enableInterrupt(onStep);

//step_dir.attach(&motor.target);
I2Cone.begin(19,18, 400000UL);
I2Ctwo.begin(23,5, 400000UL);
sensor.init(&I2Cone);
sensor1.init(&I2Ctwo);
motor.linkSensor(&sensor);
motor1.linkSensor(&sensor);

// driver config
// power supply voltage [V]
driver.voltage_power_supply = 12;
driver.init();
driver1.voltage_power_supply = 12;
driver1.init();

// link driver
motor.linkDriver(&driver);
motor1.linkDriver(&driver1);

// TorqueControlType::foc_current
// TorqueControlType::voltage TorqueControlType::dc_current
motor.torque_controller = TorqueControlType::foc_current;
motor1.torque_controller = TorqueControlType::foc_current;
// set control loop type to be used
motor.controller = MotionControlType::angle;
motor1.controller = MotionControlType::angle;

// contoller configuration based on the controll type
motor.PID_velocity.P = 0.05;
motor1.PID_velocity.P = 0.05;
motor.PID_velocity.I = 0;
motor1.PID_velocity.I = 0;

// default voltage_power_supply
motor.voltage_limit = 0.5* driver.voltage_power_supply;
motor1.voltage_limit = 0.5* driver.voltage_power_supply;
motor.current_limit = 5;
motor1.current_limit = 5;

// velocity low pass filtering time constant
motor.LPF_velocity.Tf = 0.01;
motor1.LPF_velocity.Tf = 0.01;

// angle loop controller
motor.P_angle.P = 20;
motor1.P_angle.P = 20;

// angle loop velocity limit
motor.velocity_limit = 200;
motor1.velocity_limit = 200;

// use monitoring with serial for motor init
// monitoring port
Serial.begin(115200);
motor.useMonitoring(Serial);
motor1.useMonitoring(Serial);

// current sense init and linking
current_sense.init();
current_sense.gain_b *= -1;
current_sense1.init();
current_sense1.gain_b *= -1;
motor.linkCurrentSense(&current_sense);
motor1.linkCurrentSense(&current_sense);

// initialise motor
motor.init();
motor1.init();

// align encoder and start FOC
motor.initFOC();
motor1.initFOC();
command.add(‘T’, doTarget, “target velocity”);

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

_delay(1000);
}

void loop() {

// iterative setting FOC phase voltage
motor.loopFOC();
motor1.loopFOC();

// iterative function setting the outter loop target
//motor.move(target_velocity);
motor.move(step_dir.getValue()*3.14/180);
motor1.move(step_dir.getValue()*3.14/180);
//command.run();
}