How to write Pandas bool column as True/False instead of 1/0 to XLSX

Problem:

When writing a pandas XLSX, bool-type columns are shown are 0 for False or 1 for True.

df = pd.DataFrame([
    {"a": True},
    {"a": False},
    {"a": True},
    {"a": False},
    {"a": False},
])

with pd.ExcelWriter("out.xlsx", engine="xlsxwriter") as writer:
    df.to_excel(writer)

Solution:

Map the column to a string column with your desired value before exporting:

df["a"] = df["a"].map({True: "True", False: "False"})

Full example code:

df = pd.DataFrame([
    {"a": True},
    {"a": False},
    {"a": True},
    {"a": False},
    {"a": False},
])
df["a"] = df["a"].map({True: "True", False: "False"})
with pd.ExcelWriter("out.xlsx", engine="xlsxwriter") as writer:
    df.to_excel(writer)

 

Posted by Uli Köhler in pandas, Python

How to implement 1MHz interrupt in PlatformIO / Arduino on STM32

In our previous post Minimal STM32 HardwareTimer PlatformIO / Arduino timer interrupt blink example we showed how to use HardwareTimer to blink the onboard LED of our STM32F407 board using a timer interrupt.

In this post, we’ll provide an example of how to use HardwareTimer and have a really fast interrupt which runs at 1 MHz – in other words: one million times per second.

#include <Arduino.h>

HardwareTimer timer(TIM1);
bool ledOn = false;

void OnTimer1Interrupt() {
    ledOn = !ledOn;
    digitalWrite(PC13, ledOn ? HIGH : LOW);
}

void setup() {
    pinMode(PC13, OUTPUT);
    // Configure timer
    timer.setPrescaleFactor(21); // Set prescaler to 21 => timer frequency = 168/21 = 8 MHz (from prediv'd by 1 clocksource of 168 MHz)
    timer.setOverflow(8); // Set ARR to 8 => timer frequency = 1 MHz
    timer.attachInterrupt(OnTimer1Interrupt);
    timer.refresh(); // Make register changes take effect
    timer.resume(); // Start timre
}

void loop() {
}

Note that when running such a quick interrupt, you can’t do all too much within the interrupt before the next time the interrupt will run.

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

Minimal STM32 HardwareTimer PlatformIO / Arduino timer interrupt blink example

This is a minimal example of using timer interrupts on PlatformIO / Arduino using HardwareTimer (which is a part of the PlatformIO STM32 Arduino installation – no need to install a library). Tested on the Olimex E407 board. It will run on almost any STM32 processor but you might need to adjust PC13 to the PIN connected to the LED. The example will blink the LED once per second.

#include <Arduino.h>

HardwareTimer timer(TIM1);
bool ledOn = false;

void OnTimer1Interrupt() {
    ledOn = !ledOn;
    digitalWrite(PC13, ledOn ? HIGH : LOW);
}

void setup() {
    pinMode(PC13, OUTPUT);
    // Configure timer
    timer.setPrescaleFactor(2564); // Set prescaler to 2564 => timer frequency = 168MHz/2564 = 65522 Hz (from prediv'd by 1 clocksource of 168 MHz)
    timer.setOverflow(32761); // Set overflow to 32761 => timer frequency = 65522 Hz / 32761 = 2 Hz
    timer.attachInterrupt(OnTimer1Interrupt);
    timer.refresh(); // Make register changes take effect
    timer.resume(); // Start
}

void loop() {
}

 

Posted by Uli Köhler in PlatformIO, STM32

How to use STM32 _Msk and _Pos definitions to read and write registers

The STM32 HAL contains definitions like TIM_CR1_CKD_Msk or TIM_CR1_CKD_Pos which you can use to make it easier to read or write parts of a register.

Reading a part of a register

uint32_t ckd = (TIM1->CR1 & TIM_CR1_CKD_Msk) >> TIM_CR1_CKD_Pos;

Writing a part of a register

uint32_t new_ckd_value = TIM_CLOCKDIVISION_DIV4; // example
TIM1->CR1 &= TIM_CR1_CKD_Msk; // Clear bits
TIM1->CR1 |= new_ckd_value << TIM_CR1_CKD_Pos; // Set bits

 

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

How to fix PlatformIO “Start debugging” doing nothing

Problem:

When you click on Start debugging, press F5 or click on the debug start triangle in PlatformIO

the firmware builds but then nothing happens:

