SimpleFOCStudio 2.0 a tunning and configuration tool

the bottleneck is more MCU-side.
I think it would be possible to prevent the monitoring from affecting the control loop.

The idea would be to setup a e.g. 10khz timer (like paul gould did) where the control loop happens and put readings in a FIFO buffer. Then buffer would then be emptied when the MCU idles, or interrupt based.
in the main loop() function, we could e.g. listen for commands

1 Like

Hey, my thoughts on this…

asyncio on the GUI side might be interesting for other reasons, although my impression is the GUI is very responsive despite the constant serial comms.

On the MCU side, I think there is a lot that could be done, but I think care should be taken to keep it separate from the “simple and generic” interface we have now. Any Arduino has a Serial object, but not all of them have timers that work in the same way, etc…

I know you like SAMD :wink: - I think on SAMD it should be possible to drive the SERCON using DMA, with almost no overhead to the main loop. But this will hardly be portable to other MCUs. So I think a good approach here could also be to write alternative “monitoring backends”, which can be kept separate from the main code (not wasting space and confusing the people not using them). The “pros” that want DMA-based monitoring for their MCU can then select from the available backends, or code their own.

I’m sure some people have been thinking about other channels than Serial (UDP on ESP32 for example, or MQTT, etc…). There could be backends for that too!

In terms of the existing SimpleFOC implementation, I would keep it simple, and keep it on Serial. This will be what 90% of users want when first testing it out, and what the less advanced users can realistically manage.

A possible optimization might be a binary mode for monitoring.
At the moment we send a bunch of 32 bit floats as ASCII. This incurs a penalty both in terms of ASCII conversion of the data, and sending some extra bytes.
I think converting to a binary format might improve the performance somewhat.
The ASCII format could be default, and we could keep it for the commander, but the binary format could be used by the monitoring when called from the SimpleFOC Studio…

1 Like

On the MCU side, I think there is a lot that could be done, but I think care should be taken to keep it separate from the “simple and generic” interface we have now. Any Arduino has a Serial object, but not all of them have timers that work in the same way, etc…

Agreed, also with your backend idea. the default could be a backend that synchroneously write via the configured Stream. I think it would still be doable to keep the FIFO idea without losing generality.

I know you like SAMD :wink: - I think on SAMD it should be possible to drive the SERCON using DMA, with almost no overhead to the main loop. But this will hardly be portable to other MCUs. So I think a good approach here could also be to write alternative “monitoring backends”, which can be kept separate from the main code (not wasting space and confusing the people not using them). The “pros” that want DMA-based monitoring for their MCU can then select from the available backends, or code their own.

Well it’s the dev board I have in stock, and my initial plan was to reproduce Paul Gould’s controller. Lots have happend since. I’m more and more interested with the SMT32G4. But yeah, I do want DMA-based/async monitoring. And I totally agree we should design a binary protocol. Another thing I’d like to see are timestamps which would become crucial it we go async

Couldn’t agree more. I discovered it recently, and I’m now trying to decide between three chips for my next board design:

  • RP2040
  • STM32G4
  • ESP32 Pico D4
    I’m happy to share once I’ve got something worth looking at :slight_smile:

@runger @JorgeMaker @Antun_Skuric

Just so you know, I’ve put quite a bit of effort on the data logging side. I chose to go separate way from the commander interface since I aim for real-time data logging performance, probably on a separate, outbound-only. data link. I won’t be needing SimpleFOCStudio’s connectors. I tried, but I then found a solution that’s both simpler and much, much higher performing. I should be ready for a little demo by monday or tuesday.

Beware, it’s Pyside6-only (pyqt5 is GPL, btw), uses QtQML, and it parses C-code sunch as “Arduino-FOC/src/common/foc_utils.h” to genrate parsers automatically. It’s going to be a bit nasty at first, but don’t worry, I hate nasty code.

for example, to send a struct from MCU, it becomes as simple as:

    Serial.println("PhaseCurrent_s");
    Serial.write((uint8_t*)(&pc), sizeof(pc));

from python side, my architectural aim is to have not a simple loc to add to support a new C struct.

I use pyclibrary to parse c structs definition, and then convert them to numpy structured arrays.

I have a POC, but I’m to proud to show it as it is :blush:

Hi @Jason_Kirsons ,

I had some time today and I have decided to implement your suggestion to add a Jogging control.

Captura de pantalla 2021-05-20 a las 19.27.38

The fast reverse button reduces the current target by 2 times the specified increment, the reverse button reduces the current target by the specified increment … etc. Stop button, in angle control mode, sets the current angle as target angle and in velocity control sets the target to zero.

Regards

4 Likes

That’s great! I love it! It makes it so much quicker to use.

1 Like

Hi @Jason_Kirsons,

Just got time to implement your second suggestion os something similar. Each custom command has a name and a value as yoy can see at the bellow.

Once you have defied each custom command in rder to execute each of them you have to select it and once selected press the space key (⎵) or right arrow key (→).

customCommands-1

Regards

Hi @JorgeMaker

Thanks, I’ve tested with a few custom commands:
image

