Tutorial: Getting started with PlatformIO IDE and the Simple FOC Library

I’ve put together a 20min tutorial on how to use Simple FOC with PlatformIO IDE:

If you’ve never used PlatformIO IDE then I strongly recommend you check it out. It’s SO much better than Arduino IDE.

The video covers:

  • installation of platformio (and visual studio code)
  • creation on new project (selecting an ESP32 board)
  • adding multiple libraries (including github sourced libraries)
  • testing a gimbal motor and as5600 magnetic sensor
  • adding an additional board (pro mini mega368p gimbal controller)
  • switching between two boards using platformio environments
  • using build flags to have one code base for two boards
10 Likes

Thank you for your tutorial,
I’ve also been using platformio on atom. Compared with Arduino IDE, platformio ide has better interface effect and function Association

Thanks a lot @Owen_Williams for letting me know about PlaformIO. Compared to Arduino IDE, this looks much closer to what I am used to .

For those landing here, notice that the current version of PlaformIO doesn’t support the Nucleo-L476RG. Fortunately there is a workaround, see here.

1 Like

We have an online version of the tutorial as well:

If using PlatformIO with SimpleFOC, its important to add the option

lib_archive = false

to your platformio.ini

The error you post looks like a setup error of some kind, it has nothing to do with SimpleFOC. it means the Arduino (atmelavr) platform is not installed.

When using PlatformIO, you have to go the “Platforms” pane, and install the correct platform for your MCU. Ardunio, STM32 and ESP32 all have separate platforms.

Hi @runger,
I tried to install SimpleFOC on PlatformIO, but I get error during compilation.
Compiling .pio\build\esp32doit-devkit-v1\lib862\Simple FOC\drivers\hardware_specific\esp32_mcu.cpp.oCompiling .pio\build\esp32doit-devkit-v1\lib862\Simple FOC\drivers\hardware_specific\esp8266_mcu.cpp.o
.pio\libdeps\esp32doit-devkit-v1\Simple FOC\src\drivers\hardware_specific\esp32_ledc_mcu.cpp:21:26:
fatal error: soc/soc_caps.h: No such file or directory
compilation terminated.
*** [.pio\build\esp32doit-devkit-v1\lib862\Simple FOC\drivers\hardware_specific\esp32_ledc_mcu.cpp.o] Error 1
=================================== [FAILED]

Any idea what I can do?
soc/soc_caps.h ---- should I try to find this file?

This error is caused by having the incorrect ESP32 platform version.

If you upgrade the ESP32 platform to the latest version, the error should go away.

Sometimes it also seems to be necessary to do a make clean and/or erase any cached parts of the project to get PlatformIO to compile with the new code.

Still missing something. Is it path to g++?

PS C:\Users\Svein\Documents\PlatformIO\Projects\simple_tutorial\src> cd "c:\Users\Svein\Documents\PlatformIO\Projects\simple_tutorial\src" ; if (?) { g++ main.cpp -o main } ; if (?) { .\main }
g++ : The term ‘g++’ is not recognized as the name of a cmdlet, function, script file, or operable progr
am. Check the spelling of the name, or if a path was included, verify that the path is correct and try a
gain.
At line:1 char:84

  • … nts\PlatformIO\Projects\simple_tutorial\src" ; if ($?) { g++ main.cp …
  •                                                           ~~~
    
    • CategoryInfo : ObjectNotFound: (g++:String) [], CommandNotFoundException
    • FullyQualifiedErrorId : CommandNotFoundException

PS C:\Users\Svein\Documents\PlatformIO\Projects\simple_tutorial\src>

PlatforIO might be to difficult for me.
Maybe it is better to stick to Arduino IDE?

Executing task in folder simple_tutorial: C:\Users\Svein.platformio\penv\Scripts\platformio.exe debug

