Arduino Mini R4 poor performance

So the G474re could be the one! Might order in a bit then.

The old uno is profoundly underpowered, but might be enough for your case, indeed it sounds like probably. I like the raspberry pi picos, and yes they definitely have a crystal. Some people have gotten simplefoc working in a basic way on it.

OK, so after a brain melting afternoon learning about 1% of the STM Cube apps, I think I actually got the mcu to see the crystal on the programmer. The main speed is superb but have higher flutter…so a bit of cypherin’ left haha!


Well the 401re is working now but the Uno still edged it out. For a vinyl turntable all that is needed is stability.

So again there can be difference because of the different driver implementation.
At slow speed deadtime can impact the speed.
Can the deadtime be different with F4 and Uno drivers ?

[EDIT] Even the defaut PWM frequency could be different, are you specifying it in your sketch ?

Changing the 401 clock to the crystal HSE was massive. The lack of a crystal in the factory setup is a known issue for for speed consistency in my case. My sketch is as basic as can be using back emf. I am not a programmer so drivers are not my concern, looking for plug and play. Wasted far too much time cyphering out STM Cube MX software, but I was curious if the crystal was the main issue, and it is. I am sure you are correct about the other factors but I simply am not capable enough to get into that…wish I was haha!

// Open loop motor control example
#include <SimpleFOC.h>

// BLDC motor & driver instance
// BLDCMotor motor = BLDCMotor(pole pair number);
BLDCMotor motor = BLDCMotor(11, 21, 90);
// BLDCDriver3PWM driver = BLDCDriver3PWM(pwmA, pwmB, pwmC, Enable(optional));
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);

// Stepper motor & driver instance
//StepperMotor motor = StepperMotor(50);
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6, 8);

//target variable
float target_velocity = 3.46;

// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); }
void doLimit(char* cmd) { command.scalar(&motor.voltage_limit, cmd); }

void setup() {

// driver config
// power supply voltage [V]
driver.voltage_power_supply = 12;
// limit the maximal dc voltage the driver can set
// as a protection measure for the low-resistance motors
// this value is fixed on startup
driver.voltage_limit = 12;
driver.init();
// link the motor and the driver
motor.linkDriver(&driver);

// limiting motor current (provided resistance)
motor.current_limit = 0.2; // [Amps]

// open loop control config
motor.controller = MotionControlType::velocity_openloop;

// init motor hardware
motor.init();
motor.initFOC();

// add target command T
command.add(‘T’, doTarget, “target velocity”);
command.add(‘L’, doLimit, “voltage limit”);

Serial.begin(115200);
Serial.println(“Motor ready!”);
Serial.println(“Set target velocity [rad/s]”);
_delay(1000);
}

motor.loopFOC();
// open loop velocity movement
// using motor.current_limit and motor.velocity_limit
motor.move();

// user communication
command.run();
}

This indeed is the way to. Fun, haha, trying to get a handle on the STM Cube MX software.

1 Like

Someone more experimented can confirm.
Arduino Uno would run by default at 32Khz and STM32 at 25KhZ.

Because you are using 3PWM, the deadtime should be a fixed time handled by the driver on your shield so it will be the same with both setup.

I understand what you are saying and it makes perfect sense. Sadly, the poor clock stability makes the non crystal cards useless. I might try the one @runger recommended as it uses a ceramic crystal and should be stable.

So I ordered me up one of them thar G474RE units haha! Got a turntable due to be finished in couple weeks for a friend, so I want to find the best unit for her turntable. The older Arduino Unos are perfect but I would be speccing a discontinued unit.

Thank you for all your help! Much appreciated. :smiley:

If you want a new microcontroller to get into I recommend the raspberry pi pico, and yes it has a crystal.

If I was building something de novo, I would just use a raspberry pi pico and a tmc2209 and stepper motor, I have gotten quite smooth silent motor at the rpms you are talking about and they are easy to interface to, source etc. lots of torque too. All you need to do it is feed it a pulse train and it will give you smooth quiet motion at low rpm and high torque right out of the box. The features that do most of the smoothing are already enabled.

