How to set Linux hardware clock to a specific date

hwclock --set --date '2021-01-04 13:04:00'

 

Posted by Uli Köhler in Linux

Systemd service to use a DS3231 RTC on the Raspberry Pi

The following systemd service will automatically. See this guide for more information on the setup and ensure sudo i2cdetect -y 1 detects the RTC with address 0x68.

This is an automatic service installation & enable script based on A simple systemd service autoinstall script . This script will automatically enable the service on boot:

#!/bin/bash
# This script installs and enables/starts a systemd service
# It also installs the service file
export NAME=ConfigureRTC

cat >/etc/systemd/system/${NAME}.service <<EOF
[Unit]
Description=${NAME}

[Service]
ExecStart=/bin/bash -c 'echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device && hwclock -s'
Restart=always

[Install]
WantedBy=multi-user.target
EOF

# Enable and start service
systemctl enable --now ${NAME}.service

This is just the systemd service:

[Unit]
Description=ConfigureRTC

[Service]
ExecStart=/bin/bash -c 'echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device && hwclock -s'
Restart=always

[Install]
WantedBy=multi-user.target

 

Posted by Uli Köhler in Linux, Raspberry Pi

How to enable or disable NTP time synchronization on the Raspberry Pi

Disable NTP:

sudo systemctl disable --now systemd-timesyncd

Enable NTP:

sudo systemctl enable --now systemd-timesyncd

Verifying if NTP is active

You can verify if NTP is active or not by running

timedatectl

Then look for these lines:

System clock synchronized: yes
NTP service: active

System clock synchronized will tell you if the NTP service has successfully synchronized the system time to a NTP time server: yes if synchronized, no if not synchronized.

NTP service will tell you if the NTP service is running, i.e. if it is trying to synchronize the system time to a NTP time server: active if running, inactive when not running

Output with NTP active:

               Local time: Tue 2023-03-14 16:49:28 CET
           Universal time: Tue 2023-03-14 15:49:28 UTC
                 RTC time: Tue 2023-03-14 15:49:28
                Time zone: Europe/Berlin (CET, +0100)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

Output with NTP inactive:

               Local time: Tue 2023-03-14 16:48:01 CET
           Universal time: Tue 2023-03-14 15:48:01 UTC
                 RTC time: Tue 2023-03-14 15:48:01
                Time zone: Europe/Berlin (CET, +0100)
System clock synchronized: no
              NTP service: inactive
          RTC in local TZ: no

 

Posted by Uli Köhler in Linux, Raspberry Pi

How to enable I2C port on the Raspberry Pi using raspi-config

sudo raspi-config nonint do_i2c 0

Now load the relevant modules:

sudo modprobe "i2c-bcm2835"
sudo modprobe "i2c-dev"
sudo modprobe "rtc-ds1307"

and now check if the I2C device file exists using stat /dev/i2c-1:

$ stat /dev/i2c-1
  File: /dev/i2c-1
  Size: 0               Blocks: 0          IO Block: 4096   character special file
Device: 5h/5d   Inode: 169         Links: 1     Device type: 59,1
Access: (0660/crw-rw----)  Uid: (    0/    root)   Gid: (  998/     i2c)
Access: 2023-03-14 16:23:06.643999999 +0100
Modify: 2023-03-14 16:23:06.643999999 +0100
Change: 2023-03-14 16:23:06.643999999 +0100
 Birth: -

If you instead see

ls: cannot access '/dev/i2c-1': No such file or directory

either the driver is not loaded properly or I2C is disabled. Try rebooting the system and repeating the commands above and possibly checking dmesg for any error messages.

Posted by Uli Köhler in Raspberry Pi

How to automatically add module to /etc/modules if it doesn’t exist

#!/bin/bash
check_module() {
  local module="$1"
  if grep -Fxq "$module" /etc/modules
  then
    echo "$module already exists in /etc/modules"
  else
    echo "$module not found in /etc/modules. Adding it now..."
    echo "$module" | sudo tee -a /etc/modules
  fi
}

check_module "i2c-dev"

This script will at the module if it doesn’t exist in /etc/modules yet.

