Hardware time sync through uart

Hello i am working on a project where i want to time sync a khadas vim 4 with a livox lidar mid 40 and a xsens mti 670 dk .

i am using ubuntu 22.04.5 LTS
and ROS2 env.

For the time sync between khadas vim 4 and livox lidar i follow the livox instructions (https://livox-wiki-en.readthedocs.io/en/latest/tutorials/new_product/common/time_sync.html#appendix-how-to-configure-the-ptp-master-clock

and run hardware time sync using ptp with time diffs like these

image

for time sync between khadas and xsens i have to use the uart. so the wiring i make is

khadas pin16 → xsens pin9
khadas pin9 → xsens pin2

so i runb the following code to send a pulse to xsens and check their time diff.

import serial
import time
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import TimeReference  # Correct message type

class TimeDiffMonitor(Node):

    def __init__(self):
        super().__init__('time_diff_monitor')
        # Subscribe to the correct Xsens time topic
        self.subscriber = self.create_subscription(TimeReference, '/imu/utctime', self.xsens_callback, 10)
        self.xsens_time = None

    def xsens_callback(self, msg):
        # Extract Xsens timestamp from message
        self.xsens_time = msg.time_ref.sec + msg.time_ref.nanosec / 1e9
        self.get_logger().info(f"Xsens timestamp: {self.xsens_time}")

    def get_xsens_time(self):
        return self.xsens_time

def send_sync_pulse(ser):
    sync_signal = b'SYNC'  # Create a sync pulse signal
    ser.write(sync_signal)  # Send the sync pulse through Pin 16 (TX)
    khadas_time = time.time()  # Capture Khadas system time
    print(f"Sync pulse sent at {khadas_time}")
    return khadas_time

def main(args=None):
    # Initialize ROS2 node for Xsens time monitoring
    rclpy.init(args=args)
    time_diff_monitor = TimeDiffMonitor()

    # Open UART port for sync pulses
    uart_port = '/dev/ttyS4'  # Pin 16 TX on Khadas VIM4
    baud_rate = 921600
    ser = serial.Serial(uart_port, baud_rate)

    try:
        while rclpy.ok():
            # Send sync pulse and get Khadas time
            khadas_time = send_sync_pulse(ser)

            # Spin ROS2 to process Xsens messages
            rclpy.spin_once(time_diff_monitor, timeout_sec=0.1)

            # Get the latest Xsens time
            xsens_time = time_diff_monitor.get_xsens_time()

            if xsens_time is not None:
                # Calculate and print time difference
                time_diff = abs(khadas_time - xsens_time)
                print(f"Time difference between Khadas and Xsens: {time_diff} seconds")
            else:
                print("Waiting for Xsens time...")

            time.sleep(0.1)  # For 10 Hz sync pulses
    except KeyboardInterrupt:
        ser.close()
        rclpy.shutdown()

if __name__ == '__main__':
    main()

khadas@Khadas:~/ws-livox$ python3 send_timesync2xsens.py 
Sync pulse sent at 1728767114.6118355
[INFO] [1728767114.724037827] [time_diff_monitor]: Xsens timestamp: 1728767114.5764368
Time difference between Khadas and Xsens: 0.03539872169494629 seconds
Sync pulse sent at 1728767114.8247092
[INFO] [1728767114.827760909] [time_diff_monitor]: Xsens timestamp: 1728767114.7464366
Time difference between Khadas and Xsens: 0.07827258110046387 seconds
Sync pulse sent at 1728767114.9284568
[INFO] [1728767114.932868393] [time_diff_monitor]: Xsens timestamp: 1728767114.848616
Time difference between Khadas and Xsens: 0.07984089851379395 seconds

but time diff is big. so this has to do with low latency in uart or what?

Please correct me and help me to solve it.

Any help would be appreciated.

Thanks in advance.

Are you sure it actually has hardware PTP, I have not seen that in the specs. Oddly we have a project what we are trying to find hardware with PTP(hardware not software) and USB3 with spi and i2c. So far I have not found much.

hello @foxsquirrel ,

the image below shows that the ethernet (at least) supports hardware PTP.

image

or esle should show something like that

also livox lidar when power up its clock starts from the 0. So if it didnt get the time sync the time diff would be huge, but as you can see its some milliseconds.

My problem is how to send an accurate time sync from khadas to xsens (using uart) to have an accurate time diff like with livox so at the end livox and xsens time diff be under 5 milliseconds for example so i have accurate neasuremnents.

Not sure if UART and timestamp is practical unless you are running slow. Frame and parse will add latency. We are streaming sensor data over Ethernet and must have hardware time stamp so all the sensors can sync on the master. If you do use Ethernet set up its own network, squirting data out of that will choke your “working network”.

I would use c++ 20 and thread the uart and thread chrono for the timestamp. It might come down to what is an acceptable loss of data. Pretty sure that will work out. It will be hard to implement in python, you could do the critical parts in c++ and the not critical timing in python.

2 Likes

Hello @Manolis_Chrysanidis

No idea about this, but maybe you can try to setup the cpu governor to performance and check again?

echo performance | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
echo performance | sudo tee /sys/devices/system/cpu/cpufreq/policy4/scaling_governor