Set the frame interval for the NEO-M8L

Goal

Using a Python script, it should be possible to change the position update interval of a NEO-M8L GNSS module from 1 Hz to 10 Hz. This allows the location to be updated not just once per second, but up to 10 times per second.

Prerequisites

  • NetModule Wireless Router with wireless connection
  • NetModule Software 5.0.0.104 or newer
  • Not available for legacy products NB1600, NB2700, NB3700, NB3710

The wiki was tested with router software 5.0.0.104


1. Set up the LXC Contianer

Activate the LXC container on the router

In the second step, the image of the LXC container in this case, a Debina 13 (trixie).

The easiest way to do this is to install the whole thing over the Internet. However, the router requires a mobile connection to the Internet.

From a Jenkins server you get the current image for the container

* Jenkins Server Page image-debian / Link

Here you can download a Debian image for various systems and versions.

The armhf tab is important here, and trixie

The image is the “rootfs.tar.xz” which is required. With a right click you can copy the link.

It would be structured like this:

https://jenkins.linuxcontainers.org/view/Images/job/image-debian/architecture=armhf,release=trixie,variant=default/4118/artifact/rootfs.tar.xz

When the “Apply” button is pressed, Debian will be installed.

Set up the LXC container further. A network interface is enabled here.

The container has now also been assigned an IP address.

USER
~ $ lxc-info guest0 Name: guest0 State: RUNNING PID: 2255 IP: 192.168.1.149 CPU use: 1.57 seconds BlkIO use: 4.00 KiB Memory use: 6.29 MiB KMem use: 1.18 MiB Link: virt0 TX bytes: 2.28 KiB RX bytes: 853 bytes Total bytes: 3.11 KiB ~ $

Always assign a fixed IP address for the LXC container via the DHCP server. The MAC address of the LXC container is 00:FF:AA:00:44:00.

Log in to the LXC container and test whether it can access the Internet.

USER
~ $ lxc-attach guest0 root@LXCNAME:~# ping quad9.net PING quad9.net (195.176.255.138) 56(84) bytes of data. 64 bytes from 195.176.255.138 (195.176.255.138): icmp_seq=1 ttl=51 time=37.0 ms 64 bytes from 195.176.255.138 (195.176.255.138): icmp_seq=2 ttl=51 time=40.9 ms

— quad9.net ping statistics — 2 packets transmitted, 2 received, 0% packet loss, time 3006ms rtt min/avg/max/mdev = 28.823/36.685/40.937/4.768 ms root@LXCNAME:~#

The container is installed and set up. Now you can set up further tools on the container.


Customize the LXC configuration

Adjust the LXC configuration so that the /dev/ttyUSB1 interface is available within the container.

USER
~ $ ls -l /dev/tty* crw-rw-rw- 1 root root 5, 0 Sep 30 09:17 /dev/tty crw——- 1 root root 166, 0 Sep 28 17:55 /dev/ttyACM0 crw——- 1 root root 166, 1 Sep 28 17:55 /dev/ttyACM1 crw——- 1 root root 166, 2 Sep 28 17:55 /dev/ttyACM2 crw——- 1 root root 166, 3 Sep 28 17:55 /dev/ttyACM3 crw——- 1 root root 249, 0 Sep 28 17:55 /dev/ttyNull0 crw——- 1 root root 4, 64 Sep 28 17:55 /dev/ttyS0 crw——- 1 root root 4, 65 Sep 28 17:55 /dev/ttyS1 crw——- 1 root root 188, 1 Sep 29 17:26 /dev/ttyUSB1 crw——- 1 root root 188, 2 Sep 29 17:32 /dev/ttyUSB2 crw——- 1 root root 188, 3 Sep 29 17:32 /dev/ttyUSB3 crw——- 1 root root 188, 4 Sep 29 17:32 /dev/ttyUSB4 crw——- 1 root root 188, 5 Sep 29 17:32 /dev/ttyUSB5 crw——- 1 root root 188, 6 Sep 29 17:32 /dev/ttyUSB6 ~ $