Note that it will only detect if exactly the same line as the argument to check_module is already present in /etc/modules. For example if i2c-dev option1=value1 is in /etc/modules, the script will only detect this line correctly if you call it like

check_module "i2c-dev option1=value1"

but not if you call it like

check_module "i2c-dev"

 

 

 

Posted by Uli Köhler in Linux

How to fix Raspberry Pi i2cdetect: command not found

Problem:

When trying to detect I2C devices on the Raspberry Pi (Raspbian) using i2cdetect, you see the following error:

$ i2cdetect
bash: i2cdetect: command not found

Solution:

Install i2c-tools using

sudo apt -y install i2c-tools

After installing i2c-tools , you can use i2cdetect and other related tools such as i2cget.

Posted by Uli Köhler in Embedded, Linux, Raspberry Pi

How to fix NodeJS Error: EXDEV: cross-device link not permitted, rename …

Problem:

While trying to rename a file using fs.move() in NodeJS, you see an error message such as

Error: EXDEV: cross-device link not permitted, rename '/tmp/upload_8a8c71784abf9942b40c1359935b1997' -> 'myfile.pdf'

Solution:

This error occurs because you are moving a file from one drive (/tmp in our example above) to another drive (the current directory in our example above). On most platforms, this can’t be done using a simple rename operation.

Instead, fs.copyFile() the file.

For example, instead of

await fs.move('/tmp/upload_8a8c71784abf9942b40c1359935b1997', 'myfile.pdf')

first, copy the file:

await fs.copyFile('/tmp/upload_8a8c71784abf9942b40c1359935b1997', 'myfile.pdf')

and then – if desired – remove the source file to mirror the behaviour of os.move() as closely as possible.

await fs.remove('/tmp/upload_8a8c71784abf9942b40c1359935b1997', 'myfile.pdf')
await fs.unlink('/tmp/upload_8a8c71784abf9942b40c1359935b1997')

 

Posted by Uli Köhler in NodeJS

How to get filesize in NodeJS / TypeScript using Promisese

First, import stat from the NodeJS standard library:

import { stat } from "node:fs/promises";

Async-await style

// Async-await style:
const statResult = await stat("myfile.pdf");
const fileSizeInBytes = statResult.size;

Promise.then() style

stat("myfile.pdf").then(statResult => {
    const fileSizeInBytes = statResult.size;
    // TODO your code goes here
});

 

Posted by Uli Köhler in NodeJS, Typescript

How to format axis as dB (decibel) using matplotlib

In our previous post Matplotlib custom SI-prefix unit tick formatter we showed how to format a matplotlib Y axis with a custom unit with SI prefixes.

Similarly, we can use UliEngineering.Math.Decibel in order to format plots (most notably plots with a logarithmic Y axis) as decibels:

from UliEngineering.Math.Decibel import *
import matplotlib.ticker as mtick

def decibel_formatter(v0=1.0, unit='dB'):
    def format_value(value, pos=None):
        dB = value_to_dB(value, v0=v0)
        return f'{dB:.0f} {unit}'
    return format_value

# Usage example:
plt.gca().set_yscale("log") # Optional

plt.gca().yaxis.set_major_formatter(mtick.FuncFormatter(decibel_formatter()))

 

Posted by Uli Köhler in Python

How to get footprint graphical elements using KiCAD pcbnew plugin Python API

See our previous post How to get list of all footprints using KiCAD pcbnew plugin Python API and How to get all selected footprints using KiCAD pcbnew plugin Python API for more info on how to obtain a footprint object.

Once you have a pcbnew.FOOTPRINT object, you can get its graphical elements (which are basically the lines, rectangles, circles etc in the footprint – but not any silkscreen labels) using

footprint.GraphicalElements()

Example:

for graphical_element in footprint.GraphicalItems():   
    print(graphical_element)

Output:

<pcbnew.FP_TEXT; proxy of <Swig Object of type 'FP_TEXT *' at 0x7fc47f2c41e0> >
<pcbnew.FP_SHAPE; proxy of <Swig Object of type 'FP_SHAPE *' at 0x7fc47f0f10b0> >
<pcbnew.FP_SHAPE; proxy of <Swig Object of type 'FP_SHAPE *' at 0x7fc47f2c69d0> >
<pcbnew.FP_SHAPE; proxy of <Swig Object of type 'FP_SHAPE *' at 0x7fc47f2c6d30> >
<pcbnew.FP_SHAPE; proxy of <Swig Object of type 'FP_SHAPE *' at 0x7fc47f0f10e0> >
<pcbnew.FP_SHAPE; proxy of <Swig Object of type 'FP_SHAPE *' at 0x7fc47f2c6cd0> >
<pcbnew.FP_SHAPE; proxy of <Swig Object of type 'FP_SHAPE *' at 0x7fc47f2c6ca0> >
<pcbnew.FP_SHAPE; proxy of <Swig Object of type 'FP_SHAPE *' at 0x7fc47f0f38d0> >
<pcbnew.FP_SHAPE; proxy of <Swig Object of type 'FP_SHAPE *' at 0x7fc47f2c68b0> >
<pcbnew.FP_SHAPE; proxy of <Swig Object of type 'FP_SHAPE *' at 0x7fc47f2c41e0> >
<pcbnew.FP_SHAPE; proxy of <Swig Object of type 'FP_SHAPE *' at 0x7fc47f0f10b0> >
<pcbnew.FP_SHAPE; proxy of <Swig Object of type 'FP_SHAPE *' at 0x7fc47f2c69d0> >
<pcbnew.FP_SHAPE; proxy of <Swig Object of type 'FP_SHAPE *' at 0x7fc47f2c6d30> >

You can filter them using

fp_texts: list[pcbnew.FP_TEXT] = [
    item for footprint in selected_footprint.GraphicalItems()
    if type(item).__name__ == 'FP_TEXT'
]
fp_shapes: list[pcbnew.FP_SHAPE] = [
    item for footprint in selected_footprint.GraphicalItems()
    if type(item).__name__ == 'FP_SHAPE'
]

 

Posted by Uli Köhler in Electronics, KiCAD

How to get all selected footprints using KiCAD pcbnew plugin Python API

In our previous post, we showed how to get all selected objects using the KiCAD python API using

pcbnew.GetCurrentSelection()

You can simply filter these entries to obtain just a list of selected footprints using either a for loop with inline filtering:

for selected_object in pcbnew.GetCurrentSelection():
    if type(selected_object).__name__ == 'FOOTPRINT':
        print(selected_object.GetReference())

or using a list comprehension:

selected_footprints: list[pcbnew.FOOTPRINT] = [
    footprint for footprint in pcbnew.GetCurrentSelection() if type(footprint).__name__ == 'FOOTPRINT'
]

Complete plugin example:

#!/usr/bin/env python
import pcbnew
import os

class SimplePlugin(pcbnew.ActionPlugin):
    def defaults(self):
        self.name = "Plugin Name as shown in Pcbnew: Tools->External Plugins"
        self.category = "A descriptive category name"
        self.description = "A description of the plugin and what it does"
        self.show_toolbar_button = False # Optional, defaults to False
        self.icon_file_name = os.path.join(os.path.dirname(__file__), 'simple_plugin.png') # Optional, defaults to ""

    def Run(self):
        board: pcbnew.BOARD = pcbnew.GetBoard()
        footprints: list[pcbnew.FOOTPRINT] = board.GetFootprints()
        
        # TODO Do something useful with [board]
        for selected_object in pcbnew.GetCurrentSelection():
            print(selected_object)

SimplePlugin().register() # Instantiate and register to Pcbnew

Example output (excerpt):

D39
D32
D23
D37
D18
D34
D11
D15

 

Posted by Uli Köhler in Electronics, KiCAD

How to get all selected objects using KiCAD pcbnew plugin Python API

When you have a FOOTPRINT object or a list of footprints in KiCAD’s Python API such as from board.GetFootprints(), you can get their reference designators such as C11 or R4 using

pcbnew.GetCurrentSelection():

Not that not only footprints might be selected but also other objects such as shapes, vias, pads etc.

Complete plugin example:

#!/usr/bin/env python
import pcbnew
import os