Warning! Ignore unknown configuration option https in section [env:esp32doit-devkit-v1]
Warning! Ignore unknown configuration option https in section [env:esp32doit-devkit-v1]
Processing esp32doit-devkit-v1 (platform: espressif32; board: esp32doit-devkit-v1; framework: arduino)
---------------------------------------------------------------------------------------------------Verbose mode can be enabled via -v, --verbose option
CONFIGURATION: Redirecting...
PLATFORM: Espressif 32 (3.5.0) > DOIT ESP32 DEVKIT V1
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (esp-prog) External (esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd,
olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:

  • framework-arduinoespressif32 @ 3.10006.210326 (1.0.6)
  • tool-esptoolpy @ 1.30100.210531 (3.1.0)
  • toolchain-xtensa32 @ 2.50200.97 (5.2.0)
    LDF: Library Dependency Finder → Library Dependency Finder (LDF) — PlatformIO latest documentation
    LDF Modes: Finder ~ chain, Compatibility ~ soft
    Found 29 compatible libraries
    Scanning dependencies…
    Dependency Graph
    |-- Simple FOC @ 2.2.3
    | |-- Wire @ 1.0.1
    | |-- SPI @ 1.0
    Building in debug mode
    Compiling .pio\build\esp32doit-devkit-v1\src\main.cpp.o
    Compiling .pio\build\esp32doit-devkit-v1\lib1f3\Simple FOC\drivers\hardware_specific\esp32_ledc_mcu.cpp.o
    src\main.cpp: In function ‘void setup()’:
    src\main.cpp:62:3: error: ‘current_sense1’ was not declared in this scope
    current_sense1.linkDriver(&driver1);
    ^
    src\main.cpp:70:3: error: ‘current_sense2’ was not declared in this scope
    current_sense2.linkDriver(&driver2);
    ^
    src\main.cpp:125:41: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
    command.add(‘A’, doTarget1, “target 1”);
    ^
    src\main.cpp:126:41: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
    command.add(‘B’, doTarget2, “target 2”);
    ^
    Compiling .pio\build\esp32doit-devkit-v1\lib1f3\Simple FOC\sensors\HallSensor.cpp.o
    Compiling .pio\build\esp32doit-devkit-v1\lib1f3\Simple FOC\sensors\MagneticSensorAnalog.cpp.o
    *** [.pio\build\esp32doit-devkit-v1\src\main.cpp.o] Error 1
    .pio\libdeps\esp32doit-devkit-v1\Simple FOC\src\drivers\hardware_specific\esp32_ledc_mcu.cpp:21:26: fatal error: soc/soc_caps.h: No such file or directory
    compilation terminated.
    *** [.pio\build\esp32doit-devkit-v1\lib1f3\Simple FOC\drivers\hardware_specific\esp32_ledc_mcu.cpp.o] Error 1
    =================================== [FAILED] Took 5.17 seconds ===================================
  • The terminal process “C:\Users\Svein.platformio\penv\Scripts\platformio.exe ‘debug’” terminated with exit code: 1.
  • Terminal will be reused by tasks, press any key to close it.

This means there is something wrong in your platformio.ini…

And these are a problem in the code, these variables are not declared…

(And you can’t have more than one current sense anyway, unfortunately we only support one at the moment)

For sure you can! The results should be the same in either environment, it’s just what you feel more comfortable working with…
Arduino IDE is easier to use, with fewer options. PlatformIO is much more powerful, but can be confusing if you’re new to programming or aren’t familiar with visual studio code

Good day to every one! I have installed PlatformIO IDE on VS Code. I use Arduino Nano ATmega328 (old bootloader). I connected LCD to it and installed 2 libraries: SimpleFOC and LiquidCrystal_I2C by Frank de Brabander. When I tryed to upload code, I’ve got an error. Can someone help me?

platformio.ini file code:

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:nanoatmega328]
platform = atmelavr
board = nanoatmega328
framework = arduino

upload_speed = 57600
upload_port = COM3

lib_deps = 
	askuric/Simple FOC@^2.3.2
	marcoschwartz/LiquidCrystal_I2C@^1.1.4
lib_archive = false

main.cpp code:

/*#include <Arduino.h>

// put function declarations here:
int myFunction(int, int);

void setup() {
  // put your setup code here, to run once:
  int result = myFunction(2, 3);
}

void loop() {
  // put your main code here, to run repeatedly:
}

// put function definitions here:
int myFunction(int x, int y) {
  return x + y;
}*/


#include <Arduino.h>
#include <LiquidCrystal_I2C.h> 

LiquidCrystal_I2C lcd(0x27, 20, 2); 

void setup() {
  lcd.init();
  lcd.backlight(); 
  lcd.setCursor(1, 0); 
  lcd.print("Hello, world!");
}

void loop() {
}

terminal:

Processing nanoatmega328 (platform: atmelavr; board: nanoatmega328; framework: arduino)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/nanoatmega328.html
PLATFORM: Atmel AVR (5.0.0) > Arduino Nano ATmega328
HARDWARE: ATMEGA328P 16MHz, 2KB RAM, 30KB Flash
DEBUG: Current (avr-stub) External (avr-stub, simavr)
PACKAGES:
 - framework-arduino-avr @ 5.2.0
 - tool-avrdude @ 1.60300.200527 (6.3.0)
 - toolchain-atmelavr @ 1.70300.191015 (7.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 7 compatible libraries
Scanning dependencies...
Dependency Graph
|-- Simple FOC @ 2.3.2
|-- LiquidCrystal_I2C @ 1.1.4
Building in release mode
Compiling .pio\build\nanoatmega328\lib595\Wire\Wire.cpp.o
Compiling .pio\build\nanoatmega328\lib595\Wire\utility\twi.c.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\BLDCMotor.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\StepperMotor.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\common\base_classes\CurrentSense.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\common\base_classes\FOCMotor.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\common\base_classes\Sensor.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\common\foc_utils.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\common\lowpass_filter.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\common\pid.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\common\time_utils.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\communication\Commander.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\communication\SimpleFOCDebug.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\communication\StepDirListener.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\GenericCurrentSense.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\InlineCurrentSense.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\LowsideCurrentSense.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\atmega_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\due_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\esp32\esp32_adc_driver.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\esp32\esp32_ledc_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\esp32\esp32_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\esp32\esp32s_adc_driver.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\generic_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\rp2040\rp2040_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\samd\samd21_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\samd\samd_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\b_g431\b_g431_hal.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\b_g431\b_g431_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\stm32_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\stm32f1\stm32f1_hal.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\stm32f1\stm32f1_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\stm32f4\stm32f4_hal.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\stm32f4\stm32f4_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\stm32f4\stm32f4_utils.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\stm32g4\stm32g4_hal.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\stm32g4\stm32g4_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\stm32g4\stm32g4_utils.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\stm32l4\stm32l4_hal.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\stm32l4\stm32l4_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\stm32\stm32l4\stm32l4_utils.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\current_sense\hardware_specific\teensy_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\BLDCDriver3PWM.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\BLDCDriver6PWM.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\StepperDriver2PWM.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\StepperDriver4PWM.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\atmega\atmega2560_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\atmega\atmega328_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\atmega\atmega32u4_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\due_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\esp32\esp32_ledc_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\esp32\esp32_mcu.cpp.o
.pio\libdeps\nanoatmega328\Simple FOC\src\drivers\hardware_specific\atmega\atmega328_mcu.cpp:6:83: note: #pragma message: SimpleFOC: compiling for Arduino/ATmega328 ATmega168 ATmega328PB
 #pragma message("SimpleFOC: compiling for Arduino/ATmega328 ATmega168 ATmega328PB")
                                                                                   ^
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\esp8266_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\generic_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\nrf52_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\portenta_h7_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\renesas\renesas.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\rp2040\rp2040_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\samd\samd21_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\samd\samd51_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\samd\samd_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\stm32\stm32_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\teensy\teensy3_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\teensy\teensy4_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\drivers\hardware_specific\teensy\teensy_mcu.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\sensors\Encoder.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\sensors\GenericSensor.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\sensors\HallSensor.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\sensors\MagneticSensorAnalog.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\sensors\MagneticSensorI2C.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\sensors\MagneticSensorPWM.cpp.o
Compiling .pio\build\nanoatmega328\libf85\Simple FOC\sensors\MagneticSensorSPI.cpp.o
Compiling .pio\build\nanoatmega328\lib864\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp.o
Compiling .pio\build\nanoatmega328\src\main.cpp.o
Archiving .pio\build\nanoatmega328\libFrameworkArduinoVariant.a
Compiling .pio\build\nanoatmega328\FrameworkArduino\CDC.cpp.o
In file included from .pio\libdeps\nanoatmega328\Simple FOC\src\sensors\MagneticSensorSPI.cpp:2:0:
.pio\libdeps\nanoatmega328\Simple FOC\src\sensors\MagneticSensorSPI.h:6:10: fatal error: SPI.h: No such file or directory

*************************************************************
* Looking for SPI.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:SPI.h"
* Web  > https://registry.platformio.org/search?q=header:SPI.h
*
*************************************************************

 #include <SPI.h>
          ^~~~~~~
compilation terminated.
Compiling .pio\build\nanoatmega328\FrameworkArduino\HardwareSerial.cpp.o
Compiling .pio\build\nanoatmega328\FrameworkArduino\HardwareSerial0.cpp.o
*** [.pio\build\nanoatmega328\libf85\Simple FOC\sensors\MagneticSensorSPI.cpp.o] Error 1
========================================================================================== [FAILED] Took 3.02 seconds ==========================================================================================
 *  The terminal process "C:\Users\Developer\.platformio\penv\Scripts\platformio.exe 'run', '--target', 'upload'" terminated with exit code: 1. 
 *  Terminal will be reused by tasks, press any key to close it. 

It’s not finding the SPI library… that’s strange.

Try including it with

#include <SPI.h>

or try adding it with the library manager.

But its strange because normally it is built-in.

1 Like

Good evening! Thank you very much, it solved my problem! I included it with

#include <SPI.h>
1 Like