The entry /dev/ttyUSB1 is important; this interface gives us access to the GNSS module.

This change is made directly in the router software. When updating the router software, this entry must be made again because it is not part of the official software.

Add these entries to the end of the config file.

~ $ vi /etc/lxc/guest0/config
                                                           
# Setting up a USB flash drive in the LXC container 
lxc.cgroup.devices.allow = c 188:1 rwm
lxc.mount.entry = /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file 0 0   

2. Make additional settings in the container

USER
~ $ lxc-attach guest0 root@LXCNAME:~# apt install gpsd python3-gpsapt gpsd-clients python3-paramiko nano root@LXCNAME:~#

The next step is to perform a basic test of access to the GNSS module.

USER
~ $ lxc-attach guest0 root@LXCNAME:~# cgps -s 192.168.1.1:2947 root@LXCNAME:~# cgps: WARNING gpsd server release 3.23.1, expected 3.25, API: 3.14 root@LXCNAME:~#

The GNSS data is then clearly displayed in the console using a Python plotting tool.

To configure the frame interval, you'll need Python programs and a library.

Create a subfolder for the whole thing

USER
root@LXCNAME:~# mkdir ubx_neo_m8l root@LXCNAME:~# cd ubx_neo_m8l root@LXCNAME:~# ls -l root@LXCNAME:~/ubx_neo_m8l/# ls -l -rwxr-xr-x 1 root root 1055 Sep 29 13:37 set_cfg_rate_neom8l.py -rwxr-xr-x 1 root root 2642 Sep 29 15:21 ssh_start.py drw-r–r– 3 root root 4096 Sep 29 13:33 ubxlib root@LXCNAME:~/ubx_neo_m8l/

The script set_cfg_rate_neom8l.py can be downloaded via the View Code link, and the ubxlib can be downloaded from the link using the password.

show code

* Program library ubxlib for the Python script / Link

The password for downloading the library : gnss_cfg_rate

The ssh_start.py script can be downloaded via the “show code” link.

show code

To enable SSH access, an SSH key pair must be generated within the container.

USER
root@LXCNAME:~# ssh-keygen -t rsa -b 2048 -f /root/.ssh/id_rsa -N “” root@LXCNAME:~# cat /root/.ssh/id_rsa.pub root@LXCNAME:~# ssh-rsa AAAAB3NzaC1yc2EAAAAD- … root@LXCNAME root@LXCNAME:~#

The file id_rsa.pub must then be added to the router under SSH Authorization.

Once all of this has been completed, you can run the Python script ssh_start.py, and the frame interval will be set in the GNSS module.

python3 ssh_start.py 10
# The Python script is called this way. 
# Values from 1 to 10 can be passed as arguments.

USER
root@LXCNAME:~/ubx_neo_m8l# python3 ssh_start.py 10 Setze gpsd.1.status=0 … Versuch 1/2: call set_cfg_rate_neom8l.py on… STDOUT: STDERR: 2026-09-30 10:39:20,427 INFO instantiating GnssUBlox on tty 2026-09-30 10:39:20,428 INFO using device /dev/ttyUSB1 Traceback (most recent call last): serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?) root@LXCNAME:~/ubx_neo_m8l#

Then test the whole thing with a get script.

USER
root@LXCNAME:~/ubx_neo_m8l# python3 get_cfg_rate_neom8l.py 2026-09-30 11:53:44,917 INFO instantiating GnssUBlox on tty 2026-09-30 11:53:44,917 INFO using device /dev/ttyUSB1 UBX-CFG-RATE cls:06 id:08

measRate: 100
navRate: 1
timeRef: 0

root@LXCNAME:~/ubx_neo_m8l#


3. Additional information

Download the set_cfg_rate_neom8l.py python script:

show code


Download the ssh_start.py python script:

show code


Download the library ubxlib:

Program library ubxlib for the Python script / Link

The password for downloading the library : gnss_cfg_rate


Download the get_cfg_rate_neom8l.py python script:

show code