class SimplePlugin(pcbnew.ActionPlugin):
    def defaults(self):
        self.name = "Plugin Name as shown in Pcbnew: Tools->External Plugins"
        self.category = "A descriptive category name"
        self.description = "A description of the plugin and what it does"
        self.show_toolbar_button = False # Optional, defaults to False
        self.icon_file_name = os.path.join(os.path.dirname(__file__), 'simple_plugin.png') # Optional, defaults to ""

    def Run(self):
        board: pcbnew.BOARD = pcbnew.GetBoard()
        footprints: list[pcbnew.FOOTPRINT] = board.GetFootprints()
        
        for selected_object in pcbnew.GetCurrentSelection():
            # TODO Do something useful with selected_object
            print(selected_object)

SimplePlugin().register() # Instantiate and register to Pcbnew

Example output (excerpt):

<pcbnew.PCB_VIA; proxy of <Swig Object of type 'PCB_VIA *' at 0x7fc49d2a8b70> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8de0> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8c30> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8b40> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8db0> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8c00> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8ba0> >
<pcbnew.PCB_VIA; proxy of <Swig Object of type 'PCB_VIA *' at 0x7fc49d2a8e10> >
<pcbnew.PCB_VIA; proxy of <Swig Object of type 'PCB_VIA *' at 0x7fc49d2a8bd0> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8b70> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8de0> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8c30> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8b40> >
<pcbnew.FOOTPRINT; proxy of <Swig Object of type 'std::deque< FOOTPRINT * >::value_type' at 0x7fc49d2a8db0> >
<pcbnew.FOOTPRINT; proxy of <Swig Object of type 'std::deque< FOOTPRINT * >::value_type' at 0x7fc49d2a8c00> >
<pcbnew.FOOTPRINT; proxy of <Swig Object of type 'std::deque< FOOTPRINT * >::value_type' at 0x7fc49d2a8ba0> >
<pcbnew.PCB_VIA; proxy of <Swig Object of type 'PCB_VIA *' at 0x7fc49d2a8e10> >
<pcbnew.PCB_VIA; proxy of <Swig Object of type 'PCB_VIA *' at 0x7fc49d2a8bd0> >
<pcbnew.FOOTPRINT; proxy of <Swig Object of type 'std::deque< FOOTPRINT * >::value_type' at 0x7fc49d2a8b70> >
<pcbnew.FOOTPRINT; proxy of <Swig Object of type 'std::deque< FOOTPRINT * >::value_type' at 0x7fc49d2a8de0> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8c30> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8b40> >
<pcbnew.FOOTPRINT; proxy of <Swig Object of type 'std::deque< FOOTPRINT * >::value_type' at 0x7fc49d2a8db0> >
<pcbnew.PCB_VIA; proxy of <Swig Object of type 'PCB_VIA *' at 0x7fc49d2a8c00> >
<pcbnew.FOOTPRINT; proxy of <Swig Object of type 'std::deque< FOOTPRINT * >::value_type' at 0x7fc49d2a8ba0> >
<pcbnew.FOOTPRINT; proxy of <Swig Object of type 'std::deque< FOOTPRINT * >::value_type' at 0x7fc49d2a8e10> >
<pcbnew.FOOTPRINT; proxy of <Swig Object of type 'std::deque< FOOTPRINT * >::value_type' at 0x7fc49d2a8bd0> >
<pcbnew.FOOTPRINT; proxy of <Swig Object of type 'std::deque< FOOTPRINT * >::value_type' at 0x7fc49d2a8b70> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8de0> >
<pcbnew.FOOTPRINT; proxy of <Swig Object of type 'std::deque< FOOTPRINT * >::value_type' at 0x7fc49d2a8c30> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8b40> >
<pcbnew.PCB_VIA; proxy of <Swig Object of type 'PCB_VIA *' at 0x7fc49d2a8db0> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8c00> >
<pcbnew.PCB_TRACK; proxy of <Swig Object of type 'PCB_TRACK *' at 0x7fc49d2a8ba0> >
<pcbnew.FOOTPRINT; proxy of <Swig Object of type 'std::deque< FOOTPRINT * >::value_type' at 0x7fc49d2a8e10> >
<pcbnew.FOOTPRINT; proxy of <Swig Object of type 'std::deque< FOOTPRINT * >::value_type' at 0x7fc49d2a8bd0> >
<pcbnew.PCB_VIA; proxy of <Swig Object of type 'PCB_VIA *' at 0x7fc49d2a8b70> >

 

 

 

