How to delete all .DS_Store files recursively on the command line

Use this command to recursively delete all .DS_Store files present in the directory mydir and all its subdirectories:

find mydir -type f -name .DS_Store -print0 | xargs -0 rm

Warning: Deleting the files can’t be undone.

Posted by Uli Köhler in Linux

How to fix SSH not accepting public key in authorized_keys

Problem:

You have added your SSH public key to a remote server manually or using ssh-copy-id but still you can’t login using that public key

Solution:

Typically this is caused by bad permissions of your ~/.ssh directory and/or your authorized_keys file. Fix that using:

chmod -R 700 ~/.ssh

then try to login again

Posted by Uli Köhler in Linux

How to run systemd timer twice daily

In order to run a systemd timer twice daily at fixed times, use this syntax in the .timer file:

OnCalendar=*-*-* 00,12:00:00

This line means: Run the service on each and every day (*-*-*) at 00:00:00 and 12:00:00 (00,12:00:00)

Posted by Uli Köhler in Linux

Find and remove all empty directories using the Linux command line

In order to find and remove all empty subdirectories in the current directory (.) recursively, use this command:

find . -depth -type d -print0 | xargs -0 rmdir

This command will only remove empty directories! Any file or non-empty directory won’t be modified.

Explanation of what the parts mean:

  • find: Use the find command to find directories recursively
  • .: Start recursing from the current directory. In case you want to start from a different directory, use that directory name here.
  • -type d: Only find directories – ignore files
  • -depth: Before printing a directory name, print all its sub-directory names. This avoids having to run this command repeatedly because the parent directory can’t be removed since its empty sub-directories need to be removed first
  • -print0 When printing all the directories that have been found, print a NUL character between directories. This is required in order to handle spaces in the directory names correctly
  • | xargs: Pipe the directories to xargs, a program that runs
  • -0: Split the input by NUL characters instead of newlines. This corresponds with the -print0 option to find and is required to handle spaces in directory names correctly.
  • rmdir: For each directory found, run rmdir i.e. try to remove the directory if it’s empty.
Posted by Uli Köhler in Linux

How to fix “OTGS Installer, responsible for receiving automated updates for WPML and Toolset, requires the following PHP component(s) in order to function:cURL” on Ubuntu 20.04

 Problem:

Your WordPress installation running on Ubuntu 20.04 shows you this error message:

OTGS Installer, responsible for receiving automated updates for WPML and Toolset, requires the following PHP component(s) in order to function:cURL

Learn more: Minimum WPML requirements

Solution:

You need to install the curl package for your PHP version.

Typically you can use

sudo apt -y install php7.4-curl

Doing this should immediately fix the issue (just reload your WordPress dashboard). In case you’re using PHP 7.2 you need to sudo apt -y install php7.2-curl instead.

In case the issue is still not fixed after doing this, try restarting your webserver (e.g. sudo service apache restart or sudo service nginx restart), try restarting PHP-FPM by using sudo service php7.4-fpm restart or sudo service php7.2-fpm restart or try rebooting your server. In case that doesn’t help either, you need to manually check which PHP instance the wordpress site is using and install the curl package for that PHP instance.

 

Posted by Uli Köhler in PHP, Wordpress

How to emulate Page up / Page down key in Puppeteer

To emulate a keypress to the Page up key in Puppeteer, use

await page.keyboard.press("PageUp");

To emulate a keypress to the Page down key in Puppeteer, use

await page.keyboard.press("PageDown");

 

Posted by Uli Köhler in Javascript, NodeJS, Puppeteer

How to run Nextcloud “php occ” in a docker-compose configuration

Use this command to run php occ inside a running docker Nextcloud container:

docker-compose exec -u www-data nextcloud php occ [command]

where:

  • nextcloud is the name of your container in docker-compose
  • -u www-data tells docker-compose to run the command as the www-data user that owns all the Nextcloud files.
  • Replace [command] by the php occ command you want to run, for example versions:cleanup. If you want to see a list of all available commands, just omit [command]

Note: You need to run this command in the directory where your nextcloud docker-compose.yml is located.

Example:

docker-compose exec -u www-data nextcloud php occ versions:cleanup

 
or:

docker-compose exec -u www-data nextcloud php occ trash:cleanup --all-users

 

Posted by Uli Köhler in PHP

mbed STM32 timer interrupt example

You can use the mbed Ticker API to add a timer interrupt to your mbed application. This example will use a Ticker-based timer interrupt to toggle the LED once per second, for example on the STM32F429I-DISCO board:

#include <mbed.h>

DigitalOut led1(LED1);
Ticker ticker;

/**
 * This function will be run once per second
 */
void timerTick() {
  // Toggle LED
  led1 = !led1;
}

int main() {
  ticker.attach(timerTick, 1.0 /* seconds */);

  // What you do in the main loop is not important
  while(1) {
  }
}

 

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

How to fix Raspberry Pi OpenVPN error “ERROR: Cannot open TUN/TAP dev /dev/net/tun: No such device (errno=19)”

Problem:

You want to setup OpenVPN on your Raspberry Pi but you see an error message like

Fri Jun 26 18:12:35 2020 ERROR: Cannot open TUN/TAP dev /dev/net/tun: No such device (errno=19)
Fri Jun 26 18:12:35 2020 Exiting due to fatal error

