1

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 = "";
        }

    }
4

1 に答える 1