Posted by Uli Köhler in Electronics, KiCAD

How to get list footprint Reference Designators KiCAD pcbnew plugin Python API

When you have a FOOTPRINT object or a list of footprints in KiCAD’s Python API such as from board.GetFootprints(), you can get their reference designators such as C11 or R4 using

footprint.GetReference()

Complete plugin example:

#!/usr/bin/env python
import pcbnew
import os

class SimplePlugin(pcbnew.ActionPlugin):
    def defaults(self):
        self.name = "Plugin Name as shown in Pcbnew: Tools->External Plugins"
        self.category = "A descriptive category name"
        self.description = "A description of the plugin and what it does"
        self.show_toolbar_button = False # Optional, defaults to False
        self.icon_file_name = os.path.join(os.path.dirname(__file__), 'simple_plugin.png') # Optional, defaults to ""

    def Run(self):
        board: pcbnew.BOARD = pcbnew.GetBoard()
        footprints: list[pcbnew.FOOTPRINT] = board.GetFootprints()
        
        # TODO Do something useful with [board]
        for footprint in footprints:
            print(footprint.GetReference())

SimplePlugin().register() # Instantiate and register to Pcbnew

 

 

Posted by Uli Köhler in Electronics, KiCAD

How to get list of all footprints using KiCAD pcbnew plugin Python API

When using KiCAD’s Python API for pcbnew, you can obtain a list of FOOTPRINTobjects using

board: pcbnew.BOARD = pcbnew.GetBoard()
footprints: list[pcbnew.FOOTPRINT] = board.GetFootprints()

The : pcbnew.BOARD and : list[pcbnew.FOOTPRINT] are optional but will tell your editor (such as visual studio code) which object to expect for better autocompletion.

Complete plugin example:

#!/usr/bin/env python
import pcbnew
import os

class SimplePlugin(pcbnew.ActionPlugin):
    def defaults(self):
        self.name = "Plugin Name as shown in Pcbnew: Tools->External Plugins"
        self.category = "A descriptive category name"
        self.description = "A description of the plugin and what it does"
        self.show_toolbar_button = False # Optional, defaults to False
        self.icon_file_name = os.path.join(os.path.dirname(__file__), 'simple_plugin.png') # Optional, defaults to ""

    def Run(self):
        board: pcbnew.BOARD = pcbnew.GetBoard()
        footprints: list[pcbnew.FOOTPRINT] = board.GetFootprints()
        
        # TODO Do something useful with [board]
        for footprint in footprints:
            print(footprint)

SimplePlugin().register() # Instantiate and register to Pcbnew

 

 

Posted by Uli Köhler in Electronics, KiCAD

How to get board object using KiCAD pcbnew plugin Python API

When using KiCAD’s Python API for pcbnew, you can simply get a board object using pcbnew.GetBoard():

board: pcbnew.BOARD = pcbnew.GetBoard()

The : pcbnew.BOARD is optional but will tell your editor (such as visual studio code) which object to expect for better autocompletion.

Complete plugin example:

#!/usr/bin/env python
import pcbnew
import os

class SimplePlugin(pcbnew.ActionPlugin):
    def defaults(self):
        self.name = "Plugin Name as shown in Pcbnew: Tools->External Plugins"
        self.category = "A descriptive category name"
        self.description = "A description of the plugin and what it does"
        self.show_toolbar_button = False # Optional, defaults to False
        self.icon_file_name = os.path.join(os.path.dirname(__file__), 'simple_plugin.png') # Optional, defaults to ""

    def Run(self):
        board: pcbnew.BOARD = pcbnew.GetBoard()
        # TODO Do something useful with [board]
        print(board)

SimplePlugin().register() # Instantiate and register to Pcbnew

 

