来自串行的 100 Hz 数据

Posted

技术标签:

【中文标题】来自串行的 100 Hz 数据【英文标题】:100 Hz Data From Serial 【发布时间】:2012-02-16 16:22:32 【问题描述】:

我有一个传感器,它使用 RS422 通过串行发送消息。 (我认为这是正确的术语。)无论如何,我做了我的线束,并将它连接到我的 rs422 到 USB 转换器和 tada,我在超级终端中获得了数据。好东西。

现在传感器的波特率为奇数,1500kbps。我在 Windows 中这样做,所以实际上设置波特率并不难。最初,在通电时,传感器每 10hz 发送一条 69 字节的消息。我看到这条消息,读取了正确的字节,并且消息非常准确(它包括一个等待它的时间戳,每条消息增加 0.1 秒!)最重要的是,我在其边界上收到消息,换句话说,每次阅读都是一条新信息。

无论如何,到目前为止一切都很好,所以我采取了下一步,我通过串行端口发送了一个写命令,以激活传感器数据消息。该消息大小为 76 字节,以 100hz 的频率发送出去。再次成功,更多数据开始出现在读取中。但是,我在 100hz 时没有得到它,我得到了 3968 字节的块。如果我降低缓冲区,我会得到三个非常非常非常快速的 1024 读取,然后立即读取 896。(又是 3968 字节)。 (请注意,我现在收到两条消息,一条为 10 赫兹,大小为 69,另一条为 100 赫兹,大小为 76,请注意,这两条消息的组合没有均分 3968。)

我的问题是,某处正在缓冲我的 100hz 消息,而我在收到它们时没有收到它们。我想改变它,但我不知道我在寻找什么。我不需要它的边界上的 100hz 消息,我只是不希望它在 2 Hz。我会对 30hz 甚至 20hz 感到满意。


下面是我的串行端口设置代码:

端口开放

 serial_port_ = CreateFile(L"COM6", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

CommState 和超时

 COMMTIMEOUTS comm_timeouts;
 ZeroMemory(&comm_timeouts, sizeof(COMMTIMEOUTS));
 //comm_timeouts.ReadIntervalTimeout = MAXDWORD; //Instant Read, still get 3968 chunks
 comm_timeouts.ReadIntervalTimeout = 1; //1ms timeout
 comm_timeouts.ReadTotalTimeoutConstant = 1000; //Derp?
 comm_timeouts.WriteTotalTimeoutConstant = 5000; //Derp.
 SetCommTimeouts(serial_port_, &comm_timeouts);

 DCB dcb_configuration;
 ZeroMemory(&dcb_configuration, sizeof(DCB));
 dcb_configuration.DCBlength = sizeof(dcb_configuration);
 dcb_configuration.BaudRate = 1500000;
 dcb_configuration.ByteSize = 8;
 dcb_configuration.StopBits = ONESTOPBIT;
 dcb_configuration.Parity = ODDPARITY;
 if(!SetCommState(serial_port_, &dcb_configuration))

我的阅读

 if(!ReadFile(serial_port_, read_buffer_, 1024, &bytes_read, NULL))

【问题讨论】:

【参考方案1】:

我怀疑你的串口->usb 转换器来做缓冲。由于 USB 是基于数据包的,它需要做一些缓冲。在 10Hz 的速率下,可能有足够大的延迟,以在每条消息后刷新缓冲区。但是在 100Hz 时,消息已经传到了这么远,它正在通过其他逻辑刷新缓冲区。

这有意义吗?

【讨论】:

确实如此,我也是这么认为的。但是,我是串行端口编程的新手,所以我还不想做出这样的假设。如果这是真的,我该如何绕过它?有没有办法为串口设置系统缓冲区? api 调用可能会影响串行转换器驱动程序,是否有 windows api 调用来设置通信缓冲区?我的意思是,我们知道转换器能够达到 10HZ,至少让我们明白这一点。不是 2 赫兹 我看过一次(类似的应用程序)。可以在ftdichip.com/Support/Documents/AppNotes/… 第 3.1 节中找到关于 USB 转换器功能的一个很好的解释。该文件适用于 FTDI FT232,但我认为其他文件的工作方式类似。 (还有其他有用的应用笔记)如果您使用的是 FT232 设备,您可以设置此延迟计时器。我相信它也可以在 Windows 中完成,但我从未尝试过。对于 Linux,您可以使用 intra2net.com/en/developer/libftdi/documentation/… 在 FT232 设备的 windows 中找到它,它位于 AN_107 高级驱动程序选项中:ftdichip.com/Support/Documents/AppNotes/… 我认为我的实际上是FTDI芯片,但我不知道是哪种。我想不通。它的型号是 UTS-M14,一个 4 端口 USB 转换器。我能找到的唯一一个支持 > 1500 kbps 嘿,所以我的驱动程序让我从设备管理器中更改那些,我将超时形式从 16 毫秒调整为 8 毫秒,现在就像一个魅力。感谢您的文档,请回答,以便我可以为其他人接受!

以上是关于来自串行的 100 Hz 数据的主要内容,如果未能解决你的问题,请参考以下文章

在Processing中保存串行数据

通过 QSerialPort 访问来自 Arduino 的串行数据时遇到问题

问题:关闭端口后,python 仍然读取来自 arduino 的串行数据。串口无法关闭

关于ORACLE的串行化隔离级别--来自ORACLE概念手册

使用来自 arduino 串行打印的数据更新 matlab 中的线图,为啥会出现“数组形状错误”错误?

使用 Python 最大化来自 Teensy 3.2 的实时绘图数据的串行通信速度