Embedded

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

How to use printf in mbed using STM32F429I-DISC1 and PlatformIO

In PlatformIO, you can directly use printf without any special configuration for the STM32F429-DISC1 discovery board:

#include <mbed.h>

int main() {
  while(1) {
    printf("Hello world\n");
    wait(0.5);
  }
}

This program will print Hello world twice every second. You can watch the output using the PlatformIO Monitor feature.

Posted by Uli Köhler in mbed

How to toggle the STM32F429I-DISCOVERY LED using mbed + PlatformIO

This simple firmare toggles the LED on the STM32F429I-DISC1 discovery board.

#include <mbed.h>

DigitalOut myled(LED1);

int main() {
  while(1) {
    myled = !myled;
    wait(0.5);
  }
}

This will toggle the green (PG13) LED twice per second.

The program is simple: We toggle the LED using myled = !myled; and then use wait(0.5) for 0.5 seconds.

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

How to fix raspi-config “The splash screen is not installed so cannot be activated”

Problem:

You want to enable the boot splash screen on your Raspberry Pi using raspi-config, but you see this error message:

The splash screen is not installed so cannot be activated

followed by There was an error running option B3 Splash Screen

Solution:

As you can find out from reading the raspi-config source code, it checks for the existence of /usr/share/plymouth/themes/pix/pix.script. In order to install this file, install the rpd-plym-splash package:

sudo apt -y install rpd-plym-splash
Posted by Uli Köhler in Embedded, Linux, Raspberry Pi

How to manually reload Chromium Kiosk

Problem:

You are running a Chromium Kiosk e.g. on a Raspberry Pi using a command like

chromium-browser --noerrdialogs --disable-infobars --disk-cache-dir=/dev/null --disk-cache-size=1 --kiosk http://localhost

e.g. in /etc/xdg/openbox/autostart, but you don’t know how to manuy reload the Kiosk e.g. after you have changed the underlying website

Solution:

In /etc/xdg/openbox/autostart or wherever your chromium-browser command is, enclose it in

while true ; do [CHROMIUM COMMAND] ; sleep 1 ; done

The complete command would look like this, for example:

while true ; do chromium-browser  --noerrdialogs --disable-infobars --disk-cache-dir=/dev/null --disk-cache-size=1 --kiosk http://localhost ; sleep 1 ; done

Now, to manually reload Chromium, all you have to do is to kill the process using

killall /usr/lib/chromium-browser/chromium-browser-v7

This will kill the Chromium process and the while loop will automatically restart it after one second.

In case you see an error message like

/usr/lib/chromium-browser/chromium-browser-v7: No such file or directory

you need to find out which executable is used for Chromium in order to pass that to killall. To find out the name of the executable, use

ps a | grep -i chromium

and look for a string similar to /usr/lib/chromium-browser/chromium-browser-v7.

Posted by Uli Köhler in Embedded, Linux

How to fix Chromium Kiosk still displaying old page after reboot

Problem:

You are running a Chromium Kiosk application on an embedded computer (like a Raspberry Pi) using a command like

chromium-browser --noerrdialogs --disable-infobars --kiosk http://localhost

but when you update the webpage, Chromium still displays the old page even after a reboot.

Solution:

Disable Chromium’s cache by adding

--disk-cache-dir=/dev/null --disk-cache-size=1

to the command (which is typically found in /etc/xdg/openbox/autostart). The full command will look like this:

chromium-browser --noerrdialogs --disable-infobars --disk-cache-dir=/dev/null --disk-cache-size=1 --kiosk http://localhost
Posted by Uli Köhler in Embedded, Linux

How to fix bricked Arduino MKR Zero using the RESET button

After I uploaded a broken firmware to my Arduino MKR Zero, it didnt enumerate over USB any more, hence it was not possible to upload a new firmware any more.

However, you can put the Arduino into perpetual bootloader mode by pressing the RESET button twice quickly. In this mode, the Arduino will never attempt to start the broken firmware, so you will be able to upload a new firmware again.

Posted by Uli Köhler in Arduino, Embedded

How to fix Keil EFM8 Warning C280: unreferenced local variable

Problem:

You have a C function like

int myfunc(int value) {
  return 0;
}

but you see a Keil compiler warning like

*** WARNING C280 IN LINE 7 OF C:\Users\uli\MyProject\src\main.c: 'value': unreferenced local variable

Solution:

'value': unreferenced local variable means that you don’t use that variable value in any way.

In the function shown above, you can see that value is the argument of myfunc but myfunc never actually uses the variable.

Do you think that variable should be used in this function?

You need to check your function for typos – the variable is never used at all. Possibly you are using the wrong variable or your function is missing some part of its logic.

Don’t want to use that variable at all?

Usually you can tell the compiler that you don’t want to use that variable by using

(void)value;

but that will produce an expression with possibly no effect warning.

*** WARNING C275 IN LINE 7 OF C:\Users\uli\MyProject\src\main.c: expression with possibly no effect