Linking .pio/build/olimex_e407/firmware.elf
Checking size .pio/build/olimex_e407/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   0.7% (used 936 bytes from 131072 bytes)
Flash: [          ]   1.7% (used 18064 bytes from 1048576 bytes)
Building .pio/build/olimex_e407/firmware.bin
======================================================================== [SUCCESS] Took 2.72 seconds ========================================================================

Solution:

You need to specify a debug_tool in platformio.ini. For STM32 processors, a typical choice is

debug_tool = stlink

A list of options for debug_tool is available here.

Note that you can NOT debug many boards via the USB port. You can not debug boards attached via serial-to-USB converter (like many Arduino boards). Your board need to have a proper debugger on-board (like an stlink which is integrated on many STM32 eval boards) or you need to use an external debugger.

Posted by Uli Köhler in PlatformIO, STM32

Minimal STM32 TimerInterrupt_Generic PlatformIO / Arduino timer interrupt blink example

Note: If you need more flexibility, see Minimal STM32 HardwareTimer PlatformIO / Arduino timer interrupt blink example where we show how to use HardwareTimer instead of TimerInterrupt_Generic. Note that TimerInterrupt_Generic uses HardwareTimer internally.

This is a minimal example of using timer interrupts on PlatformIO / Arduino using the TimerInterrupt_Generic library which runs on the Olimex E407. It will run on almost any STM32 processor but you might need to adjust PC13 to the PIN connected to the LED. The example will blink the LED once per second.

#include <Arduino.h>
#include <TimerInterrupt_Generic.h>

STM32Timer tim1(TIM1);
bool ledOn = false;

void OnTimer1Interrupt() {
    ledOn = !ledOn;
    digitalWrite(PC13, ledOn ? LOW : HIGH);
}

void setup() {
    pinMode(PC13, OUTPUT);
    // Enable TIM4
    
    tim1.attachInterruptInterval(500000, OnTimer1Interrupt);
}

void loop() {
}

Now add

lib_deps =
     khoih.prog/TimerInterrupt_Generic @ ^1.7.0

to your platformio.ini. My full platformio.ini looks like this:

[env:olimex_e407]
platform = ststm32
board = olimex_e407
framework = arduino
lib_deps =
     khoih.prog/TimerInterrupt_Generic @ ^1.7.0

 

 

Posted by Uli Köhler in PlatformIO, STM32

PlatformIO Olimex E407 Arduino LED blink example

This code will make the Olimex E407 LED blink.

#include <Arduino.h>

void setup() {
    pinMode(PC13, OUTPUT);
}

void loop() {
    digitalWrite(PC13, LOW);
    delay(500);
    digitalWrite(PC13, HIGH);
    delay(500);
}

 

Posted by Uli Köhler in PlatformIO, STM32

How to fix PlatformIO Olimex E407 LED_BUILTIN not working

Problem

You are trying to run a firmware on the Olimex E407 that blinks the builtin green status LED. You code uses LED_BUILTIN similar to this:

#include <Arduino.h>

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
}

but when you upload the code onto the board, the LED does not blink and stays off.

Solution

