Uli Köhler

How to disable all DHCP servers on MikroTik using SSH / CLI

The following command will disable (but not delete) all DHCP servers on MikroTik routers:

/ip/dhcp-server/disable [ find ]

 

Posted by Uli Köhler in MikroTik

How to remove ALL firewall rules on MikroTik Router

You can remove all static firewall rules on a MikroTik router using

/ip/firewall/filter/remove [ find where !dynamic ]

This will delete all the rules and there will be no way to recover them!

 

Posted by Uli Köhler in MikroTik, Networking

How to read length-prefixed binary message from Serial using Arduino

The following function allows you to read a binary message, prefixed by a single length byte, from Serial:

#include <Arduino.h>

void setup() {
    Serial.begin(115200);
}

void HandleMessage(String msg) {
    // TODO: Your code to handle the message goes here.
    // See https://techoverflow.net/2022/11/15/how-to-print-string-as-sequence-of-hex-bytes-in-arduino/
    // for an example of how to print the message as a sequence of hex bytes.
}

void ReadMessageFromSerial() {
    // Wait until the length byte is available on Serial
    while (Serial.available() == 0);

    // Read the length of the message
    int length = Serial.read();

    // Read the rest of the message
    String message = "";
    for (int i = 0; i < length; i++) {
      while (Serial.available() == 0);
      message += char(Serial.read());
    }

    // Handle the message
    HandleMessage(message);
}

void loop() {
    ReadMessageFromSerial();
}

 

 

Posted by Uli Köhler in Allgemein, Arduino, Electronics, Embedded

Where to find cheap SMD microswitches?

The cheapest SMD (no THT soldering) switch

LCSC offers the SHOU HAN MSK12CO2-SZ microswitch for about 0,023€/pc @ 1kpc. One of the disadvantages of this switch is that even though it is a pure SMD (no through soldering required), it is shipping as bulk in a bag and not as tape. Therefore, it is not suitable for all commercial assembly lines and needs to be assembled manually.

But at least it is cheap – that is, if you buy enough stuff to justify the high LCSC shipping costs.

The KiCAD footprint for this switch is Button_Switch_SMD:SW_SPDT_PCM12. Even though it’s a different switch than the C&K PCM12, it’s mostly compatible footprint-wise – even though the drill sizes are very slightly off, the footprint works well.

This switch is likely rated to DC12V, 50mA (listed as such on the LCSC website). However, from the datasheet, the exact rating is unclear, it mostly covers the test conditions

The cheapest tape&reel SMD switch

If you are looking for an alternative suitable for automated assembly, take a look at the SK-3296S-01-L1 which comes as a taped reel. It is almost 35% more expensive but given that it’s still just 0,031€/pc @1kpc and given that you’re likely not a chinese electronics designer in extreme mass manufacturing, the price is hardly worth thinking about.

It is exactly compatible footprint-wise with the C&K PCM12, so the KiCAD Button_Switch_SMD:SW_SPDT_PCM12 works even better.

This switch is rated at DC12V, 50mA.

The cheapest 1 Ampere rated switch

This is the MK-13C03-G010 which is rated at 6V 1A or 12V 0.5A. This type of current rating with voltage is related to arcing when breaking the contact.

It is priced around 0,11€/pc @1kpc.

This one is compatible with the C&K PCM13 (but rated at higher current), so use the Button_Switch_SMD:SW_SPDT_PCM13

Posted by Uli Köhler in Components, Electronics

How to install fpm package builder on Ubuntu/Debian

Problem:

You want to build a package using the fpm command, but you see the following error message:

fpm: command not found

Solution:

First, install rubygems:

sudo apt -y install rubygems

and now install fpm using rubygems:

sudo gem install fpm

 

Posted by Uli Köhler in Linux

How to fix Linux error: Package ‘libjpeg8-dev’ has no installation candidate

Problem:

While trying to install libjpeg8-dev using apt or similar tools, you see the following error message:

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Package libjpeg8-dev is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  libjpeg62-turbo-dev:armhf libjpeg62-turbo-dev

E: Package 'libjpeg8-dev' has no installation candidate

Solution:

As you can see in the error message, the correct package name to install is now libjpeg62-turbo-dev. Therefore, install it using

sudo apt -y install libjpeg62-turbo-dev

 

Posted by Uli Köhler in Linux

How to fix KiCAD JLCPCB fabrication plugin error: The wx.App object must be created first!

Problem:

