SimpleFOCStudio is INCREDIBLY unstable

Hello.

I had problems with studio back when I was starting with an UNO, and was told to update to ST and it should fix it.
NUCLEO-64 G431RB
42BLS02 motor with hall sensor

Studio will work right very, very rarely. The bad behavior varies, sometimes it just locks up, sometimes it becomes unresponsive, sometimes it ignores what I type in, sometimes it ignore button preseses, sometimes it doesn;t pull in the right values from the embedded system.

BTW, what does “Pull params” mean? It seems to pull the embedded parameters into itself even if you don’t click this?

#include <SimpleFOC.h>

//#define CURSENS
#define HALLSENS
//
//
// MOTOR: 42BLS02
// DRIVE: SimpleFOC
// SENSOR:
//
// COMMENT:
//
//

#ifdef HALLSENS
// PHASE A B C PP
HallSensor sensor = HallSensor(3, 2, 4, 4);
void doA(){sensor.handleA();}
void doB(){sensor.handleB();}
void doC(){sensor.handleC();}

#else
// encoder instance
MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
#endif

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

#ifdef CURSENS
// inline current sensor instance
InlineCurrentSense current_sense = InlineCurrentSense(0.01f, 50.0f, A0, A2, _NC);
#endif

// 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); }

// instantiate the smoothing sensor, providing the real sensor as a constructor argument
SmoothingSensor smooth = SmoothingSensor(sensor, motor);

void setup() {
sensor.init();
#ifdef HALLSENS
sensor.enableInterrupts(doA, doB, doC);
#endif

// link the motor to the sensor
//motor.linkSensor(&sensor);

smooth.phase_correction = -_PI_6;
motor.linkSensor(&smooth);

// 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

#ifdef CURSENS
current_sense.linkDriver(&driver);
// current sense init and linking
current_sense.init();
motor.linkCurrentSense(&current_sense);
motor.torque_controller = TorqueControlType::foc_current;
// Q
motor.PID_current_q.P = 50;
motor.PID_current_q.I = 100;
motor.PID_current_q.D = 0;
motor.PID_current_q.limit = 10;
motor.PID_current_q.output_ramp = 500;
motor.LPF_current_q.Tf = 0.1;
// D
motor.PID_current_d.P = 0;
motor.PID_current_d.I = 0;
motor.PID_current_d.D = 0;
motor.PID_current_d.limit = 10;
motor.PID_current_d.output_ramp = 500;
motor.LPF_current_d.Tf = 0.1;
#endif

//motor.controller = MotionControlType::torque;
motor.controller = MotionControlType::torque;
// 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();

}

It is aimed to refresh and pull again parameter configurations allowing a resynchronization between the GUI and what is currently running in your board.

Did you checked your serial communications without using SimpleFOC studio? SimpleFOC it is only and nothing else more than an application with a GUI allowing sending command and plotting data using the Serial Port. A unstable connection could seriously affect the overall “user experience”

BR

It’s just more stuff that needs to be done. Always lots more to do, this is why I am a big fan of navigating effectively at a high level to work efficiently. We can’t do everything. We gotta focus on what matters most.

@JorgeMaker explanation is probably correct i.e. the serial comms may be unstable.
Are you confident that usart rx/tx is super solid?
If you are using software serial or there is noise on rx/tx or too much interrupts or mcu clock settings are not quite right then rx/tx may be unstable.
I was recently playing with a board that required software serial and when I went faster than 76800 baud the rx/tx started to ‘stutter’ dropping random characters. This would have made SimpleFOCStudio unusable.

Hi @sgordon777 ,

As recommended by @Owen_Williams, one approach to troubleshooting the unstable behavior is to consider lowering the bit rate of your serial port configuration. Decreasing the bit rate can enhance the reliability of your serial port communications.

BR

I can try lowering bitrate, but I raised it to 921600 to solve a specific problem: When the bitrate was 115200, turning on the motor.monitor() in my loop() was affecting my FOC and causing my motor to run roughly(a once per revolution thump). Raising the bitrate to 921600 completely fixed this (I didn’t try any values in between 115200 and 921600).

Guess some thread is blocking on the transmission of the motor parameters causing FOC computations to wait?

SimpleFOC does not use any threads. Using the monitor always has a computational cost that can undoubtedly affect the performance of your engine.

If you are using an stunning 921600 bit rate, almost 1 Mbps, we may have discovered why you are experiencing problems using serial port communications in a noisy application prone to noise and interference, such as control engines. .

Most likely, you will need to come to compromise on the appropriate bitrate for your application to make ir works as a whole.

BR

I used 921600 and even 2 x faster recently, and could see no problems with it.

I was testing the new communications code in the drivers repository.

With a serial speed of 2 x 921600 I could get the monitoring data out with only 4 x downsampling while still getting excellent performance on loopFOC()…

I think whether serial communications works reliably depends a lot on the setup: many people are using USB serial. For USB serial it doesn’t matter what baud rate you set, it is ignored. USB speed will determine the maximum serial speed, and USB is both very reliable, and for USB 2.0 FS (which is what almost all the MCU support) its 10Mbits line speed, but with some overhead for the USB protocol.

Others are using a ST-Link with virtual com port, and if you have an original ST-Micro ST-Link V3, I think you can expect to run the UARTS to almost their maximum speed, and it will still work. The UART connection is only via a usually short cable to the ST-Link, and then it is USB to the computer. This is how I was testing, and 2 x 921600 was no problem.

Yet others are using serial UART and TTL2USB Serial adapters - here it will depend a lot on the quality of the hardware, length of the cables, etc…

So I don’t think a high serial speed per se is a problem, but rather the surrounding systems, and how its all connected together.

1 Like

I’m using a ST NUCLEO board (G431RB) and Arduino defaults for the platform:

upload=mass_storage
USB=none
U(S)ART=enabled, generic serial
usb speed=low/full-speed

This ST platform is brand new to me so I’ve not researched any of the settings yet(want to get motors working right). The Mass storage is incredibly annoying, and compile/upload time is worse than the UNO, even at 921KBPS

is U(S)ART a bit-banged UART?

No, it’s just meaning UART, or with synchronous option USART, they are both hardware.

The Nucleo should have on-board STLink… why not use this?

I guess I thought I was Which option would I choose?

You should use SWD, I think that will be the fastest.

TBH I think the culprit may be QT. SimpleFOCStudio’s code looks fine for connecting with it.
Probably the library not working for certain platforms.

I’m getting the same ‘brokeness’ and I think the amount of brokeness I’m observing and I think you are as well is too great to say that the developer would have not realized / tested.

I don’t see any other solution than trying a different UI frontend. For this I’ve wrote a draft UI :SimpleFOC WebUI (Based on SimpleFOC Studio and without WebSerial)

While it’s not perfect yet it shouldn’t randomly lockup / be weird etc.

Feel free to check it out.

1 Like