However I wouldn’t use the pico for simplefoc stuff. The STM32 G431 whatever is the winner there.

The pico would be nice indeed. At the moment I am using the SimpleFOC shield so the 431 would not be a direct fit with the shield. I am trying @runger suggestion of the G474re with onboard crystal and Uno form factor. Should have it in a day or two. The 401re is running much better after the clock rerouting in STM32CubeMX. Thanks for the ideas.

1 Like

I have a similar turntable project to Jazzboy, and use a Nucleo. (I originally also tried the Uno R4, but found it not as good).

I tried a few things on my Nucleo64, using the same monitoring app as Jazzboy used. I have the FE446. no HSE. Running in open loop, I get fairly good precision in speed stability, +/- 0.15%.

  1. I inserted the delayMicrosceconds(100) into the loop(). It caused some slight speed instability, with a random spike of around 0.8% every few seconds.

  2. I tried PWM at 4k, 25k, 32k, 48k. 4k was a bit worse, but not bad. 25k, 32k, 48k were all very similar.

  3. I normally use “motor.move(28.0731f)” in the loop, hard coded. I tried setting “motor.target = 28.0731” in init, and called “motor.move()” in the loop. Woah. BIG CHANGE. 1% spikes every second or so. very different behavior. Switched back to hardcoding, and reuploaded. back to max 0.15% speed variation.

Looking at the code, I would have no explanation why that would be.
The value passed to the move() function is merely set to the motor.target, if provided. Nothing else is done with it.
That this would make such a difference for you is hard to understand. Are you sure there weren’t other, additional changes you reversed along with the way you set the target value?

yep. tried it again. only moved “motor.target =” to init() and “motor.move()” to loop, vs the hardcoding of the target speed “motor.move(28.0731f)” in loop. definitely see more speed variation in the motor.target instance, rather than the hardcoding. it is significant.

How long did the speed variation last? With an 11 pole pair motor, any variation in the properties of the bearing, which can be caused by squeazing the bearing for instance, or just dust etc. or friction from any source, will lead to a small variation as the increase in torque affects motor timing, basically. Even small amounts of force will lead to significant tendency to slow down for a small fraction of a rotation, and then spurt faster later. Like having an elastic band in your drivetrain. This is one reason I would prefer a stepper motor, with 200 poles, in such a situation, although good to see it’s mostly working out.

You can catch phenomena like that by graphing things or using the serial monitor, it timestamps things. You could add a section that compares the number of steps with the microsecond counter.

But in any case the loop frequency has no effect on the frequency of the sine wave output, and thus motor speed, in open loop velocity mode. The function that decides what to output on the pwm pins checks the number of microseconds elapsed since the last time it was called, using the microseconds timer provided by arduino. There would have to be something wrong with that timer or something in there to cause a significant change in frequency for a significant period. Anything else would cause a brief glitch/noise in the waveform but that’s about it.

i strongly suspect a mechancal cause, not the waveform. You could just watch the waveform with an oscope that tells you the frequency and see if it changes briefly. I have done this using sense resistors and it was rock solid for me with a b431b-esc1 board, which I think does not have a crystal oscillator.

So…the Nucleo G474re was just less good the the reprogrammed F401re. Soldered back the jumper to 5v logic, programmed up the Elegoo R3 and once again Arduino joy. Now have 3 Nucleo door stops, but might try to get them working to spec in the future. The screenshot is of the Elegoo, today.

Was that also using the default clock config for the G474?

Yes, just blasted the sketch into the beastie. Don’t really get why the humble Uno smokes these über cards. I first checked what the stock routing in the G474re was, witj the STM32mx Cube software, and it uses the crystal so not sure why they are underperforming.

Would you mind posting the clock config?
I would also expect to get seriously better performance.
Is it clocked all the way to 168MHz with the HSE by default?
Arduino R3 should barely clock at like 16MHz IIRC so the performance should be hugely different.