计算机和微控制器之间延迟最低的通信方法是什么?
What is the lowest latency communication method between a computer and a microcontroller?
我有一个项目,其中我需要尽可能低的延迟(最好在 1-100 微秒范围内)以便计算机之间的通信(Windows + Linux + MacOSX ) 和一个微控制器(arduino 或 stm32 或任何东西)。
我强调,不仅要快,而且要低延迟(例如,与月球的快速通信将具有低延迟)。
目前我尝试过的方法是通过 USB 串口或通过 USB 发送 HID 数据包。我得到的结果大约不到一毫秒。我的测量方法是往返通信,然后除以二。这没关系,但我会更高兴有更快的东西。
编辑:
这个问题似乎很难回答。我发现的最佳解决方法是同步计算机和微控制器的时钟。同步确实需要通信。通过下面的过程,dt
是半个往返,sync
是时钟之间的差异。
t = time()
write(ACK);
read(remotet)
dt = (time() - t) / 2
sync = time() - remotet - dt
请注意,此同步的不精确度最多为dt
。最快的通信渠道的重要性仍然存在,但我对精度有一个估计。
还要注意与不同系统上的时间戳差异相关的技术细节(us/ms 基于 Linux 上的纪元,ms/us 自 MCU 在 Arduino 上启动以来)。
注意Arduino上的时钟转换。经常同步更安全(在我的情况下是每一项措施)。
以太网
找一块有千兆以太网端口直接连接到微控制器的板子,然后用交叉线直接连接到PC。
简而言之,PC 无法处理这么短的截止日期。即使在 Intel Core 系列处理器上使用裸机 RTOS,您最终也会遇到 2-3 µS 范围内的中断延迟(处理器响应中断的速度)。 (参见 http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/industrial-solutions-real-time-performance-white-paper.pdf)
这忽略了任何类型的通信 link,如 USB 或以太网(或其他),需要打包数据、握手、缓冲以避免数据丢失等。
USB 堆栈会有延迟,无论 link 有多快,因为缓冲以避免数据丢失。与以太网相同。实际上,由于系统中发生的其他事情以及协议中对稳健性的需求,任何成熟的 OS 上的现代堆栈驱动程序都无法实现低延迟。
如果你的最后期限是个位数的微秒(甚至在毫秒范围内),你真的需要在微控制器上进行实时处理并处理较慢的控制 loop/visualization楼主。
要回答这个问题,有两种低延迟方法:
串口或并口。可以将延迟降低到毫秒级,但您的性能可能因制造商而异。 Brainboxes 是一个不错的品牌,尽管他们的卡片售价超过 100 美元!
自己写驱动。应该可以实现几百微秒的延迟,尽管如果内核需要提供更高优先级的服务,显然它可以中途中断您的进程。这就是许多科学设备实际工作的方式。 (很多人告诉你 PC 不能在短期限内工作是错误的)。
您无法保证延迟 到 userland without real time operating system. You're at the mercy of the kernel and it's slice time 和抢占规则。这可能高于您的最大值 100us。
为了让工作站响应硬件事件,您必须使用中断和设备驱动程序。
您的选项仅限于提供 IRQ:
的接口
- 硬件 serial/parallel 端口。
- PCI
- PCI 上的一些接口桥。
或者。如果你喜欢滥用 IO,声卡。
USB 不是其中之一,它具有 1kHz 的轮询率。
也许 Thunderbolt 可以,但我不确定。
USB 原始 HID 具有被破解的 8KHz 轮询率(125us 轮询间隔)与 Teensy 3.2(或更高版本)相结合。 Mouse overclockers have achieved 8KHz poll rate with low USB jitter, and Teensy 3.2 (Arduino clone) is able to do 8KHz poll rate with a slightly modified USB FTDI driverPC端
除此之外,您还需要更好的方法,您现在正在研究 PCI-Express 并行端口,通过数字引脚直接向并行端口上的引脚发送低延迟信号。它们必须是真正的并行端口,而不是通过 USB 层。千兆赫兹级 PC 上的 DOS 应用程序经过测试可获得低于 1us 的能力(1.4Ghz Pentium IV)并口引脚信号,但如果您编写虚拟设备驱动程序,您可能可以在 Windows 内获得低于 100us 的能力。
使用 wazoo 中提高的优先级和关键部分,最好是非垃圾收集语言,最少的后台应用程序,并且基本上在关键循环中消耗 100% 的 CPU 核心,并且您可以绝对可靠地达到 <100us。不是 100% 的时间,但肯定是在五个九的范围内(甚至可能比这好得多)。如果你能忍受这样的偏差。
有关信息,我只是 运行 在装有两个专用 PCIe 并行端口卡的 Windows 10 PC 上进行了一些测试。
使用 Python 代码(实际上使用 Psychopy Builder 和 Psychopy 编码器)发送 TTL(方波)脉冲,2 通道示波器显示 4us 到 8us 的两个脉冲之间的偏移非常一致。
这是 python 代码 运行 在 'above normal' 优先级的时候。
当 运行 在 正常优先级 时,除了偶尔出现 30us 的间隙外,它几乎是相同的,大概是在任务切换发生时)
我有一个项目,其中我需要尽可能低的延迟(最好在 1-100 微秒范围内)以便计算机之间的通信(Windows + Linux + MacOSX ) 和一个微控制器(arduino 或 stm32 或任何东西)。
我强调,不仅要快,而且要低延迟(例如,与月球的快速通信将具有低延迟)。
目前我尝试过的方法是通过 USB 串口或通过 USB 发送 HID 数据包。我得到的结果大约不到一毫秒。我的测量方法是往返通信,然后除以二。这没关系,但我会更高兴有更快的东西。
编辑:
这个问题似乎很难回答。我发现的最佳解决方法是同步计算机和微控制器的时钟。同步确实需要通信。通过下面的过程,dt
是半个往返,sync
是时钟之间的差异。
t = time()
write(ACK);
read(remotet)
dt = (time() - t) / 2
sync = time() - remotet - dt
请注意,此同步的不精确度最多为dt
。最快的通信渠道的重要性仍然存在,但我对精度有一个估计。
还要注意与不同系统上的时间戳差异相关的技术细节(us/ms 基于 Linux 上的纪元,ms/us 自 MCU 在 Arduino 上启动以来)。
注意Arduino上的时钟转换。经常同步更安全(在我的情况下是每一项措施)。
以太网
找一块有千兆以太网端口直接连接到微控制器的板子,然后用交叉线直接连接到PC。
简而言之,PC 无法处理这么短的截止日期。即使在 Intel Core 系列处理器上使用裸机 RTOS,您最终也会遇到 2-3 µS 范围内的中断延迟(处理器响应中断的速度)。 (参见 http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/industrial-solutions-real-time-performance-white-paper.pdf)
这忽略了任何类型的通信 link,如 USB 或以太网(或其他),需要打包数据、握手、缓冲以避免数据丢失等。
USB 堆栈会有延迟,无论 link 有多快,因为缓冲以避免数据丢失。与以太网相同。实际上,由于系统中发生的其他事情以及协议中对稳健性的需求,任何成熟的 OS 上的现代堆栈驱动程序都无法实现低延迟。
如果你的最后期限是个位数的微秒(甚至在毫秒范围内),你真的需要在微控制器上进行实时处理并处理较慢的控制 loop/visualization楼主。
要回答这个问题,有两种低延迟方法:
串口或并口。可以将延迟降低到毫秒级,但您的性能可能因制造商而异。 Brainboxes 是一个不错的品牌,尽管他们的卡片售价超过 100 美元!
自己写驱动。应该可以实现几百微秒的延迟,尽管如果内核需要提供更高优先级的服务,显然它可以中途中断您的进程。这就是许多科学设备实际工作的方式。 (很多人告诉你 PC 不能在短期限内工作是错误的)。
您无法保证延迟 到 userland without real time operating system. You're at the mercy of the kernel and it's slice time 和抢占规则。这可能高于您的最大值 100us。
为了让工作站响应硬件事件,您必须使用中断和设备驱动程序。 您的选项仅限于提供 IRQ:
的接口- 硬件 serial/parallel 端口。
- PCI
- PCI 上的一些接口桥。
或者。如果你喜欢滥用 IO,声卡。
USB 不是其中之一,它具有 1kHz 的轮询率。 也许 Thunderbolt 可以,但我不确定。
USB 原始 HID 具有被破解的 8KHz 轮询率(125us 轮询间隔)与 Teensy 3.2(或更高版本)相结合。 Mouse overclockers have achieved 8KHz poll rate with low USB jitter, and Teensy 3.2 (Arduino clone) is able to do 8KHz poll rate with a slightly modified USB FTDI driverPC端
除此之外,您还需要更好的方法,您现在正在研究 PCI-Express 并行端口,通过数字引脚直接向并行端口上的引脚发送低延迟信号。它们必须是真正的并行端口,而不是通过 USB 层。千兆赫兹级 PC 上的 DOS 应用程序经过测试可获得低于 1us 的能力(1.4Ghz Pentium IV)并口引脚信号,但如果您编写虚拟设备驱动程序,您可能可以在 Windows 内获得低于 100us 的能力。
使用 wazoo 中提高的优先级和关键部分,最好是非垃圾收集语言,最少的后台应用程序,并且基本上在关键循环中消耗 100% 的 CPU 核心,并且您可以绝对可靠地达到 <100us。不是 100% 的时间,但肯定是在五个九的范围内(甚至可能比这好得多)。如果你能忍受这样的偏差。
有关信息,我只是 运行 在装有两个专用 PCIe 并行端口卡的 Windows 10 PC 上进行了一些测试。
使用 Python 代码(实际上使用 Psychopy Builder 和 Psychopy 编码器)发送 TTL(方波)脉冲,2 通道示波器显示 4us 到 8us 的两个脉冲之间的偏移非常一致。
这是 python 代码 运行 在 'above normal' 优先级的时候。 当 运行 在 正常优先级 时,除了偶尔出现 30us 的间隙外,它几乎是相同的,大概是在任务切换发生时)