You can use this hack to avoid this warning:

r = r; // Avoid unused local variable

 

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

How to fix Keil EFM8 ERROR C267 ‘SLAB_ASSERT’: requires ANSI-style prototype

Problem:

You want to compile your EFM8 application but you see these error messages:

*** WARNING C206 IN LINE 86 OF C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\8051\v4.1.7\Device\EFM8BB3\peripheral_driver\src\adc_0.c: 'SLAB_ASSERT': missing function-prototype
*** ERROR C267 IN LINE 86 OF C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\8051\v4.1.7\Device\EFM8BB3\peripheral_driver\src\adc_0.c: 'SLAB_ASSERT': requires ANSI-style prototype

Solution:

Go into your Project properties (by right-clicking on your project on the top left and clicking “Properties”) -> C/C++ Build -> Project Modules

There, select 8051 -> EFM8 and check the Assert checkbox to include the assertion module. Now recompile your module.

Posted by Uli Köhler in EFM8, Embedded

How to fix Keil error C129: “missing ‘;'” without any missing semicolon (EFM8)

Problem:

You have source code like

uint16_t convert(uint16_t input) {
   return input * 2;
}

that you want to compile using EFM8

// *** ERROR C129 IN LINE 1 OF C:\Users\user\TestProject\src\Test.c: missing ';' before 'convert'

Solution:

Keil doesn’t know what the uint16_t before the declaration of convert().

#include <stdint.h>

stdint.h contains declarations for several standard integer types like uint8_t, uint16_t, uint32_t, int16_t etc.

The final code should look like this:

#include <stdint.h>

uint16_t convert(uint16_t input) {
    return input * 2;
}

 

Posted by Uli Köhler in EFM8

What does SCON0_TI = 1 mean for the EFM8?

SCON0 is the UART0 serial port control register (Serial CONtrol 0). The TI bit enables the Transmit Interrupt, i.e. when the transmission of a byte is finished, the CPU will be interrupted.

Setting

SCON0_TI = 1;

is neccessary for some of the EFM8 UART libraries (like the STDIO UART library) so they initialize properly. Although this is a simplification, the library needs to know that there is no UART transmission going on at the moment.

Also, don’t forget to enable global interrupts using

IE_EA = 1;

else, the UART0 transmit interrupt will never be run.

Posted by Uli Köhler in EFM8, Embedded

Arduino MKR Zero schematic library for KiCAD

This library provides a schematic symbol for the Arduino MKR zero’s 2.54mm (0.1″) headers. Currently I don’t have the footprint

Download KiCAD schematic library here (ArduinoMKRZero.lib)

This KiCAD library is hereby released into the public domain (CC0 1.0 Universal)

This image shows the Arduino MKR Zero schematic symbol from the library.

Posted by Uli Köhler in Arduino, Electronics, KiCAD

How to fix wifi blocked on boot on Raspberry Pi 4

After migrating a fresh Raspbian install using the official 2020-04 Raspbian light image from my Raspberry Pi Model 2 to my new Raspberry Model 4, the Wifi was disabled at boot.

I tried configuring the Wifi using raspi-config but that didn’t change anything.

First, try rfkill unblock all and then reboot in order to check if the Wifi adapter is still unblocked after the reboot. In my case, this fixed the issue permanently and wifi worked immediately.

If that doesn’t help, check if country=... is set in /etc/wpa_supplicant/wpa_supplicant.conf. You need to set it to your correct country code to comply with regulatory limits. For example, use country=DE to set the regulatory domain to Germany.

Posted by Uli Köhler in Linux, Raspberry Pi

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

Computing the CRC8-ATM CRC in Python

The 8-bit CRC8-ATM polynomial is used in many embedded applications, including Trinamic UART-controlled stepper motor drivers like the TMC2209:

\text{CRC} = x^8 + x^2 + x^1 + x^0

The following code provides an example on how to compute this type of CRC in Python:

def compute_crc8_atm(datagram, initial_value=0):
    crc = initial_value
    # Iterate bytes in data
    for byte in datagram:
        # Iterate bits in byte
        for _ in range(0, 8):
            if (crc >> 7) ^ (byte & 0x01):
                crc = ((crc << 1) ^ 0x07) & 0xFF
            else:
                crc = (crc << 1) & 0xFF
            # Shift to next bit
            byte = byte >> 1
    return crc

This code has been field-verified for the TMC2209.

Posted by Uli Köhler in Algorithms, Embedded, MicroPython, Python

MicroPython ESP32 minimal UART example

This example shows how to use UART on the ESP32 using MicroPython. In this example, we use UART1 which is mapped to pins GPIO9 (RX) and GPIO10 (TX).

from machine import UART
uart = UART(1, 115200) # 1st argument: UART number: Hardware UART #1

# Write
uart.write("test")

# Read
print(uart.read()) # Read as much as possible using

Don’t know how to upload the file to MicroPython so it is automatically run on boot?

Posted by Uli Köhler in Embedded, MicroPython, Python