Monitor causing jerky movement on Raspberry Pi 5

Hi there.

I have gotten started with simpleFOC and so far it seems like a fantastic project.

I am running a simpleFOCMini controlled from raspberry pi pico. I use the commander to control the motor by sending default commands and monitor interfaces to read data back.

When I control the motor from my m1 macbook pro it runs completely smooth either using a serial terminal or a python script to send commands. However when I run the same unit from a Raspberry Pi 5 AND monitor is used the movement jerks seemingly in time with the reporting from monitor. If I disable monitoring in the program running on the pico the movement is smooth also when run from the Pi5. The result is the same wether I use a serial terminal or python script on the PI.

I have attempted to downsample monitoring and it then became clear that it jerks for every reporting point.

The pico is connected to the Pi using USB, and the Pi is running Ubuntu 24.04

Its mysterious, can anyone advice?

Thank you!
Thor

Hey @Thorangutang,
Did you maybe try using a higher baudrate for the serial communication?

This might help, causing less time delay when sending/receiving data.

Hi Antun and thank you for your reply.

I have now tried all baud rates between 9600 - and 460800. I can see no discernible difference. Though I must report that the jerking in time with the monitor reports also happens on my m1, just much more subtly.

For this project I really only need the motor position, is there possibly a “lighter” way to read this?

In the future to be able to use the monitor telemetry solution is naturally preferable.

I include the code here just in case.

Thank you again!

Thor

#include <Arduino.h>
#include <SimpleFOC.h>

// Define board type here - uncomment the board you're using
//#define BOARD_TYPE_SHIELD
#define BOARD_TYPE_MINI

#ifdef BOARD_TYPE_SHIELD
  const int pwmPin1 = 0;
  const int pwmPin2 = 1;
  const int pwmPin3 = 2;
  const int enablePin = 3;
#elif defined(BOARD_TYPE_MINI)
  const int pwmPin1 = 10;
  const int pwmPin2 = 11;
  const int pwmPin3 = 12;
  const int enablePin = 13;
#else
  #error "Please define either BOARD_TYPE_SHIELD or BOARD_TYPE_MINI"
#endif

// magnetic sensor instance - SPI
MagneticSensorSPI sensor = MagneticSensorSPI(17, 14, 0x3FFF);

float filteredAngle = 0.0;
const float alpha = 0.001; // Low-pass filter coefficient

// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(11);
BLDCDriver3PWM driver = BLDCDriver3PWM(pwmPin1, pwmPin2, pwmPin3, enablePin);

// commander interface
Commander command = Commander(Serial);
//Commander command = Commander(Serial1);

void doMotor(char* cmd) { command.motor(&motor, cmd); }
//void onMotor(char* cmd){ command.motor(&motor, cmd); }
//void doTarget(char* cmd){command.scalar(&motor.target, cmd);}

void setup() {
  // monitoring port
  Serial.begin(115200);
  // enable the debugging output
  SimpleFOCDebug::enable(&Serial);
  // initialise magnetic sensor hardware
  sensor.init();
  // link the motor to the sensor
  motor.linkSensor(&sensor);
  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  driver.init();
  // link driver
  motor.linkDriver(&driver);
  // set control loop type to be used
  motor.controller = MotionControlType::angle;
  // contoller configuration based on the control type 
  motor.PID_velocity.P = 0.4;
  motor.PID_velocity.I = 5;
  motor.PID_velocity.D = 0;
  // default voltage_power_supply
  motor.voltage_limit = 3;
  // velocity low pass filtering time constant
  motor.LPF_velocity.Tf = 0.01;
  // angle loop controller only deceleration on lower values.
  motor.P_angle.P = 20;
  // angle loop velocity limit
  motor.velocity_limit = 50;

  // initialise motor
  motor.init();
  // align encoder and start FOC
  motor.initFOC();
  // set the inital target value
  motor.target = 0;

  // define the motor id
  //command.add('A', onMotor, "motor");
//command.add('T',doTarget,"target");
  char motor_id = 'M';
  command.add(motor_id,doMotor,"motor");
  // use monitoring with serial for motor init
  // comment out if not needed
  motor.useMonitoring(Serial);
  motor.monitor_downsample = 250; // default 10

    motor.monitor_start_char = motor_id; // the same latter as the motor id in the commander 
  motor.monitor_end_char = motor_id; // the same latter as the motor id in the commander 
  command.verbose = VerboseMode::machine_readable; 
  // Run user commands to configure and the motor (find the full command list in docs.simplefoc.com)
  Serial.println(F("Motor commands sketch | Initial motion control > torque/voltage : target 2V."));
  
  _delay(1000);
}

void loop() {
  // Regularly update the sensor reading
  sensor.update();
  // iterative setting of the FOC phase voltage
  motor.loopFOC();
  // iterative function setting the outter loop target
  // velocity, position or voltage
  // if target not set in parameter uses motor.target variable
  motor.move();
  // user communication
  command.run();
  /*
 static unsigned long lastMonitorTime = 0;
  if (millis() - lastMonitorTime > 10) { // Adjust the interval as needed
    motor.monitor();
    lastMonitorTime = millis();
  }
  */
  motor.monitor();
}


  // Print the filtered angle

Hi, is this with the mbed core from Arduino or the earlephilhower core? If using the mbed core, I’d try the other one…

If it doesn’t improve then it’s probably an issue of unbuffered serial writes. You’ll have to change the monitoring implementation to not cause blocking IO. One way to do this would be to use the Telemetry code from our drivers repo. In this code base I’ve already solved that issue.

I will investigate.

The code is compiled using PlatformIO in Vscode I assume this is using the mbed core. I think that my Arduino IDE has the Arduino mbed core. I will investigate switching and see if that changes things.

Then I will investigate the telemetry code, that sounds good.

Thank you!

Best Thor.

Hi all.

Switching core to the earlephilhower (earlephilhower (Earle F. Philhower, III) · GitHub) one does indeed seem to do the trick. It is running smoothly now.

Thank you.

Best
Thor