Platformio + raspberrypi pico: SPI.h not found

I have just installed platformio core on windows. Blink example compiles and loads fine. When I add dependency to Simple FOC, there are compile errors:

.pio\libdeps\pico\Simple FOC\src\sensors\MagneticSensorI2C.h:5:10: fatal error: Wire.h: No such file or directory
...
.pio\libdeps\pico\Simple FOC\src\sensors\MagneticSensorSPI.h:6:10: fatal error: SPI.h: No such file or directory

My platformio.ini:

[env:pico]
platform = raspberrypi
framework = arduino
board = pico
upload_protocol = picotool

lib_deps = 
	askuric/Simple FOC@^2.3.0

lib_archive = false

The only source file is main.cpp which is a blink example. Doesn’t even include SimpleFOC.
When I add #include <SPI.h> to my main.cpp it compiles just fine. Somehow it only happens while compiling a dependent library.

Any ideas what could be wrong?

Here’s a longer log:

Processing pico (platform: raspberrypi; framework: arduino; board: pico)
--------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/raspberrypi/pico.html
PLATFORM: Raspberry Pi RP2040 (1.9.0) > Raspberry Pi Pico
HARDWARE: RP2040 133MHz, 264KB RAM, 2MB Flash
DEBUG: Current (cmsis-dap) External (cmsis-dap, jlink, raspberrypi-swd)
PACKAGES: 
 - framework-arduino-mbed @ 4.0.2 
 - tool-rp2040tools @ 1.0.2 
 - toolchain-gccarmnoneeabi @ 1.90201.191206 (9.2.1)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 43 compatible libraries
Scanning dependencies...
Dependency Graph
|-- Simple FOC @ 2.3.0
Building in release mode
Compiling .pio\build\pico\libb10\Simple FOC\sensors\MagneticSensorI2C.cpp.o
Compiling .pio\build\pico\libb10\Simple FOC\sensors\MagneticSensorSPI.cpp.o
Archiving .pio\build\pico\libFrameworkArduinoVariant.a
Compiling .pio\build\pico\FrameworkArduino\timer.cpp.o
Compiling .pio\build\pico\FrameworkArduino\wiring.cpp.o
Compiling .pio\build\pico\FrameworkArduino\wiring_analog.cpp.o
Compiling .pio\build\pico\FrameworkArduino\wiring_digital.cpp.o
Compiling .pio\build\pico\FrameworkArduino\wiring_pulse.cpp.o
Compiling .pio\build\pico\FrameworkArduino\wiring_shift.cpp.o
In file included from .pio\libdeps\pico\Simple FOC\src\sensors\MagneticSensorI2C.cpp:1:
.pio\libdeps\pico\Simple FOC\src\sensors\MagneticSensorI2C.h:5:10: fatal error: Wire.h: No such file or directory

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

    5 | #include <Wire.h>
      |          ^~~~~~~~
compilation terminated.
*** [.pio\build\pico\libb10\Simple FOC\sensors\MagneticSensorI2C.cpp.o] Error 1
In file included from .pio\libdeps\pico\Simple FOC\src\sensors\MagneticSensorSPI.cpp:2:
.pio\libdeps\pico\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
*
*************************************************************

    6 | #include <SPI.h>
      |          ^~~~~~~
compilation terminated.
*** [.pio\build\pico\libb10\Simple FOC\sensors\MagneticSensorSPI.cpp.o] Error 1
========================== [FAILED] Took 5.75 seconds ==========================

Verbose for one file:

arm-none-eabi-g++ -o ".pio\build\pico\libb10\Simple FOC\sensors\MagneticSensorI2C.cpp.o" -c -Wvla -fno-rtti -std=gnu++14 -DMBED_TRAP_ERRORS_ENABLED=1 -Os -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -c -fdata-sections -ffunction-sections -fmessage-length=0 -fno-exceptions -fomit-frame-pointer -funsigned-char -mcpu=cortex-m0plus -mthumb 
-iprefixC:\Users\svofs\.platformio\packages\framework-arduino-mbed\cores\arduino @C:\Users\svofs\.platformio\packages\framework-arduino-mbed\variants\RASPBERRY_PI_PICO\includes.txt 
-nostdlib -DPLATFORMIO=60111 -DARDUINO_RASPBERRY_PI_PICO -DARDUINO_ARCH_RP2040 -DARM_MATH_CM0PLUS -DCOMPONENT_FLASHIAP=1 -DDEVICE_ANALOGIN=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 -DDEVICE_I2CSLAVE=1 -DDEVICE_INTERRUPTIN=1 -DDEVICE_PORT_IN=1 -DDEVICE_PORT_OUT=1 -DDEVICE_PWMOUT=1 -DDEVICE_RESET_REASON=1 -DDEVICE_RTC=1 -DDEVICE_SERIAL=1 -DDEVICE_SERIAL_FC=1 -DDEVICE_SPI=1 -DDEVICE_USBDEVICE=1 -DDEVICE_USTICKER=1 -DDEVICE_WATCHDOG=1 -DMBEDTLS_ENTROPY_NV_SEED -DMBED_BUILD_TIMESTAMP=1670863580.9430058 -DMBED_MPU_CUSTOM -DPICO_NO_BINARY_INFO=1 -DPICO_ON_DEVICE=1 -DPICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1 -DPICO_TIME_DEFAULT_ALARM_POOL_DISABLED -DPICO_UART_ENABLE_CRLF_SUPPORT=0 -DTARGET_CORTEX -DTARGET_CORTEX_M -DTARGET_LIKE_CORTEX_M0 -DTARGET_LIKE_MBED -DTARGET_M0P -DTARGET_NAME=RASPBERRY_PI_PICO -DTARGET_RASPBERRYPI -DTARGET_RASPBERRY_PI_PICO -DTARGET_RELEASE -DTARGET_RP2040 -DTARGET_memmap_default -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -D__CMSIS_RTOS -D__CORTEX_M0PLUS -D__MBED_CMSIS_RTOS_CM -D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= -DCORE_PATCH= -DUSE_ARDUINO_PINOUT -DARDUINO=10810 -DARDUINO_ARCH_MBED "-I.pio\libdeps\pico\Simple FOC\src" 
-IC:\Users\svofs\.platformio\packages\framework-arduino-mbed\cores\arduino
-IC:\Users\svofs\.platformio\packages\framework-arduino-mbed\cores\arduino\api\deprecated
-IC:\Users\svofs\.platformio\packages\framework-arduino-mbed\cores\arduino\api\deprecated-avr-comp
-IC:\Users\svofs\.platformio\packages\framework-arduino-mbed\variants\RASPBERRY_PI_PICO ".pio\libdeps\pico\Simple FOC\src\sensors\MagneticSensorI2C.cpp"

