解決
「port.ReadByte」によるデータ バイト単位の読み取りは遅すぎます。問題は SerialPort クラス内にあります。「port.Read」を介してより大きなチャンクを読み取るように変更しましたが、バッファオーバーランはなくなりました。
私は自分で解決策を見つけましたが、それを書き留めておくと助けになりました。おそらく他の誰かが同じ問題を抱えており、Google経由でこれを見つけています...
(どうすれば回答済みとしてマークできますか?)
編集2
設定することにより
port.ReadBufferSize = 2000000;
問題を 30 秒ほど遅らせることができます。どうやら、.Net は本当に遅すぎるようです... 私のアプリケーションはそれほど重要ではないので、バッファを 20MB に設定しましたが、それでも原因に興味があります。
編集
以前は考えもしなかったことをテストしました(恥ずかしい):
port.ErrorReceived += (object self, SerialErrorReceivedEventArgs se_arg) => { Console.Write("| Error: {0} | ", System.Enum.GetName(se_arg.EventType.GetType(), se_arg.EventType)); };
オーバーランしているようです。.Net 実装は 500k には遅すぎるのでしょうか、それとも私の側にエラーがありますか?
元の質問
私は非常に原始的なオジロ スコープ (avr、ADC データを uart 経由で ftdi チップに送信する) を作成しました。PC側には、このデータを表示するWPFプログラムがあります。
プロトコルは次のとおりです。
2 同期バイト (0xaffe) - 14 データ バイト - 2 同期バイト - 14 データ バイト - ...
私は 16 ビット値を使用するため、14 データ バイト内に 7 チャネル (LSB ファースト) があります。
hTerm で uC ファームウェアを確認したところ、すべてが正しく送受信されます。しかし、C# でデータを読み取ろうとすると、一部のバイトが失われることがあります。oszilloscop プログラムはめちゃくちゃですが、同じ症状を持つ小さなサンプル アプリケーションを作成しました。
a) COM ポートから 1 バイトを読み取り、-1 (EOF) を無視する、および b) 同期パターンを待機する 2 つの拡張メソッドを追加しました。
サンプル プログラムは、最初に (0xaffe) を待ってデータ ストリームに同期し、次に受信したバイト数を期待値と比較します。アサート失敗メッセージが表示されるまで、ループが数回実行されます。Google経由で失われたバイトについて何も見つけることができませんでした。助けていただければ幸いです。
コード
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SerialTest
{
public static class SerialPortExtensions
{
public static byte ReadByteSerial(this SerialPort port)
{
int i = 0;
do
{
i = port.ReadByte();
} while (i < 0 || i > 0xff);
return (byte)i;
}
public static void WaitForPattern_Ushort(this SerialPort port, ushort pattern)
{
byte hi = 0;
byte lo = 0;
do
{
lo = hi;
hi = port.ReadByteSerial();
} while (!(hi == (pattern >> 8) && lo == (pattern & 0x00ff)));
}
}
class Program
{
static void Main(string[] args)
{
//500000 8n1
SerialPort port = new SerialPort("COM3", 500000, Parity.None, 8, StopBits.One);
port.Open();
port.DiscardInBuffer();
port.DiscardOutBuffer();
//Sync
port.WaitForPattern_Ushort(0xaffe);
byte hi = 0;
byte lo = 0;
int val;
int n = 0;
// Start Loop, the stream is already synced
while (true)
{
//Read 7 16-bit values (=14 Bytes)
for (int i = 0; i < 7; i++)
{
lo = port.ReadByteSerial();
hi = port.ReadByteSerial();
val = ((hi << 8) | lo);
Debug.Assert(val != 0xaffe);
}
//Read two sync bytes
lo = port.ReadByteSerial();
hi = port.ReadByteSerial();
val = ((hi << 8) | lo);
Debug.Assert(val == 0xaffe);
n++;
}
}
}
}