Timing of FOC Loop

Why does the loop(loopFOC() + move()) lasts ~10KHz on a STM32 Blue Pill @72MHz, even with a STM32G431 @170MHz which is a lot of quicker ?(??)

Best Regards

Maybe they are both subjected to the same sensor delay? I.e i2c or spi clock speed is the limiting factor.

Have you tried calling move() only one in every 10 loops? This also helps smooth out the velocity readings.

Hi @Owen_Williams,
Many thanks for your prompt reply. In fact, I computed the timing without movement of the motor, so without interruption of sensor like this:

t0=_micros();
motor.loopFOC();
motor.move();
t2=_micros();
Serial.print("...");
Serial.println(t2-t0);

The result is t2-t0 = 94 with a time distribution of loopFOC() @75 + a move() @19 = 94us.

What do you think about ?

Try this.

t0=_micros();
motor.loopFOC();
static long count;
count++;
If (count % 10 == 0) {
  motor.move();
}
t2=_micros();
Serial.print("...");
Serial.println(t2-t0);

What I’m trying to say is that the move() function doesn’t have to be called as often as loopFOC(). I’m trying to establish why your g4 timings are not 2.5x black pill. I suspect it is to do with slow sensor readings.

What sensor are you using for this timing test?

Hi @Owen_Williams,
I tried your modification here above, and I get well 75us for t2-t0 as shown previously.

I use the hall sensors with target velocity @0 rpm, therefore without rotation of the motor to avoid the interrupts of the halls.

Thank you.

1 Like

Hi @Owen_Williams, @Antun_Skuric,
I wrote this code to measure with an oscilloscope, the timing of the loopFOC() :

GPIOA->BSRR = GPIO_BSRR_BS15;
motor.loopFOC();
GPIOA->BSRR = GPIO_BSRR_BR15;

and surprise, I get around 20us…So that means that there is an accuracy issue with micros() and so, the accuracy of velocity, and so on. What would explain a lot of things…

Maybe, to use a Timer for a best accuracy as for the Atmega328…

Best regards.

What mcu were you using?

Did you have some issues due to this?
I honestly did not experience any so far. Or i did not know I had it :smiley:
_micros() function is a wrapper for Arduino s micros() so we can change it relatively easily.

Hi @Antun_Skuric, I am confused about this question as well. I tested with blue pill and esp32, as5600 in i2c mode. To prevent the serial from delay, I set high and low to one pin at each loop. The oscilloscope shows blue pill and esp32 runs the loop at period of 400us when count%10==0. That is much slower than expected. Does as5600 communication slow down the period?

Yes, on an ESP32 the I2C communication will be the slowest part. See my timing diagrams here:

The ESP32 doing I2C at 400kHz (the max) is the 3rd picture from the top. Pin D2 is the I2C sensor reading. Pins D0 is the move() and D1 is the loopFOC() times.

So you can see I2C communication takes up almost all the time.
SPI is considerably faster, but of course SPI sensors cost a bit more than the AS5600…

400us sounds like you are running at i2c at 100k. I thing I typically get nearer 100us running 400k

Have you tried Wire.setClock(400000) before and/or after sensor.init()?

YES, it works! something wrong with my esp32, I tested with black pill(103C8T6). when the i2c speed is default, loopfoc last 640us and move last 600us. i2c speed@400K, loopfoc 320us and move 270us. i2c speed @1M, loopfoc 260us and move 200us. :grin:

1 Like