USB转串口 模拟 PPS+GPRMC 进行授时

article/2025/10/16 5:30:57

把 PC的系统时间 通过USB转串口发出来 来模拟 PPS+GPRMC 授时, 这大冷天的, 用来在室内测试MCU或者SOC的授时功能, 传感器的授时与线束检测, 测试干扰等等, 还是比较合适的.

如下图, 左边为 USB转9针RS232串口, 右边为 USB转TTL串口

在这里插入图片描述

原理:

  • PPS 有 3V3 / 5V / 12V 等规格, 这里用串口芯片的RTS引脚来模拟PPS(DTR引脚也可以), 左边RS232的DB9口中虽然也有RTS引脚, 但是实测是±9V, 所以用右边的USB转TTL芯片的3.3V的RTS来代替
  • GPRMC 是RS232 电平, 直接用左边DB9中的PIN3–TXD引脚发出来就可以了
  • 图左都是RS232电平, 图右都是TTL电平, 所以才用了两个来混搭, 如果自己打板子用一个USB转串口芯片+RS232芯片就够了

Python3 的脚本1.py如下(Win下为 COM*, Ubuntu下为/dev/ttyUSB*, 需要先安装pyserial和nmeasim)

#!/usr/bin/python3# python3 -m pip install pyserial
# python3 -m pip install nmeasimfrom nmeasim.models import GpsReceiver
from threading import Timer
from datetime import datetime
import serialttl_ser   = serial.Serial('COM7')	# 右边板子的串口号, 用到RTS或者DTR引脚, 模拟PPS
rs232_ser = serial.Serial(port="COM14", baudrate=9600)	# 左边板子的串口号, 用到TXD, 9600波特率, 模拟GPRMCgps = GpsReceiver(output=('RMC',))	# 单GPRMC输出
# https://gitlab.com/nmeasim/nmeasim/-/blob/master/nmeasim/models.py
# output=("GGA", "GLL", "GSA", "GSV", "RMC", "VTG", "ZDA")def pps_high():ttl_ser.setRTS(False)	# -9V, 3.3V, PPS输出高, 如果用DTR引脚就setDTRdef pps_low():ttl_ser.setRTS(True)	# 9V, 0V, PPS输出低def pps_init():# print('pps_init')pps_low()	# 初始低电平def gprmc_out():gps.date_time = datetime.now()	# 获取电脑的系统时间gps.__lat_sign = 'N'	# GPRMC中的一些信息, 只要时间的话下面这些参数可以不用设置gps.lat = 39.1234gps.__lon_sign  = 'N'gps.lon = 116.5678gps.__mag_sign = 'E'gps.mag_var = 4.1gps.kph = 1.0gps.heading = 1.0rs232_ser.write(gps.get_output()[0].encode('utf-8') + b'\r\n')	# 发出GPRMC信息, 结尾加上\r\n# print(gps.get_output()[0].encode('utf-8'))# ts = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]# print('gprmc_out :', ts, ts[-3:])# print()def pps_out():pps_high()ts = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]	# 精确到msprint(ts)Timer(1 - int(ts[-3:])/1000, pps_out).start()	# 每次都进行补偿Timer(0.02, pps_init).start()   # PPS高电平持续时间20ms, 示波器实测约32msTimer(0.10, gprmc_out).start()  # PPS上升沿后100ms, 发出GPRMCpps_init()
pps_out()

运行python3 1.py, 环境为 Win10, i7-8086K, 测试时间为 2021年12月30日, 北京时间减去8小时就是下面GPRMC中的时间

在这里插入图片描述

换算成十六进制, 结尾一定要有0x0D, 0x0A, 如果没有, 以Velodyne的激光雷达VLP-16为例, 即便网页可能有之前的GPS Position信息, 但是Wireshark里面抓到的512字节的数据包只会显示PPS Locked, 却没有GPRMC信息

在这里插入图片描述

