PlatformIO

How to fix PlatformIO ESP8266/ESP32 fatal error: SPI.h: No such file or directory

Problem:

You are trying to compile your PlatformIO application for the ESP8266 or ESP32 but you’re seeing an error message like

In file included from .pio/libdeps/d1_mini/TFT_eSPI/TFT_eSPI.cpp:17:0:
.pio/libdeps/d1_mini/TFT_eSPI/TFT_eSPI.h:32:17: 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://platformio.org/lib/search?query=header:SPI.h
*
*************************************************************

 #include <SPI.h>

This problem is common using the TFT_eSPI library.

Solution:

First, ensure that your platformio.ini has

framework = arduino

If you’re using a different frameworkSPI.h won’t be available since it’s a part of the Arduino framework !

Secondly, add this line to your platformio.ini:

lib_ldf_mode = deep+

and recompile your source code. This will reconfigure the library dependency finder (ldf) to find dependencies of dependency libraries:

Dependency Graph
|-- <TFT_eSPI> 2.3.52
|   |-- <SPI> 1.0

 

Posted by Uli Köhler in ESP8266/ESP32, PlatformIO

Where to find info about mbed mbed_app.json overridable parameters?

The first resource can have a look at is the platform configuration option page. Additionally, check the manual on how to use the mbed CLI to show configuration options.

Additionally, you can look at targets.json on GitHub:

For example, "Target" => "config" => "default-adc-vref" would need to be entered like this into mbed_app.json:

{
    "target_overrides": {
      "*": {
          "target.default-adc-vref": 3300
      }
    }
}

 

Posted by Uli Köhler in C/C++, mbed, PlatformIO

How to fix mbed AnalogIn.read_voltage() returning nan or 0.000 (PlatformIO)

Problem:

You are trying to read an ADC voltage in mbed / PlatformIO like this:

AnalogIn myADC(PA_5); 
// Read and print voltage, then return
float v = myADC.read_voltage();
printf("%f\n", v);

but this only prints nan or 0.000.

Solution:

mbed doesn’t know the reference voltage for your platform. The easiest method is to provide the referene voltage in the constructor of AnalogIn:

AnalogIn myADC(PA_5, 3.3);

This specifies a reference voltage of 3.3V. While this applies to most applications in their default configuration, note that the reference voltage might be different depending on the configuration of your microcontroller.

In my experience, it’s almost always better to experimentally verify the reference voltage instead of trying to theorize about it if it’s not immediately obvious.

Full example:

#include <mbed.h>

BufferedSerial pc(USBTX, USBRX, 115200); // tx, rx

AnalogIn   myADC(PA_5, 3.3);

FileHandle *mbed::mbed_override_console(int fd) {
    return &pc;
}

int main() {
  while(1) {
    float v = myADC.read_voltage();
    printf("%f\n", v);
    ThisThread::sleep_for(100ms);
  }
}
{
    "target_overrides": {
      "*": {
        "target.printf_lib": "std"
      }
    }
}
Posted by Uli Köhler in C/C++, mbed, PlatformIO

How to fix mbed printf() ignoring decimals in PlatformIO

Problem:

You are using code like

printf("%.2f\n", myFloat);

in your mbed/PlatformIO application, but instead of printing myFloat with 2 decimal places, it always prints it with 6 decimal places (like 0.000000).

Solution:

mbed uses the minimal-printf library by default which is configured to save space on the Microcontroller. Hence, float max decimals support is disabled by default. In order to get all printf features at the expense of more flash usage and much slower executing, us add mbed_app.json in the root directory of the PlatformIO project with "target.printf_lib": "std":

{
    "target_overrides": {
      "*": {
        "target.printf_lib": "std"
      }
    }
}

See the platform configuration option page for more details and similar options.

Posted by Uli Köhler in C/C++, mbed, PlatformIO

How to fix mbed printf() printing literal %f in PlatformIO

Problem:

You are using code like

printf("%f\n", myFloat);

in your mbed/PlatformIO application, but instead of printing myFloat it prints literal %f.

Solution:

mbed uses the minimal-printf library by default which is configured to save space on the Microcontroller. Hence, float support (i.e. %f support) is disabled by default. You need to enable it by adding mbed_app.json in the root directory of the PlatformIO project with "platform.minimal-printf-enable-floating-point": true:

{
    "target_overrides": {
      "*": {
        "platform.minimal-printf-enable-floating-point": true
      }
    }
}

See the platform configuration option page for more details and similar options.