And then the controller has some custom commands (changing parameters from @runger 's DRV8316 driver)

void doCustom(char* cmd) { 
  switch(cmd[0]) {
    case 'S':
      printf("Slew Rate: %i\n", atoi(&cmd[1]));
      driver.setSlew((DRV8316_Slew)atoi(&cmd[1])); 
      break;
  }
}


command.add('Z', doCustom, (char*)"Custom");

It looks like it’s working well!

Would it be possible to save the custom commands in the JSON file when we save the config?


Also, is it possible to save this in the JSON? Or always default to “M”?
image

Hi @Jason_Kirsons,

You are right, It’s a bit annoying having to add the custom commands every time yo execute the application. I will add the functionality of being able to save custom commands in the JSON file and also saving the “M” o whatever parameter of the engine. When I have it done I will let you know, it is a minimal change that adds quite value :slight_smile:

1 Like

Just added support to save custom commands and motorID. Hope did not brake anything. If you can, please let me know if everything works fine.

Regards !!

1 Like

Thanks Jorge! Now I can open SimpleFOC Studio, Load, and it remembers everything.

1 Like

First of all, thank you very much Jorge for this fantastic tool, very useful!

I have seen a bug, when changing the low pass filter of ‘d’, edit the ‘q’ wrongly.
This happens in device tree mode, in form view mode it works correctly

1 Like

Hi @Jorgefer88

Thank you for advising :slight_smile: I will try to reproduce the described behavior to solve it.

Regards

EDIT: I hope i have just solved the minor bug in my last commit to the repository without breaking anything else :slight_smile:

It seems that now it works great! :smiley:

Thanks!

1 Like

I have been using SimpleFOCStudio for a few weeks with the STM32F446RE without any problems

Now I have switched to ESP32 (the same configuration, but I have it seems that I have to tune the parameters again) but I find that it does not connect correctly with the application.

From the Arduino IDE and with the CoolTermWin it works without problems, but with the Studio it does not connect from the main screen (Three or Form View)

I have come to connect by doing the following:
Connect from “Cmd Line”, (from there it always connects me correctly) with the sequence:
MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: Index search …

And then go to the main screen.
If I try to connect directly from the main screen 90% of the time it doesn’t succeed.

Always with the same configuration and testing 115200.

In any case, even though I connect, after a few minutes the change of parameters starts to go very slowly until I see similar data (but wrong) to those of the “motor.monitor ();” and it crashes

Traceback (most recent call last):
  File "C: \ Users \ Jorge-PC \ Desktop \ SimpleFOCStudio \ src \ gui \ configtool \ graphicWidget.py", line 116, in upDateGraphic
    signals = np.array (signalList, dtype = float)
ValueError: could not convert string to float: '.'
Traceback (most recent call last):
  File "C: \ Users \ Jorge-PC \ Desktop \ SimpleFOCStudio \ src \ gui \ configtool \ graphicWidget.py", line 116, in upDateGraphic
    signals = np.array (signalList, dtype = float)
ValueError: could not convert string to float: '\ r2.35695452340005.00'
Traceback (most recent call last):
  File "C: \ Users \ Jorge-PC \ Desktop \ SimpleFOCStudio \ src \ gui \ configtool \ graphicWidget.py", line 116, in upDateGraphic
    signals = np.array (signalList, dtype = float)
ValueError: could not convert string to float: ''

Has anyone had these problems or been able to prove that it is not just my thing?

These types of errors are not easy to correct as they are difficult to reproduce.

My guess about what is happening is that for some reason that I am not aware of, the MCU is sending unparsable values in a float [ '\ r2.35695452340005.00' ] and the application starts throwing exceptions until it crashes.

One thing that could be done to see where the error comes from is to analyze if the strings sent by the MCU that later are parsed to floats.

I will try to investigate the problem, because apart from this problem, I have others in control.
Even adjusting the parameters a bit (as little as I could), from 20rad/s it destabilizes, when with the STM32F4 I get 120rad/s without problems. Exactly the same configuration (motor, driver, and encoder).

Just so you see, I just skipped this in the window:
Error

How many decimal digits are you using in your floats? You can play with decimal_places variable to see if it makes any difference

I did not have that configuration defined.

If I put command.decimal_places = 3; in setup () it ignores me, since when I run # I always get 0

When it is running I can change it, but the same 4 decimal places still appear in the terminal. It’s pretty weird

Data taken with CoolTermWin:

0.0000 -0.5371 0.0000 7.0780
0.0000 -0.5371 0.0000 7.0780
0.0000 -0.5371 0.0000 7.0780
0.0000 -0.5533 0.0000 7.0780

Changing the decimals to 2 in Arduino IDE, it ignores:

22: 00: 17.612 → 0.0000 -1.0867 -0.0039 6.5110
22: 00: 17.658 → 0.0000 -1.1367 -0.0042 6.5110
22: 00: 17.658 → 0.0000 -1.1631 -0.0042 6.5110
22: 00: 17.658 → Decimal: 2
22: 00: 17.705 → 0.0000 -1.1787 -0.0042 6.5110
22: 00: 17.705 → 0.0000 -1.1344 -0.0005 6.5110
22: 00: 17.751 → 0.0000 -1.1310 -0.0000 6.5110

How many decimal places can SimpleFOCStudio handle?