Hoverboard main board with simpleFOC

Absolutely. The idea is to write a simpler “third party” firmware on the GD32 and use SimpleFOC to send commands to this firmware. I guess that these commands would be the PWM for all phases. The bottleneck of this strategy is probably the amount of commands to send and feedback (hall sensors) to receive via I2C. STM32 I2C bus can support up to 100Kb/s, but I’ve no idea of the required data rate sent by SimpleFOC ? Would it depend on the actual motor speed ?

What you are proposing is not possible without re-writing SimpleFOC algorithm which creates a catch-22, if you have the knowledge and skills to re-write it then you won’t need to do that. Also i2c simply doesn’t have the bandwidth. You need something like full duplex 10MHz SPI to get data back from the current sensors, etc. It’s going to be a nightmare.

The way I see it, your best option with simpleFOC is to make it work on GD32 board (if that’s possible) and send velocity commands to all 4 wheels via I2c.

Thanks a lot for your feedback. I2C bandwidth is definitely not good enough and the only solution is to make simpleFOC work on GD32 board. This may be feasible since Arduino framework has been ported to GD32: GitHub - CommunityGD32Cores/ArduinoCore-GD32: Arduino core for GD32 devices, community developed, based on original GigaDevice's core . Is this processor good enough for simpleFOC is another story…

Exactly - since gd32 are supported by Arduino framework (and are functinally very similar to STM32s), SimpleFOC should work with them. You can probably remove everything you don’t need from simpleFOC framework to reduce the final elf file size and make it fit on MCUs with smaller flash size.
There’s a minimal branch for this Minimal Code Version | Arduino-FOC

You can give it a try - if you do, please let us know how it goes.

Personally I would use PlatformIO rather than ArduinoIDE because the error messages are clearer and better, which is useful when doing this kind of thing.
Apparently this framework version runs in PlatformIO.

Anyway, once you have the framework installed in the IDE, you can just install the SimpleFOC library normally, but I would not expect it to work…

This GD32 chip is a clone of the STM32F103, so it should be able to do similar things, but in order to be able to control motors, SimpleFOC has MCU-specific PWM initialisation code… we have 14 different MCU types, but GD32 isn’t one of them
And even though it is like an STM32F103, it doesn’t look like the Arduino framework for it has the same APIs as the STM32 framework does. Our STM32-specific code uses the STM32 HAL (hardware abstraction library) to do the PWM initialisation.

So I’m guessing the exercise to get this working will mean writing a PWM driver (and if you want current sensing then also an ADC driver) for it…

1 Like

Dear sir,
I study the FOC driver (at link you listed) and even tested it. I found that the UART communication between robot controller and driver only handle two motor with one command, and when made FOC ad ADC/PWM the two motors not accurate positioning (i.e. one motor start fast than other) and so robot rotate (i.e. motor not synchronous together even with same ADC values applied to each motor-side).
Are you have solution to make the FOC driver : run motors synchronous if same ADC/PWM applied to them, second how to control each side by different commands (by UART) that may make two side work with same speed and position.

I’m using Simple FOC for robotics. Yes you can synchronize many motors for use on diferential drive wheels, arms and legs. Just as if you had brushed DC gear motors, you need encoders on the motors and a PID loop to control velocity of the wheels or position of the joint.

A robot with wheels where each is powerd by a diffent motor will NEVER drive straight even with PID velocity control on each wheel. The friction under each wheel is differnent, or a some other tiny thing turns the robot. Maybe the winding of the moters are not the same and one has 1 pole with lower inductace. The physical world is not perfect.