左边为PPS发出的时间戳, 加上8小时刚好是北京时间, 精度在4ms以内, 通用测试还是可以的

PPS波形(CP2104芯片, PPS高电平持续时间, 示波器实测脉宽比设置的20ms多出12ms, 不过PPS用的上升沿, 这个应该影响不大)

在这里插入图片描述

两个脉冲上升沿的间隔 1s

在这里插入图片描述

上升沿有点惨不忍睹 快1ms了, 这带来的PPS误差又多了1ms, 把9600bps改成115200bps也没有改善, 换成CH340或者空载差别也不大, 如果用MCU来模拟可能会好一点, 或者加个74芯片

在这里插入图片描述

如果只是单纯授时, 脚本中不要定位信息也是可以的, 如下

def gprmc_out():gps.date_time = datetime.now()rs232_ser.write(gps.get_output()[0].encode('utf-8') + b'\r\n')# $GPRMC,024941.113,A,0000.000,N,00000.000,E,0.0,0.0,301221,,,A*64
# $GPRMC,024942.119,A,0000.000,N,00000.000,E,0.0,0.0,301221,,,A*6D
# $GPRMC,024943.114,A,0000.000,N,00000.000,E,0.0,0.0,301221,,,A*61
# $GPRMC,024944.113,A,0000.000,N,00000.000,E,0.0,0.0,301221,,,A*61
# $GPRMC,024945.119,A,0000.000,N,00000.000,E,0.0,0.0,301221,,,A*6A

用VLP-16做个测试, 首先看下VLP-16用户手册中时间同步的要求:

  • PPS + 每秒一次的NMEA V2.3 GPRMC 或 GPGGA
  • PPS是固定的, 后面的NMEA 可以通过 串口 或者 以太网口 发送, 以太网口需要通过 TCP/UDP/广播 发送 NMEA 消息 到 10110 端口, 这里就不考虑了, 以下GPRMC只指通过串口 RS232电平 发出来的信息
  • PPS和GPRMC在高电平要能提供至少2mA的电流, 可能是为了抗干扰, 加了类似光耦的装置? 想要一根线挂很多激光雷达可能不太行
  • PPS是TTL电平, 3.3V/5V, 脉宽10us-200ms, 下面程序里设置成20ms
  • GPRMC是RS232电平, 9600bps, 格式可以是 HHMMSS, HHMMSS.s, HHMMSS.ss, 或 HHMMSS.sss(上面程序用的这个), 结尾要有0x0D, 0x0A, 也就是\r\n 或者叫 <CR><LF>, 时序要求见下图, 下面程序里设置成PPS上升沿100ms后发出

在这里插入图片描述

一开始网页界面重叠, 还以为是雷达坏了

在这里插入图片描述

其实是浏览器的字体设置成特大了, 改成推荐的中就正常了(相信有遇到同样情况的)

在这里插入图片描述

没有 PPS+GPRMC 授时的时候显示

在这里插入图片描述

发出PPS+GPRMC后, 网页显示锁定

在这里插入图片描述

Wireshark也能抓到GPRMC的包

在这里插入图片描述

00f4位置的02代表PPS Locked, 测试完成.

在这里插入图片描述

欢迎扫描二维码关注本人微信公众号, 及时获取最新文章:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/cYT7sVas.shtml

相关文章

GPC规范-SCP02

SPC02 流程 SPC02 指令 命令&#xff1a; 响应&#xff1a; 举例回复&#xff1a; 密钥分散数据&#xff1a; 0000FFFFFFFFFFFFFFFF Key Info&#xff1a; 20 02&#xff08;scp02&#xff09; Card挑战数&#xff1a; 001AC6619BE83082 Card加密值&#xff1a; 7…

STM32模拟GPS输出PPS、GPRMC与VLP16时钟同步