When running the JLCPCB fabrication plugin in KiCAD to export fabrication data, you see the following error message:

wx._core.PyNoAppError: The wx.App object must be created first!

Solution:

This appears to be a bug with current versions of the JLCPCB fabrication plugin, but you can easily fix it by adding a line to plugin.py, which is located here:

/home/uli/.local/share/kicad/6.0/3rdparty/plugins/com_github_bennymeg_JLC-Plugin-for-KiCad/plugin.py

(depending on the operating system, the kicad folder will be located elsewhere).

Find the following lines which are almost at the top of the file:

# WX GUI form that show the plugin progress
class KiCadToJLCForm(wx.Frame):
    def __init__(self):

and add the following line directly after def __init__(self):

        self.app = wx.PySimpleApp()

Result:

# WX GUI form that show the plugin progress
class KiCadToJLCForm(wx.Frame):
    def __init__(self):
        self.app = wx.PySimpleApp()

 

Posted by Uli Köhler in KiCAD

How to pair Bluetooth Gamepad / Game controller from Amazon

I bought a cheap game controller on Amazon:

However, from reading the manual it was completely unclear how to pair it with my laptop or my smartphone, so I figured it out myself.

How to pair the Gamepad

Press the button between the sticks and the button left of the touch pad. Press both buttons together for 5-10 seconds.

Press those buttons until the LED on the controller starts blinking with the following pattern: Blink-Blink-Pause ... Blink-Blink-Pause

If the LED on the back side doesn’t blink at all or just blinks shortly, charge the game controller using the microUSB port on the back side.

Once the LEDs blink wit the Blink-Blink-Pause pattern, the controller is ready to be paired. Open up the Bluetooth settings on your Laptop or Smartphone and connect to the gamepad.

Re-pairing the device

At least for my devices, I need to re-pair the device every time I restart the computer. In order to do this, remove the gamepad from the list of paired devices on your computer / smartphone. Then, bring the gamepad into pairing mode using the method described above and pair it again.

So far I couldn’t find a reliable method of keeping the device connected or paired, but re-pairing it on every use is sufficiently easy.

Posted by Uli Köhler in Hardware

How to find out which version of OpenWRT you are running

  1. Login to your OpenWRT router using SSH, e.g. using
    ssh [email protected]
  2. Print the content of /etc/openwrt_release:
    cat /etc/openwrt_release
  3. This will print, for example
    DISTRIB_ID='OpenWrt'
    DISTRIB_RELEASE='21.02.0'
    DISTRIB_REVISION='r16279-5cc0535800'
    DISTRIB_TARGET='ipq40xx/generic'
    DISTRIB_ARCH='arm_cortex-a7_neon-vfpv4'
    DISTRIB_DESCRIPTION='OpenWrt 21.02.0 r16279-5cc0535800'
    DISTRIB_TAINTS='no-all busybox'

As you can see in the DISTRIB_RELEASE line in the output, we’re running OpenWRT 21.02.0 on this router.

Posted by Uli Köhler in OpenWRT

OctoPrint systemd service file for autostarting OctoPrint

After you have installed OctoPrint using

sudo pip3 install OctoPrint

you can create /etc/systemd/system/octoprint.service with the following content (depending on your setup, you might need to replace the user & group pi by the name of the user that should run OctoPrint):

[Unit]
Description=octoprint

[Service]
ExecStart=/usr/local/bin/octoprint serve
WorkingDirectory=/data
Restart=always
User=pi
Group=pi

[Install]
WantedBy=multi-user.target

After creating the file, enable autostart & start the service using

sudo systemctl enable --now octoprint

 

Posted by Uli Köhler in 3D printing, systemd

What current rating do JST “XH” connectors have?

JST XH connector crimp contacts have a 3A current rating per contact (with 0.33mm² cables).

Source: JST website

Posted by Uli Köhler in Electronics

What are the part numbers for JST “XH” crimp contacts and where to buy them?

JST XH connector crimp contacts have the following part numbers:

  • SXH-001T-P0.6 (0.08…0.33mm²)
  • SXH-002T-P0.6 (0.05…0.13mm²)
  • SXH-001T-P0.6N (slighly different shape than the others, see datasheet, 0.13…0.33mm²)

Datasheet link

One source to buy them from is LCSC. They have high base shipping costs so if you just want to buy a couple of contacts, you should rather buy a crimp set on Aliexpress or Amazon, but in larger quantities it’s hard to beat LCSC.

Source: JST website

Posted by Uli Köhler in Electronics

