Adapt existing robot code to use SimpleFOC commander & BLDC

So I want to build a variant of this Arduino robot documented on this Github project

The robot is capable of Maze navigation and exploration and uses very basic PWM DC motors:

But instead, I'd use these $20 2205 BLDC motors to give much more precise and powerful control:

The driver board is this $20 dual-channel driver which is open hardware Starting with this code on the ESP32 target/ motor driver board to spin some wheels

The 'brain' is this Open Hardware ESP32DevC as 'brain'. Trying to get this ESP32 ' brain'/ controller code running

SimpleFOC Commander will work over the I2C communication bus. I2C Field Orientated Control (FOC) code:

I'm hoping this might appeal to others too, and that someone else might make a similar bot and help me with the code.

The end goal is to edit lines 163-168 & Lines 200 - 298 to get an affordable and accurate robot running.

Does anyone want to help me make a cool Arduino bot?

You are asking for a very big task. Sure it might be that somebody find it intriguing and jumps on your train. But this is rather unlikely.

If you break it down into specific questions you will get answers from much more people.
BLDC-motors are driven be ESCs which need a standard servo-signal as input.

This means the existing code has to be modyfied from - yeah - what motors is the original project using? This is information that you should provide
to using a servo-signal to drive the ESCs. These ESCs have to be able to drive both directions.

best regards Stefan

1 Like

Thanks Stefan

BLDCS can also be driven by the Simple FOC Arduino library I linked to above, and the cheap motor drivers I linked to.

SimpleFOClibrary gives you the choice of using 3 different torque control strategies:

Specifically can someone

  1. Help me replace these lines With code suitable for SimpleFOC I2C code

never heard of "FOC" before.

help me by explaining what "FOC" means and help me by posting a link that has democodes about how to use FOC

best regards Stefan

1 Like

FOC is Field Orientated Control. I posted the demo code above.

OK this explains what words are behind the TLA (three letter acronym) but not yet what it means in detail.

"demo-code above" is a pretty unprecise description
Programming is a much more complex thing than

"can somebody post the cheatcode for platinum-level?"

best regards Stefan

Demonstration Arduino code for Field Orientated Control of BLDC motors

aha. In the description with the link they use the word "pendulum" I assume the meaning is a two-wheel balancing-vehicle.

So are you planning to build such a two-wheel vehicle?

I'm planning to build the robot that corresponds to this code/project I've just added a photo to my first post. A bit more information can be found on the project page here I've updated my posts and comments to make them as clear as possible.

OK well done adding the details.
anyway even the most professional software-developper will do this project in multiple steps

connecting only one single component with the microcontroller
and then
using an existing demo-code where the code is well known to work reliably to test if the wiring between microcontroller and component works.

Repeat this for each component.

Then start to modify the existing demo-code to your needs.
The strategy behind this is keep the system simple to reduce possible sources of bugs.
The more things you add at the same time the more sources for bugs are inside the system and the longer it wil take to find them.

A lot of users go through this experience: throw it all together and then start testing
tinkering around trying this, trying that without really knowing if this will solve the problems.
This method will take hours, days, weeks without really proceeding.

If you have the patience for systematic testing and adding only one thing at the time and then immidiately test - in the end - you will finish your project faster.

You have written that you plan to build this project. So what is the actual state?
Do you have all the components laying on your desk and can start wiring them together?

best regards Stefan

1 Like

Thanks, that's helpful advice. As the proposed code was only released four days ago, I think there may not yet be well known reliable code, but the author of that software is interested in supporting this effort.

I've ordered motors and Deng board, but they haven't arrived yet. I have a ESP32devC board on my desk. I'll start doing code to get those spinning.

Hi Sam,

If you would like to practise some coding and learning how to debug with the serial monitor you can play with this code-example

This demo-code incorprates two different things:

it shows how timed actions can be coded in a non-blocking way
The command delay() is blocking which is "the bad way" to code timed actions

The code demonstrate the use of two macros that save typing two lines of code that can be added to the code for debugging purposes. instead of typing three lines of code you type a single line of code.

The demo-code shows how fast the main-loop can execute which is nescessary to do
for all things that must be checked thousands of times each second.

And how to realise actions that are executed only after a longer period of time.
This code requires nothing but any kind of pure ESP32-board (or any other microcontroller-board) with an USB-to-serial-interface
Here is the demo-code

// start of macros dbg and dbgi
#define dbg(myFixedText, variableName) \
  Serial.print( F(#myFixedText " "  #variableName"=") ); \
  Serial.println(variableName);
// usage: dbg("1:my fixed text",myVariable);
// myVariable can be any variable or expression that is defined in scope

#define dbgi(myFixedText, variableName,timeInterval) \
  do { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName); \
    } \
  } while (false);
// usage: dbgi("2:my fixed text",myVariable,1000);
// myVariable can be any variable or expression that is defined in scope
// third parameter is the time in milliseconds that must pass by until the next time a 
// Serial.print is executed
// end of macros dbg and dbgi


unsigned long MyTestTimer = 0;                   // variables MUST be of type unsigned long

//helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &periodStartTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();  
  if ( currentMillis - periodStartTime >= TimePeriod )
  {
    periodStartTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  } 
  else return false;            // not expired
}


unsigned long myFastCounter;
unsigned long mySlowCounter;

void setup() {
  Serial.begin(115200);
  Serial.print( F("\n Setup-Start  \n") );
  myFastCounter = 0;
  mySlowCounter = 0;
}


void loop() {
  myFastCounter++;
  // loop is running fast but only once per second (1000 milliseconds)
  // the value myFastCounter is printed to the serial monitor
  dbgi("dbgi-demo",myFastCounter,1000);

  // non-blocking timing-function
  // evaluates true only if milliseconds given as the second parameter
  // have passed by
  if (TimePeriodIsOver (MyTestTimer,2000) ) {
    mySlowCounter++;    
    dbg("dbg-Demo",mySlowCounter);
  }

  // if you un-comment the line below. The serial monitor will be flooded
  // with messages
  //dbg("dbg-flooding-demo",mySlowCounter);  
  // this demonstrates why dbgi is the better choice in fast running loops
}

and here is a link that explains how the macros work and what they are

The name "ESP32devC" does not narrow down to one particular board.
There are ESP32devC v1, ESP32devC v2m ESP32devC v3, ESP32devC v4

ESP32-DevKitC-32E, ESP32-DevKitC-32UE, ESP32-DevKitCVE, ESP32-DevKitCVIE, ESP32-DevKitCS1

Does your ESP32-board have a blue LED? If yes

Of course you are free to follow this suggestion or not:
As an exercise to learn coding you could modify the code above to add a function that does blink
this blue LED (which is connected to IO-pin 2 in most cases)

To make this blue LED blink beeing ON 500 milliseconds / beeing OFF 500 milliseconds in parallel to the other stuff that the demo-code already does.

Whenever a question arises regardless what the question is. Just post the question in the forum
together with your actual full sketch

best regards Stefan

1 Like