The solution is to have the master computer meare the robot’s heading with a sensor like an IMU or even a simple gyro. The master computer runs a “heading PID” and commands the velocity set points in the left and right motor to keep the heading constant. (or to keep it not constant if the plan is to roll along an arc or a conic section.

A simple industrial solutio is to paint a line on the floor and the robot uses optical sensors to folow the line. IMU chips cost under $10.

Then you find the gyro drifts at some number of radians per seconds and you need a clever scheem to compensate. We typically use multiple heading and odomerty sensors, optical-flow and IMU and GPS and wheel sensors and put it all in a Kalman filter. Lucky for us ROS has funtions to do everything I described above, do not re-inven it.

In short, expect the wheels to slip and not grip the floor as theory would predict. Sense the error and corect it by adjusting the velocity set point of each wheel

Same for my walking robot, you need sensors and multiple levels of control loops. Thevelocity PID in Simple FOC is only the innermost loop

Dear Mr. ChrisA
Really many thanks for your a lot of information and sharing this experiences.
I spent much time just to run motors to create indoor robot.
by the way I use BLDC motors from (old hoverboard),
Proposed robot for :-

  • Indoor application (so, no GPS can use).
  • Very low speed traveling/positioning.
  • First version will be remotely controlled (i.e. I’ll control robot by mobile via video app, and so robot has camera to let me see what he see, and then I control it by arrows).

So, kindly, can you guide me to find PID controller that at least control the two motors drivers go like what I need (specially at straight-forward for two motors).
I modified the original driver of hoverboard to work as (PWM (speed), Direction) per each motor.

so, my requirement now is PID-Controller make balance movement in straight-forward for these two motors.
I have AXDL345 gyro, Arduino, Hall encoder from each wheel, and serial Bluetooth for commands (simple arrows).
Kindly, help me to find that,
thanks in advance.

Hi,

I am one of the contributors to that firmware.
I am spending a lot of time at the moment understanding/improving the current sensing for dual motors
Let me know if you have any questions.
Maybe we can collaborate.

1 Like
1 Like

Hi,

I started experimenting with the arduino-GD32 platform in this new project.
The sideboards have no motor control but it helps me validate that USART/I2C/GPIOs are handled properly.

I imagine that if we want to later extend this to splitboards using simpleFOC, we would need to write such driver with GD32 SPL ?

I discussed it with one of the active Splitboard project and there is some interest. We could borrow some of the SPL code from there.

Please any advice is welcome.

I’m not sure what SPL is, but yeah, it would need a GD32-specific PWM driver and ADC driver for current sensing…

I’d be interested to see any progress you make on this!

It’s the GD32 hal.
As we would be aiming for specific boards, is it OK if we develop only 6pwm and then only low side current sensing?

Well, there are two parts to this answer:

  1. of course it is ok, and I would be happy to help if I can

  2. BUT: we would probably leave the support for GD32 on a branch if it only supported 6-PWM and low-side sensing. This is because I think it would cause a lot of confusion and support effort if we merged it to the main branch in this state. The SimpleFOC hardware (SimpleFOC shield, SimpleFOC mini) is 3-PWM, and the shield uses inline sensing, so lots of users would ask about this.

But I also think that if you made it work for 6-PWM low side sensing, it is actually the hardest case, and we could probably manage to make the other cases work quite quickly based on that…

1 Like

Thanks for offering your help.
I totally understand not having complete support for GD32 would be misleading.
Actually we would be implementing only 6PWM and low side, but only for some GD32 chips (GD32F130C6T6, GD32F130C8T6), but we have to start somewhere.

I forked ArduinoFOC and will start to investigate 6PWM.

First step, replace all ‘stm32’ by ‘gd32’ :rofl:

1 Like

Its probably a good idea not to copy the STM32 code - a lot of that code is about optimising the pin assignments to the timers based on the framework PinMap structures.

Some of the other PWM drivers are much “cleaner” e.g. the RP2040 one.

For a new MCU I’d almost start with an “empty” file containing just the stubs that need to be implemented like _configure6PWM() and _setDutyCycle6PWM().

Thanks for the hint :pray:

Hey no problem - if you’re on discord I’m also happy to jump on a chat if you want to discuss anything. We’re very appreciative if anyone wants to undertake such a difficult task, so happy to support!

The basic operating principle of the PWM drivers is that the _configureXY methods return a void* to a hardware-specific struct. You can put in in whatever you like and need for the GD32, but typically it contains references to the timers and channels used, etc…

the _configureXY methods are supposed to make sure the pins used make sense, make sure the timers/pins aren’t being used more than once, etc… Then they initialise the timers, sometimes this also involves setting up the clocks that drive the timers.

Finally they create and fill the driver-specific struct and return a pointer to it.

If at any point they fail, they should clean up as best they can, and return the error constant. They can make use of SimpleFOCDebug::println() to inform the user what when wrong.

the _setDutyCycleXY methods are called to change the duty cycle or set the phases to hi Z mode. They should be implemented as efficiently as possible and should never print to serial port or things like this.

In terms of PWM, the object is provide the most control over the frequency as the hardware allows, ideally from 1Hz to 200kHz :slight_smile: if the hardware can’t do it, we take whatever the hardware can do. The SimpleDC library can use low PWM frequencies, the SimpleFOC library uses 2kHz - 100kHz realistically for BLDC driving, with 22 - 40kHz being the most used ranges.
For a given PWM frequency, the hardware should be configured to give the highest resolution it can, e.g. generally this means setting the clocks as fast as they can go.

PWM should be configured in “phase correct” or “centre-aligned” mode. Sometimes this is also called “up-down counting” mode. In this mode the timers count up to the top, and down again, switching on as they pass the compare value upwards and off as they pass it downwards. This leads to PWM signals that have the on-time “centred” in their periods, and this is important for low-side current sensing.

In terms of 6-PWM there is extra complexity: dead-time insertion.
Some MCUs can do it in hardware, some can do it, but only for very specific pins (e.g. STM32) and others can’t do it at all. If GD32 offers it, it would be good to support it.
Where not supported due to hardware or bad pin choices, the 6-PWM driver should support software dead-time insertion. This can only work if the PWM is centre aligned and all pins are driven by timers that are synchronised (same PWM frequency and started concurrently).

Furthermore the 6-PWM driver should support setting Hi-Z mode by checking the phase state and setting the FETs accordingly.

Really, if there are any questions, please let me know. You can also feel free to DM me.