Instead of LED_BUILTIN, use PC13 – the pin the LED is connected to (which you can see on the Olimex E407 schematic:

#include <Arduino.h>

void setup() {
    pinMode(PC13, OUTPUT);
}

void loop() {
    digitalWrite(PC13, LOW);
    delay(500);
    digitalWrite(PC13, HIGH);
    delay(500);
}

 

Posted by Uli Köhler in PlatformIO, STM32

How to fix PlatformIO STM32 Error: libusb_open() failed with LIBUSB_ERROR_ACCESS

Problem:

While trying to program your STM32 board using stlink and PlatformIO (most programmers integrated onto a development board are STLink programmers), you see this error message:

xPack OpenOCD, x86_64 Open On-Chip Debugger 0.11.0-00155-ge392e485e (2021-03-15-16:43)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
debug_level: 1

hla_swd
Error: libusb_open() failed with LIBUSB_ERROR_ACCESS
Error: open failed
in procedure 'program'
** OpenOCD init failed **
shutdown command invoked

Solution:

You need to setup the correct permissions for the STLink usb devices – in other words, install the correct stlink udev rules files. On Ubuntu, install stlink-tools using

sudo apt -y install stlink-tools
sudo systemctl restart udev

After that, unplug your stlink (or development board) for 5 seconds and plugin it in again. This will cause the new device permissions to take effect.

Now you can retry uploading the firmware from PlatformIO.

Posted by Uli Köhler in PlatformIO, STM32

How to start KiCAD installed from flatpak

After you have installed KiCAD from Flatpak using

flatpak install --from https://flathub.org/repo/appstream/org.kicad.KiCad.flatpakref

you can run it using

flatpak run org.kicad.KiCad

You can append any arguments to KiCAD, for example open a project file directly from the command line:

flatpak run org.kicad.KiCad MyProject.pro

 

Posted by Uli Köhler in KiCAD

How to create pandas pd.DataFrame from list of dicts

You can create a pandas pd.DataFrame from a list of dicts (lst) using the pd.DataFrame(lst) constructor.

a = {"x": 1, "y": 2}
b = {"x": 3, "y": 2}
c = {"x": 6, "y": 9}
df = pd.DataFrame([a,b,c])

df will look like this:

Posted by Uli Köhler in pandas, Python

How to fix git credential manager core: git fatal: No credential backing store has been selected.

Problem:

After installing git credential manager core, you see this error message:

fatal: No credential backing store has been selected.

Set the GCM_CREDENTIAL_STORE environment variable or the credential.credentialStore Git configuration setting to one of the following options:

  secretservice : freedesktop.org Secret Service (requires graphical interface)
  gpg           : GNU `pass` compatible credential storage (requires GPG and `pass`)
  cache         : Git's in-memory credential cache
  plaintext     : store credentials in plain-text files (UNSECURE)

See https://aka.ms/gcmcore-linuxcredstores for more information.

Solution:

If you are on a graphical computer, run

git config --global credential.credentialStore secretservice

On a server, if automated i.e. passwordless access is required, use

git config --global credential.credentialStore plaintext

Note that this is insecure since all the passwords are stored in a plaintext file.

Posted by Uli Köhler in git

How to identify the latest npm package version

You can use

npm info [package name] version | head -n1

to print just the latest package version, for example:

npm info @angular/cli version | head -n1

The head -n1 part is neccessary to suppress unwanted npm info messages. Just running the command without head -n1 :

npm info @angular/cli version

prints the following output:

12.2.6
npm notice 
npm notice New minor version of npm available! 7.21.1 -> 7.24.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v7.24.0
npm notice Run npm install -g [email protected] to update!
npm notice

I typically use the node:latest docker container instead of a local npm to find the latest version of an npm package:

docker run -it --rm node:latest npm info meshcommander version | head -n1

At the time of writing this article, the command prints

0.9.0-d

 

Posted by Uli Köhler in NodeJS

How to run one-off command in docker

If you want to just run a command on a docker image without permanently creating a container, run

docker run -it --rm [image] [command]

for example

docker run -it --rm node:latest npm --version

By using --rm we tell docker to immediately remove the container once the command has finished.

Posted by Uli Köhler in Allgemein

How to optimize MySQL/MariaDB tables in docker-compose

If your MariaDB / MySQL root password is stored in .env , use this command:

source .env && docker-compose exec mariadb mysqlcheck -uroot -p$MARIADB_ROOT_PASSWORD --auto-repair --optimize --all-databases

You can also directly use the root password in the command:

docker-compose exec mariadb mysqlcheck -uroot -phoox8AiFahuniPaivatoh2iexighee --auto-repair --optimize --all-databases

 

Posted by Uli Köhler in Container, Databases, Docker

How to rotate Raspberry Pi LCD by 180°

In order to rotate a DSI-connected LCD screen like the Raspberry Pi 7″ LCD screen by 180 degrees, append

lcd_rotate=2

to /boot/config.txt

Posted by Uli Köhler in Raspberry Pi

How to unpause Marlin after M0/M1 echo:busy: paused for user

In Marlin, you can pause the firmware using M0 or M1 which will cause the firmware to loop-print

echo:busy: paused for user
echo:busy: paused for user
echo:busy: paused for user
echo:busy: paused for user
echo:busy: paused for user
echo:busy: paused for user

In order to continue or unpause, use

M108

 

Posted by Uli Köhler in 3D printing

How to reboot Marlin using G-Code

On most Marlin boards, you can use M997 to reboot/restart the microcontroller:

M997

While this is technically the command to update the firmware, on most boards this is implemented by a simple reboot, which will load the bootloader which could update the firmware e.g. if there is a firmware.bin file on the SD card. Since unless a firmware update is intended there is no such file on the SD card, the M997 command will just reboot the board.

Posted by Uli Köhler in 3D printing