这里写目录标题 1.VLP16与GPS相关的管脚&#xff1a;2.利用GPS信息完成时间同步 TimeSynchronization3.查找同步关系4.修改ROS代码结论 1.VLP16与GPS相关的管脚&#xff1a; GPS-RECEIVE 接收GPS的GPRMC语句&#xff0c;注意是RS232电平(high 3-15V&#xff0c;low 1.2V以下)&…

c++处理GPRMC

#include <iostream> #include<string> #include<vector>// A::member 表示A成员中的member // namespace my_vary202234610229 namespace是c的关键字&#xff0c;将变量定义在自己创建的my_vary命名空间 // 访问命名空间中的变量需要作用域分解符 // 命名空…

gPRC基本介绍

1.说明 gRPC英文全名为Google Remote Procedure Call&#xff0c; 即Google远程过程调用&#xff0c; 是Google发布的一个高性能、通用的开源RPC框架&#xff0c; 2.gRPC定义 gRPC是一个现代的开源高性能RPC框架&#xff0c; 可以在任何环境中运行。 它可以高效地连接数据中心内…

自动驾驶时间同步分析概述--PPS/GPRMC/PTP/全域架构时间同步方案

时间同步的重要性在生活中已经充分体现。试想你因一个姑娘在酒吧和别人大打出手&#xff0c;并约定下周六早上九点在后海小树林里进行群体活动。为此你微信召集了在南非、印度、泰国干建筑的好兄弟。可在你如期赴约的时候&#xff0c;发现队友只有河畔的孤影。当你在病床上睁开…

U-BLOX GPS 模块及GPRMC指令解析

受朋友所托&#xff0c;调试一款GPS模块&#xff0c;该模块是UBLOX的NEO-6M GPS模组。想到用这款GPS的人较多&#xff0c;自己日后也有可能在用到这个模块&#xff0c;就写下这份笔记。 一、介绍 基本信息如下&#xff1a; 1、 模块采用U-BLOX NEO-6M模组&#xff0c;体积小巧&…

ROS节点解析GPS数据:GPRMC/GPFDP/HEADINGA

数据解析&#xff0c;肯定是要知道数据格式的&#xff1a; 数据格式参考&#xff1a;&#xff08;前人已经总结的比较齐全了&#xff09; https://blog.csdn.net/u010384390/article/details/78432016?ops_request_misc%257B%2522request%255Fid%2522%253A%2522163031225416…

python各种模块,迭代器,生成器

从逻辑上组织python代码&#xff08;变量&#xff0c;函数&#xff0c;类&#xff0c;逻辑&#xff1a;实现一个功能&#xff09; 本质就是.py结尾的python文件(文件名&#xff1a;test.py,对应的模块名就是test) 包&#xff1a;用来从逻辑上组织模块的,本质就是一个目录&#…

VFS - 虚拟文件系统的加载和导出

VFS - 代码生成器预览功能实现VFS - 虚拟文件系统基本操作方法的封装VFS - 虚拟文件系统的加载和导出 这是 VFS 的最后一篇&#xff0c;前面两篇中的基本方法已经实现了一个简单的虚拟文件系统&#xff0c;可以创建目录和文件&#xff0c;可以读写文件的内容。在这最后一篇中&a…

如何优雅的使用javascript递归画一棵结构树

递归和尾递归 简单的说&#xff0c;递归就是函数自己调用自己&#xff0c;它作为一种算法在程序设计语言中广泛应用。其核心思想是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。一般来说&#xff0c;递归需要有边界条件、递归前进阶段和递归返回阶段…

python数据结构和算法 时间复杂度分析 乱序单词检测 线性数据结构 栈stack 字符匹配 表达式求值 queue队列 链表 递归 动态规划 排序和搜索 树 图

python数据结构和算法 参考 本文github 计算机科学是解决问题的研究。计算机科学使用抽象作为表示过程和数据的工具。抽象的数据类型允许程序员通过隐藏数据的细节来管理问题领域的复杂性。Python是一种强大但易于使用的面向对象语言。列表、元组和字符串都是用Python有序集合…