Solution:

This error occurs if you’ve installed OpenVPN using sudo apt install -y openvpn but if you didn’t reboot after installing it. In order to fix the issue, reboot using

sudo reboot

 

Posted by Uli Köhler in Linux, Raspberry Pi

How to create filename containing date/time in Python

In datalogging quiten often you have to create a new log file once you start to log data.

Often it’s convenient to include the current date and time in the log file.  In Python, this is pretty easy to do:

from datetime import datetime

filename = f"Temperature log-{datetime.now():%Y-%m-%d %H-%m-%d}.csv"

This will create filenames like

Temperature log 2020-06-17 22-37-41.csv
Temperature log 2019-12-31 00-15-55.csv

Note that if you use another Date/time format, you need to avoid special characters that must not occur in filenames. The rules for which filename is correct are much easier on Linux than on Windows, but since you should be compatible with both operating systems, you should always check the Windows rules.

These characters are forbidden for Windows filenames:

<>:"/\|?*

The date-time format we used above, %Y-%m-%d %H-%m-%d is specially crafted in order to avoid colons in ISO-8601-like date/time formats such as 2020-04-02 11:45:33 since colons would be illegal in Windows filenames (they would work in Linux filenames, though). %Y-%m-%d %H-%m-%d only contains spaces and dash (-) characters in order to avoid any issues with filename rules.

Posted by Uli Köhler in Python

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

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 create filename containing date/time in C#

In datalogging, often you have to create a new log file once you start to log data.

In most cases, it’s convenient to include the current date and time in the log file. Here’s how you can do that in C# without using external libraries:

string filename = String.Format("Temperature logging {0}.csv",
                                DateTime.UtcNow.ToString("yyyy-MM-dd HH-mm-ss"));

This will create filenames like

Temperature log 2020-06-17 22-37-41.csv
Temperature log 2019-12-31 00-15-55.csv

Note that if you use another Date/time format, you need to avoid special characters that must not occur in filenames. The rules for which filename is correct are much easier on Linux than on Windows, but since you should be compatible with both operating systems, you should always check the Windows rules.

These characters are forbidden for Windows filenames:

<>:"/\|?*

The date-time format we used above, yyyy-MM-dd HH-mm-ss is specially crafted in order to avoid colons in ISO-8601-like date/time formats such as 2020-04-02 11:45:33 since colons would be illegal in Windows filenames. yyyy-MM-dd HH-mm-ss only contains spaces and minus (-) characters in order to avoid any issues, now and in the future.

Posted by Uli Köhler in C#

How to fix C/C++ error: call of overloaded ‘abs(uint32_t)’ is ambiguous

Problem:

You are trying to compile a C/C++ program but you see an error message like

src\main.cpp:127:21: error: call of overloaded 'abs(uint32_t)' is ambiguous

that refers to a line like

long timedelta = abs(millis() - startTime);

Solution:

Cast the argument to abs() to int or another suitable type:

long timedelta = abs(((int)millis() - startTime));

That should fix the error.

The reason for the error message is that millis() and startTime are both unsigned integers (uint32_t), hence their difference (millis() - startTime) is also an uint32_t. However it makes no sense to compute the abs() of an unsigned integer since the absolute value of an absolute-value integer is  always the same as the input argument.

Then, the compiler tries to cast the uint32_t to any type that is compatible with abs(), like int, float, double, … but it doesn’t know which of those types is the correct one to cast it to.

By saying call of overloaded abs() the compiler is trying to tell you that there are multBiple argument types with which you can call abs(), including intfloat, double, … – a function with the same name but different argument types is called overloaded.

By saying is ambiguous, the compiler is telling you that it doesn’t know which of those variants of abs() it should call.

Note that the compiler does not know that all overloaded variants of abs() fundamentally do the same thing, so it won’t just cast your uint32_t into any arbitrary type. Also, there are tiny details in how the abs() variants work – for example, float abs(float) will do a different calculation compared to double abs(double) since it computes with 32-bit floating point numbers (float) as opposed to 64-bit floating point numbers (double).

Hence, the compiler can’t just assume that they are all the same and it doesn’t matter which one it calls, even though they represent the same underlying mathematical operation

Posted by Uli Köhler in C/C++, GCC errors

How to fix C/C++ round(): error: invalid operands of types ‘float’ and ‘int’ to binary ‘operator&’

Problem:

You are trying to compile a C/C++ program but you see an error message like

src\main.cpp:357:21: error: invalid operands of types 'float' and 'int' to binary 'operator&'

that refers to a line like

long m = round(v) & 0x7FF;

Solution:

The result of round() is a floating point number. You are trying to use the & operator to perform bitwise AND of a float and an int (0x7FF in the example above). However, you can not perform bitwise operation on floats in C/C++.

In order to fix this, case the result of round() to int:

long m = ((int)round(v)) & 0x7FF;

That should fix the compiler error.

 

Posted by Uli Köhler in C/C++, GCC errors

What .gitignore to use for LTSpice XVII projects?

Besides the .asc files containing the circuit to simulate, LTSpice XVII genates .log.raw and .op.raw files during simulation. Usually, you don’t want to commit those files.

This is the .gitignore file I use to manage my LTSpice XVII projects:

*.log
*.raw
Posted by Uli Köhler in Electronics