我用 C# 制作了一个数据记录应用程序。它通过 SerialPort 类连接到 4 个 USB 传感器。我在每个字节上触发了数据接收事件阈值。当接收到数据时,程序会检查该字节是否是行尾。如果不是,则将输入添加到缓冲区。如果是行尾,则程序添加时间戳并将数据和时间戳写入文件(每个输入源获得一个专用文件)。
使用多个 COM 端口输入时会出现问题。我在输出文件中看到的是:
4 个文件中的任何一个:
...
timestamp1 value1
timestamp2 value2
timestamp3 value3
value4
value5
value6
timestamp7 value7
...
因此,看起来计算机速度不够快,无法在下一个值到达之前到达所有 4 个中断。我有充分的理由相信这是罪魁祸首,因为有时我会看到这样的输出:
...
timestamp value
timestamp value
value
val
timestamp ue
timestamp value
...
这可能是因为我将处理器亲和性更改为仅在 Core 2 上运行。我这样做是因为我使用的时间戳是用处理器周期计算的,所以我不能有多个时间引用,具体取决于哪个核心是跑步。我在下面放了一些代码片段;任何可能有助于删除时间戳的建议将不胜感激!
public mainLoggerIO()
{
//bind to one cpu
Process proc = Process.GetCurrentProcess();
long AffinityMask = (long)proc.ProcessorAffinity;
AffinityMask &= 0x0002; //use only the 2nd processor
proc.ProcessorAffinity = (IntPtr)AffinityMask;
//prevent any other threads from using core 2
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
Thread.CurrentThread.Priority = ThreadPriority.Highest;
long frequency = Stopwatch.Frequency;
Console.WriteLine(" Timer frequency in ticks per second = {0}",
frequency);
long nanosecPerTick = (1000L * 1000L * 1000L) / frequency;
Console.WriteLine(" Timer is accurate within {0} nanoseconds",
nanosecPerTick);
if (Stopwatch.IsHighResolution)
MessageBox.Show("High Resolution Timer Available");
else
MessageBox.Show("No High Resolution Timer Available on this Machine");
InitializeComponent();
}
等等。每个数据返回中断如下所示:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
//serialPort1.DataReceived = serialPort1_DataReceived;
rawPort1Data = "";
rawPort1Data = serialPort1.ReadExisting();
this.Invoke((MethodInvoker)delegate { returnTextPort1(); });
}
方法 returnTextPort#() 是:
private void returnTextPort1()
{
if (string.Compare(saveFileName, "") == 0)//no savefile specified
return;
bufferedString += rawPort1Data;
if(bufferedString.Contains('\r')){
long timeStamp = DateTime.Now.Ticks;
textBox2.AppendText(nicknames[0] + " " + timeStamp / 10000 + ", " + rawPort1Data);
//write to file
using (System.IO.StreamWriter file = new System.IO.StreamWriter(@saveFileName, true))
{
file.WriteLine(nicknames[0] + " " + timeStamp / 10000 + ", " + rawPort1Data);//in Ms
}
bufferedString = "";
}
}