Posted by Uli Köhler in C/C++, mbed, PlatformIO

How to fix mbed error: ‘wait’ was not declared in this scope (PlatformIO)

Problem:

While compiling your mbed / PlatformIO application, you see an error message like

src/actuators.cpp:253:5: error: 'wait' was not declared in this scope
  253 |     wait(1.0);
      |     ^~~~

 

Solution:

wait is an old API and has been deprecated in favour of the C++ standard ThisThread::sleep_for. Use

ThisThread::sleep_for(1s);

 

Posted by Uli Köhler in Embedded, mbed, PlatformIO

How to fix PlatformIO mbed error: ‘Mutex’ does not name a type

Problem:

You are trying to compile your PlatformIO mbed application using Mutexes like

Mutex myLock;

but you see an error message like

src\main.cpp:3:1: error: 'Mutex' does not name a type
 Mutex myLock;
 ^~~~~

Solution:

Add this line to your platformio.ini:

build_flags = -D PIO_FRAMEWORK_MBED_RTOS_PRESENT

This will enable the RTOS features in mbed, including the Mutex.

Posted by Uli Köhler in mbed, PlatformIO

How to fix PlatformIO fatal error: stm32f429i_discovery_lcd.h: No such file or directory

Problem:

You are trying to compile your PlatformIO application using  the LCD_DISCO_F429ZI library, but you see an error message like

 #include "stm32f429i_discovery_lcd.h"
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
*** [.pio\build\disco_f429zi\src\main.o] Error 1
In file included from .pio\libdeps\disco_f429zi\LCD_DISCO_F429ZI_ID2432\LCD_DISCO_F429ZI.cpp:19:0:
.pio\libdeps\disco_f429zi\LCD_DISCO_F429ZI_ID2432\LCD_DISCO_F429ZI.h:25:10: fatal error: stm32f429i_discovery_lcd.h: No such file or directory

Solution:

First, ensure that BSP_DISCO_F429ZI is listed is library dependency in platformio.ini like this:

[env:disco_f429zi]
platform = ststm32
board = disco_f429zi
framework = mbed
lib_deps =
    LCD_DISCO_F429ZI
    BSP_DISCO_F429ZI

 

Replace the line

#include "stm32f429i_discovery_lcd.h"

in LCD_DISCO_F429ZI.h with

#include "Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_lcd.h"

 

Posted by Uli Köhler in C/C++, PlatformIO

How to fix PlatformIO fatal error: ../Fonts/fonts.h: No such file or directory

Problem:

You are trying to compile a PlatformIO application using the BSP_DISCO_F429ZI library, but you see an error message like

In file included from .pio\libdeps\disco_f429zi\BSP_DISCO_F429ZI_ID2208\Drivers\BSP\STM32F429I-Discovery\stm32f429i_discovery_lcd.c:75:0:
.pio\libdeps\disco_f429zi\BSP_DISCO_F429ZI_ID2208\Drivers\BSP\STM32F429I-Discovery\stm32f429i_discovery_lcd.h:49:10: fatal error: ../Fonts/fonts.h: No such file or directory
 #include "../Fonts/fonts.h"
          ^~~~~~~~~~~~~~~~~~
compilation terminated.

Solution:

The BSP_DISCO_F429ZI package includes fonts.h from the wrong directory. Replace

#include "../Fonts/fonts.h"

by

#include "Utilities/Fonts/fonts.h"

in order to fix the issue. You might need to do that multiple times (in multiple files) in order to fix your build.

Posted by Uli Köhler in C/C++, PlatformIO

Minimal ESP-IDF UART transmit example for ESP32 & PlatformIO

The following example writes the string CAFE to UART continously, waiting for 100ms in between:

#include <driver/gpio.h>
#include <driver/uart.h>
// Include FreeRTOS for delay
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>

int app_main() {
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };
    uart_driver_install(UART_NUM_1, 2048, 0, 0, NULL, 0);
    uart_param_config(UART_NUM_1, &uart_config);
    uart_set_pin(UART_NUM_1, 10, 9, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

    // Main loop
    while(true) {
        uart_write_bytes(UART_NUM_1, "CAFE", 5);
        vTaskDelay(100 / portTICK_RATE_MS);
    }
}

 

Posted by Uli Köhler in C/C++, Embedded, PlatformIO

ESP-IDF equivalent to Arduino delay()

You can use the FreeRTOS API to provide a delay similar to the Arduino delay() function in the ESP-IDF framework. FreeRTOS is included in the PlatformIO ESP-IDF default configuration.