Since you added SimpleFOC as a library in PIO (lib_deps in the .ini file) it will try to compile the whole thing, which is relying on those libraries to be available. Even if you’re not using them, they’re needed to compile the SFOC library. You can add:

lib_deps = 
SPI
Wire
askuric/Simple FOC@^2.3.0
1 Like

@VIPQualityPost thank you, that indeed works!

I’m looking at one of your platformio.ini files here though:

And there’s no SPI or Wire in lib_deps. The tutorial also doesn’t mention adding them. Is this something that has changed recently, or is there more to it?

It’s weird, not sure what is up there… I’ve never had to explicitly add these libraries, as normally they are built in and ship with the frameworks…

I’ll have to see if I have the same problem on RP2040.

1 Like

Yes, I think this is a framework issue too…

edit: just checked my first rp2040 board from a long time ago, and I didn’t need to put these in - maybe if I try to re-build this project, it’ll flag as necessary, but definitely was not required at the time.

Last night I have found out that there are two versions of Arduino framework for pipico. The default one is based on mbed, the other one by Earle Philhower uses Pico SDK. I can’t say that I agree that the more the better applies in this case, a lot of confusion and unspeakable amount of wasted effort is more like it. Anyway, rant off…

Back on topic – turns out that they implement SPI slightly differently. To instantiate SPI1 in the mbed version, you have to do something like this:

constexpr int SPI1_MISO = 12;
constexpr int SPI1_MOSI = 11;
constexpr int SPI1_SCLK = 10;

MbedSPI SPI1(SPI1_MISO, SPI1_MOSI, SPI1_SCLK);

Yup. Mbed is total crap, IMHO.

Earlephilhower’s core is around 2x-4x faster because it doesn’t use mbed.

I also find it extremely weird that they had to build something NOT on the official SDK, which is so good and well documented. I quickly tried to switch, but it turns out that Philhower’s version has to build everything from source and under Windows it’s somehow a huge drama, so I backed off for now.

Funnily my first attempt to peruse platformio core for rp2040 was under my normal pipico virtualboxed Linux, but it’s Alpine-based, which uses musl, and none of the platformio-supplied pre-built toolchain stuff agreed to work on it, even with compat libs installed, so I switched to Windows.

Wow, ok that’s weird. I use platformio under OSX and it works with no problems.
Normally platformio downloads all the tools and components it needs, but I guess there’s some kind of incompatibility with your strange Linux.

I don’t find the official SDK that well documented, actually, but it’s there under the hood, in both framework versions… the SimpleFOC code uses the Pico SDK methods to initialize PWM and current sensing, since that’s not something you can do with Arduino framework apis.

Platformio did download pre-built toolchain, which was pre-built in an incompatible environment and I didn’t find an option to use my existing toolchain.

My Linux is not really strange: Alpine is used very frequently in Docker-based environments and Docker-based environments are very frequently used for repeatable builds. So it’s the duck’s guts for my specific needs. The only thing that’s slightly strange is that I’m using it in a full virtual machine rather than in a container. This is because I also like it handling all pico-usb stuff as well.

Hoorj! Managed to build my test project with Philhower toolchain under my strangelinux :slight_smile:

I had to make one modification to Simple FOC:

somehow hardware/adc.h was not included and I had compile errors.

There are also const-ness violations in the Commander that are trivial to fix:

src/main.cpp: In function 'void setup()':
src/main.cpp:81:31: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
   81 |     command.add('A', onMotor, "motor");
      |                               ^~~~~~~
1 Like

Yeah, it’s a bug but it’s fixed on the dev branch IIRC, it will be part of the next release…

1 Like