How to fix ESP32 error: ‘ESP_LOGE’ was not declared in this scope

Problem:

When trying compile your ESP32 project, you see an error message such as

.pio/libdeps/esp32dev/HumanESPHTTP/src/QueryURLParser.cpp:29:9: error: 'ESP_LOGE' was not declared in this scope
         ESP_LOGE("Query URL parser", "parsing URL");
         ^~~~~~~~

Solution:

At the top of the file where the error occurs (QueryURLParser.cpp in this example), add the following line:

#include <esp_log.h>

 

 

Posted by Uli Köhler in C/C++, ESP8266/ESP32

How to actually turn off nginx logs entirely

If you’re using statements in your nginx config such as

access_log off;
error_log off;

this will not actually turn off the logging. it will just write the logs to /usr/share/nginx/off.

In order to actually turn off logging, use

access_log /dev/null;
error_log /dev/null;

 

Posted by Uli Köhler in nginx

How to delete logs from Gitlab Docker instance (Omnibus)

You can often save multiple gigabytes of space by deleting old logs from Gitlab instances. It should be clear that the logs will be lost forever once deleting them, so ensure that you don’t really care about your content before deleting this.

First, enter the logs directory, that is the directory mapped to /var/log/gitlab. This should be mapped out from your container to a local directory or volume. In our Gitlab reference config for docker-compose, we have mapped it to the logs directory.

In that directory, run the following commands:

find . \( -name "*.gz" -o -name "*.log* -o -name "*.s" -o -name "*.u" \) -exec rm -v {} \;

This will delete all files with the given extensions.

Posted by Uli Köhler in GitLab

How to iterate all IP addresses in network using Python

The following code will iterate over all IP addresses in the given network, i.e. 192.168.1.0 ... 192.168.1.254:

import ipaddress

network = ipaddress.ip_network('192.168.1.0/24')

for ip in network:
    print(ip)

The following variant will iterate over all IP addresses in this network except the broadcast IP address 192.168.1.255 and the network IP address 192.168.1.0:

import ipaddress

network = ipaddress.ip_network('192.168.1.0/24')

for ip in network:
    # Ignore e.g. 192.168.1.0 and 192.168.1.255
    if ip == network.broadcast_address or ip == network.network_address:
        continue
    print(ip)

 

Posted by Uli Köhler in Python

What is a DALI “control gear”?

Typically, one DALI control gear is just a lamp that can be controlled using DALI.

More generally, a control gear can also be a DALI device controlling more than one physical lamp or some similar device. However, if you’re a DALI beginner, it’s much easier to think of control gear as individual lamps controllable by DALI.

Posted by Uli Köhler in DALI

How to set DAPC level (dim level) directly using DALI

In order to directly set the power level for a given control gear (lamp) using DALI, you have to send the following two bytes:

  1. The short address of the control gear, multiplied by 2
  2. The data byte containing the power level (0...255).

In order to distinguish between command messages (frames) and DAPC (direct arc power control) messages, remember that the 1st bit must always be 0 for DAPC messages.

For example, if you want to set half brightness level for the lamp with short address 3, send the following bytes:

  • 6 (= 3 * 2)
  • 127 (= half brightness)
Posted by Uli Köhler in DALI

How to convert DALI short address to address byte

In order to convert the address byte for a single DALI control gear to an address byte to send over the wire, multiply the short address by 2  and add 1. The following C macro can be used to compute the address byte:

#define DALI_SHORT_ADDR_TO_ADDR_BYTE(short_addr) (1 + (short_addr << 1))

Since the 1st bit is set (by adding 1), this will activate command mode, i.e. the control gear expects a command byte as data byte for the DALI message.

Posted by Uli Köhler in DALI

How to fix pip fatal error: portaudio.h: No such file or directory

Problem:

While trying to install a package using pip, you see the following error message:

x86_64-linux-gnu-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -fPIC -I/usr/local/include -I/usr/include -I/usr/include/python3.10 -c src/pyaudio/device_api.c -o build/temp.linux-x86_64-3.10/src/pyaudio/device_api.o
src/pyaudio/device_api.c:9:10: fatal error: portaudio.h: No such file or directory
    9 | #include "portaudio.h"
      |          ^~~~~~~~~~~~~
compilation terminated.
error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1
[end of output]

Solution:

On Ubuntu, you need to install the portaudio19-dev package:

sudo apt -y install portaudio19-dev

 

Posted by Uli Köhler in Python