First, include the FreeRTOS headers

// Include FreeRTOS for delay
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>

After that, you can use vTaskDelay(...) to perform the delay. This example delays by 500ms:

vTaskDelay(500 / portTICK_RATE_MS);

You can use vTaskDelay() even if not using FreeRTOS tasks.

For a full example, refer to PlatformIO ESP-IDF ESP32 blink example

Posted by Uli Köhler in C/C++, Embedded, PlatformIO

How to set pin to output mode using ESP-IDF

Use this snippet to define a pin as output using the ESP-IDF framework (e.g. using PlatformIO):

gpio_config_t io_conf;
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
// Define the pin here (e.g. (1ULL << 2) for GPIO9)
io_conf.pin_bit_mask = (1ULL << 2);
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);

The example above configures GPIO2 as an output. Use (1ULL << 3) to configure GPIO3 as an output

Posted by Uli Köhler in C/C++, Embedded, PlatformIO

How to fix ESP-IDF ‘undefined reference to app_main’

Problem:

You are trying to compile your C/C++ ESP8266/ESP32 firmware using the ESP-IDF framework. Your source code looks like this:

int main() {
    // ...
}

but you only see an error message like this:

.platformio/packages/toolchain-xtensa32/bin/../lib/gcc/xtensa-esp32-elf/8.2.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\nodemcu-32s\esp-idf\esp32\libesp32.a(cpu_start.c.o):(.literal.main_task+0x18): undefined reference to `app_main'
.platformio/packages/toolchain-xtensa32/bin/../lib/gcc/xtensa-esp32-elf/8.2.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\nodemcu-32s\esp-idf\esp32\libesp32.a(cpu_start.c.o): in function `main_task':
.platformio\packages\framework-espidf\components\esp32/cpu_start.c:540: undefined reference to `app_main'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\nodemcu-32s\firmware.elf] Error 1

Solution:

For the ESP-IDF framework, the main() function needs to be named app_main():

int app_main() {
    // ...
}

See PlatformIO ESP-IDF ESP32 blink example for a complete example.

Posted by Uli Köhler in C/C++, Embedded, PlatformIO

PlatformIO ESP-IDF ESP32 blink example

This example is the equivalent of the simple Arduino blink example for ESP32 boards when using the ESP-IDF framework:

#include <driver/gpio.h>
// Include FreeRTOS for delay
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>

#define LED 2 // LED connected to GPIO2

int app_main() {
    // Configure pin
    gpio_config_t io_conf;
    io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_OUTPUT;
    io_conf.pin_bit_mask = (1ULL << LED);
    io_conf.pull_down_en = 0;
    io_conf.pull_up_en = 0;
    gpio_config(&io_conf);

    // Main loop
    while(true) {
        gpio_set_level(LED, 0);
        vTaskDelay(500 / portTICK_RATE_MS);
        gpio_set_level(LED, 1);
        vTaskDelay(500 / portTICK_RATE_MS);
    }
}

 

Posted by Uli Köhler in C/C++, Embedded, PlatformIO

How to fix Platform IO “No tasks to run found. Configure tasks…”

If you see this message while trying to run a PlatformIO task like Build or Upload:

No tasks to run found. Configure tasks...

you can fix that easily: Open Preferences: Open settings (JSON) in Visual Studio code (the default keybinding to open the action menu is Ctrl+Shift+P).

Then look for this line:

"task.autoDetect": "off"

and delete it.

Now save the file. You can immediately run PlatformIO tasks after saving settings.json without restarting Visual Studio Code !

Posted by Uli Köhler in PlatformIO

mbed STM32F4DISCOVERY simple LED demo

This demo shows you how to control the STM32F4DISCOVERY LEDs using mbed.
I use mbed from inside PlatformIO.

#include <mbed.h>

DigitalOut greenLED(PD_12);
DigitalOut orangeLED(PD_13);
DigitalOut redLED(PD_14);
DigitalOut blueLED(PD_15);

int main() {
  while(1) {
    // Cycle LEDs in order
    // NOTE: You can toggle a LED using
    //  blueLED = !blueLED;
    blueLED = 0;
    greenLED = 1;
    wait(0.25);
    greenLED = 0;
    orangeLED = 1;
    wait(0.25);
    orangeLED = 0;
    redLED = 1;
    wait(0.25);
    redLED = 0;
    blueLED = 1;
    wait(0.25);
  }
}

 

Posted by Uli Köhler in mbed, PlatformIO