Periodic Jerk in velocity control mode

Hi,

New here and have tried to search for this issue without luck, perhaps I didn’t have the correct terminology?

I am running Simple FOC Mini, AS5600 and ESP32-C6 Super Mini.

Overall I can get things working, including angle control. However, when I run velocity control to tune the PID parameters there is a periodic jerk in the motion when the speeds are over approx. 50 r/s.

The period of this disruption is around 2 sec, regardless of the speed.

https://youtu.be/O66ddPv0T7E

Any pointers on where I should start to look for a solution?

Thanks,
Mig

Seems I found the problem:

https://www.reddit.com/r/arduino/comments/1iuwcdq/psa_arduino_with_single_core_esp32s_adds_5ms/

Issue with single core ESP32 and Arduino.

Will try running in a separate task.

Did the RTOS solution work for you? I’m experiencing the same 2-second thunk.

Hi,

Yes it solved the problem!

1 Like

Wonderful! I’ll give it a shot. Thanks for the feedback.

I think I’ve been sitting here troubleshooting this thing so long that my brain has gone fuzzy and my vision cross-eyed. Would you mind posting your code showing how you implemented the solution?

Hi, Sorry for delayed response.

Below is the Arduino code that I used just to test if this fixed the problem.
For my actual code I moved all the initialisation out of the task.

[code]

#include <SimpleFOC.h>

#define I2C_SDA 6 // Custom SDA pin

#define I2C_SCL 7 // Custom SCL pin

TaskHandle_t TaskHandle_Motor; //For Motor Control

// BLDC motor & driver instance

BLDCMotor motor = BLDCMotor(7);

BLDCDriver3PWM driver = BLDCDriver3PWM(0, 1, 2, 3);

// encoder instance

//Encoder encoder = Encoder(2, 3, 500);

// Interrupt routine intialisation

// channel A and B callbacks

//void doA(){encoder.handleA();}

//void doB(){encoder.handleB();}

MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);

// instantiate the commander

Commander command = Commander(Serial);

void doMotor(char* cmd) { command.motor(&motor, cmd); }

void setup()

{

// use monitoring with serial

Serial.begin(115200);

xTaskCreate(MyTaskMotor, “TaskMotor”, 2000, NULL, 1, &TaskHandle_Motor);

}

void loop()

{

vTaskDelete(NULL);

}

/*--------------------------------------------------*/

/*---------------------- Tasks ---------------------*/

/*--------------------------------------------------*/

static void MyTaskMotor(void* pvParameters)

{

unsigned long timer;

// enable more verbose output for debugging

// comment out if not needed

SimpleFOCDebug::enable(&Serial);

// if SimpleFOCMini is stacked in arduino headers

// on pins 12,11,10,9,8

// pin 12 is used as ground

//pinMode(12,OUTPUT);

//pinMode(12,LOW);

Wire.begin(I2C_SDA, I2C_SCL);

// initialise magnetic sensor hardware

sensor.init(&Wire);

// link the motor to the sensor

motor.linkSensor(&sensor);

// driver config

// power supply voltage [V]

driver.voltage_power_supply = 12;

driver.init();

// link the motor and the driver

motor.linkDriver(&driver);

// aligning voltage [V]

motor.voltage_sensor_align = 3;

// set motion control loop to be used

motor.controller = MotionControlType::angle;

// contoller configuration

// default parameters in defaults.h

// velocity PI controller parameters

motor.PID_velocity.P = 0.17f; //0.17

motor.PID_velocity.I = 0.55; //0.55

motor.PID_velocity.D = 0.0005; //0.0005

// default voltage_power_supply

motor.voltage_limit = 10;

// jerk control using voltage voltage ramp

// default value is 300 volts per sec ~ 0.3V per millisecond

motor.PID_velocity.output_ramp = 300;

// 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.005f; //0.02

// angle P controller

motor.P_angle.P = 6;

motor.P_angle.D= 0.2; //.2

motor.P_angle.I= 0.001;

// maximal velocity of the position control

motor.velocity_limit = 50;

// comment out if not needed

motor.useMonitoring(Serial);

// initialize motor

motor.init();

// align encoder and start FOC

motor.initFOC();

// add target command M

command.add(‘M’, doMotor, “motor”);

Serial.println(F(“Motor ready.”));

Serial.println(F(“Set the target angle using serial terminal:”));

_delay(1000);

timer = micros();

while(1)

{ //Control Loop



if ((micros()-timer) >= 0)

  { timer = micros();

    // main FOC algorithm function

  // the faster you run this function the better

  // Arduino UNO loop  \~1kHz

  // Bluepill loop \~10kHz

  motor.loopFOC();



  // Motion control function

  // velocity, position or voltage (defined in motor.controller)

  // this function can be run at much lower frequency than loopFOC() function

  // You can also use motor.move() and set the motor.target in the code

  motor.move();



  // function intended to be used with serial plotter to monitor motor variables

  // significantly slowing the execution down!!!!

  // motor.monitor();



  // user communication

  command.run();

  }



} 

}

[/code]

Good luck