我正在从一个连接到编码器的串行端口(美国数字S5光学轴编码器和QSB)读取每个数据条目时需要精确时间(ms)的项目。串行端口数据精确时间戳
我把编码器安装在一个小推车上,我用它来计算购物车的速度。
这里是我做过什么至今:
命令连接到串行端口,并写入QSB告诉编码器流数据。这里可用的命令:
www.usdigital.com/assets/general/QSB%20Commands%20List_1.pdf www.usdigital.com/assets/general/QSB%20Applications%20Examples.pdf
使用输入行()来读取收到的数据。
- 将所有数据行放入一个StringBuilder并输出到一个文件。
当我将输出值阈值和间隔速率设置为尽可能快时,我能够在1ms之间获得数据条目。 这里是我的了:
----time stamp(h/m/s/ms)-------value
与正确的时间标记数据:https://www.dropbox.com/s/pvo1dz56my4o99y/Capture1.JPG
不过,也有突然的“跳跃”,大约200毫秒时的数据是连续的(我滚在恒定速度车)
数据不正确的时间戳:https://www.dropbox.com/s/sz3sxwv4qwsb2cn/Capture2.JPG
这里是我的代码:
private void buttonOpenEncoderPort_Click(object sender, EventArgs e)
{
serialPortEncoder.Write("S0E\r\n");//start streaming data
System.Threading.Thread.Sleep(500);
serialPortEncoder.Write("W0B0\r\n");//set threshold to 0 so the encoder will stream data a the interval I set.
System.Threading.Thread.Sleep(500);
serialPortEncoder.Write("W0C0000\r\n");//set output interval to 0 so it will stream as fast as possible
System.Threading.Thread.Sleep(1500);
backgroundWorkerEncoder.RunWorkerAsync();}
//I am using a background worker to pull data out.
private void backgroundWorkerEncoder_DoWork(object sender, DoWorkEventArgs e)
{
while (serialPortEncoder.IsOpen)
{
if (serialPortEncoder.BytesToRead != 0)
{
try
{
String s = serialPortEncoder.ReadLine();//read from encoder
LazerBucket.Add(getCurrentTimeWithMS(timeEncoder) + "-----" + s + "\r\n");//put one line of data with time stamp in a List<String>
richTextBoxEncoderData.BeginInvoke(new MethodInvoker(delegate()
{
richTextBoxEncoderData.Text = s; })); //update UI
}
catch (Exception ex) { MessageBox.Show(ex.ToString()); }
}
}
}
private String getCurrentTimeWithMS(DateTime d)//to get time
{
StringBuilder s = new StringBuilder();
d = DateTime.Now;
int hour = d.Hour;
int minute = d.Minute;
int second = d.Second;
int ms = d.Millisecond;
s.Append(" ----" + hour.ToString() + ":" + minute.ToString() + ":" + second.ToString() + ":" + ms.ToString());
return s.ToString();
}
如果有人能找到时间跳跃的原因,我会认真对待它。 200ms是太多不容忽视的。
EDIT:
至于建议,我试图Stopwatch
但还是有200ms的延迟。但是,当我将时间戳和BytesToRead打印在一起时,我发现缓冲区中的数据随着readLine()的执行而减少。最终BytesToRead将下降到单个数字,这就是延迟发生的地方。我正在寻找更好的解决方案来实现线程。还有延迟的解释。也许我读得很快,所以缓冲区跟不上我?
EDIT:
问题解决了。请参阅下面的答案。感谢您的回复。秒表确实有帮助。现在我正在试图确定事件驱动还是轮询更好。
当您不将它作为后台任务运行时会发生什么?这可以排除主板引起的混乱现象 – lboshuizen
通过串口使用正交解码器是非常非常可疑的。当你在垃圾回收器顶部的线程池调度算法之上包含Windows线程调度延迟时,它肯定不会变好。你的系统设计简直不合适。 –
@lboshuizen感谢您的回复。如果我使用数据接收事件来收集数据,那么我在一秒钟内获得的数据就显着不足。 – Timtianyang