黑马毕向东Java课程笔记(day20-1——20-17)IO流:File类及相关方法、递归、递归的相关练习、Properties、PrintWriter类与PrintStream类、合并流与切割流

1、File类概述   File是文件和目录路径名的抽象表示形式。 用来将文件或者文件夹封装成对象&#xff0c;方便对文件与文件夹的属性信息进行操作。   前面说到的“流”&#xff0c;它只能操作数据&#xff0c;想要操作由数据封装成的文件的信息&#xff0c;必须使用File对象…

算法: 如何优雅的使用javascript递归画一棵结构树

递归和尾递归 简单的说&#xff0c;递归就是函数自己调用自己&#xff0c;它做为一种算法在程序设计语言中广泛应用。其核心思想是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。一般来说&#xff0c;递归需要有边界条件、递归前进阶段和递归返回阶段…

day04函数名 闭包 迭代器 生成器(各种推导式和生成器表达式) 内置函数 装饰器 递归...

一.今日内容概 1. 函数本质就是一个内存地址. 用起来和变量一模一样 2. 闭包 内层函数对外层变量的使用 1. 保护变量 2. 让一个变量常驻内存 3. 迭代器 可迭代对象: __iter__ 迭代器: __iter__ __next__ from collecti…

linux 迭代列出文件,讲解在Linux命令行下使用ls命令列出文件的技巧

Linux ls 命令可以说是在 Linux 中常见到的命令之一&#xff0c;因为使用它可以掌握系统中文件所在目录中的内容&#xff0c;从而能够查看与修改文件&#xff0c;如果你正在使用 Linux ls 命令&#xff0c;不妨看一下以下技巧&#xff0c;它能帮助你更快速的完成任务。 ls 命令…

学习递归的另一种方法

每个学期&#xff0c;我都会通过一项调查&#xff0c;以获取有关我的教学的一些反馈。 上学期终于有人给我写一篇新文章的想法。 特别是&#xff0c;他们想了解有关递归的更多信息&#xff0c;所以我认为我会综合一些技巧。 递归概述 对于那些可能是第一次学习递归的人&#x…

用非递归方法实现递归算法时_学习递归的另一种方法

用非递归方法实现递归算法时 每个学期&#xff0c;我都会通过一项调查&#xff0c;以获取有关我的教学的一些反馈。 上学期终于有人给我写一篇新文章的想法。 特别是&#xff0c;他们想了解有关递归的更多信息&#xff0c;所以我认为我会综合一些技巧。 递归概述 对于那些可能…

bat 文件夹移动

echo off echo hello world ::得到当天 set pathLog%date:~0,4%%date:~5,2%%date:~8,2% :: eg:能得到 秒:set pathLog%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2% :: set pathLog%pathLog: 0% ::创建文件夹 md "d:\log\log%pathLog% ec…

【Python零基础入门篇 · 19】:os模块、可迭代对象和迭代器对象

目录 一、os模块 1、os模块中的命令&#xff1a; 2、常用命令的代码演示 os.getcwd() os.chdir(path) os.listdir(path) os.mkdir(path) os.makedirs(path) os.rename(旧名,新名) 3、举例&#xff1a;查找文件夹下所有满足要求的文件 二、可迭代对象和迭代器对象 1、…

day18:File(构造方法、创建、删除文件或者文件夹、 判断性、重命名与剪切、得到性、过滤性)、递归(遍历文件夹文件)

一 回顾 1.HashMap集合 特点: A.数据结构也是Hash表结构 B.多线程中是不安全 C.默认的数组的初始化容量是16 2.HashMap与HashSet的比较 相同点:都是hash表结构来存储 不同点: A.HashSet的底层就是使用HashMap来实现 B.HashSet的数据结构针对与是元素 HashMap的…