Posted by Uli Köhler in Electronics, KiCAD

ESP-IDF HTTP webserver minimal ArduinoJson serialization example

static const httpd_uri_t valueHandler = {
    .uri       = "/api/value",
    .method    = HTTP_GET,
    .handler   = [](httpd_req_t *req) {
        httpd_resp_set_type(req, "application/json");
        // create json docuemnt
        DynamicJsonDocument json(1024);
        json["value"] = 1.0;
        // Serialize JSON to string
        std::string buf;
        serializeJson(json, buf);
        // Send response
        httpd_resp_send(req, buf.c_str(), buf.length());
        return ESP_OK;
    }
};

In order to add the ArduinoJson to PlatformIO, add the following lib_deps to platformio.ini:

lib_deps =
    [email protected]

 

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

How to list all V4L cameras using v4l2-ctl

You can list all connected cameras using

v4l2-ctl --list-devices

Example output:

bcm2835-codec-decode (platform:bcm2835-codec):
        /dev/video10
        /dev/video11
        /dev/video12
        /dev/video18
        /dev/video31
        /dev/media0

bcm2835-isp (platform:bcm2835-isp):
        /dev/video13
        /dev/video14
        /dev/video15
        /dev/video16
        /dev/video20
        /dev/video21
        /dev/video22
        /dev/video23
        /dev/media2
        /dev/media3

rpivid (platform:rpivid):
        /dev/video19
        /dev/media1

HD USB Camera: HD USB Camera (usb-0000:01:00.0-1.2):
        /dev/video0
        /dev/video1
        /dev/media4

 

Posted by Uli Köhler in Audio/Video, Linux

How to fix VirtualHere USB client ./vhuit64 ERROR: could not insert ‘vhci_hcd’: Operation not permitted

Problem:

When trying to run the VirtualHere USB client on Linux, you see the following error message:

$ ./vhuit64 
Please run with sudo
modprobe: ERROR: could not insert 'vhci_hcd': Operation not permitted

Solution:

Simply run vhuit64 using sudo:

sudo ./vhuit64

 

Posted by Uli Köhler in Linux

How to fix erpc ValueError: The generated shim code version … is different to the rest of eRPC code

Problem:

When trying to import your erpc project generated Python code using e.g.

from erpc_myproject import *

You see the following error message:

Traceback (most recent call last)
Cell In [1], line 1
----> 1 from erpc_myproject import *

File ./erpc_myproject/__init__.py:13
     11     version = "unknown"
     12 if version != "1.9.1":
---> 13     raise ValueError("The generated shim code version (1.9.1) is different to the rest of eRPC code (%s). \
     14 Install newer version by running \"python setup.py install\" in folder erpc/erpc_python/." % repr(version))
     16 from . import common
     17 from . import client

ValueError: The generated shim code version (1.9.1) is different to the rest of eRPC code ('unknown'). Install newer version by running "python setup.py install" in folder erpc/erpc_python/.

Solution:

Either you have not installed the erpc Python library (if the error message lists ... different to the rest of eRPC code ('unknown')) or you have installed the wrong version (e.g. ... (1.9.1) is different to the rest of eRPC code ('1.10.0')).

If you have not installed erpc at all, simply use

pip install erpc

and retry running your script.

If you have installed the wrong version, you have two options:

Option 1 (preferred): Re-generate the code

Just use the original command (some erpcgen call) you’ve used to re-generate the code using the currently installed version.

Option 2: Install the correct version

For this, you need to determine what the correct version is. Let’s consider the following error message:

ValueError: The generated shim code version (1.9.1) is different to the rest of eRPC code ('1.10.0'). Install newer version by running "python setup.py install" in folder erpc/erpc_python/.

From this message, we can read that the shim code version is 1.9.1 whereas you have 1.10.0 installed. Therefore, in order to make it work, we need to install erpc version 1.9.1.

Install it using

pip install -U erpc==1.9.1

and then retry your command. If you are using jupyter notebooks or similar, you need to restart your kernel to load the new library!

Posted by Uli Köhler in Embedded, Python
This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Cookie settingsACCEPTPrivacy &amp; Cookies Policy