長さ8バイトのシリアルデータフレームをPCに送信するマイクロコントローラープロジェクトがあり、PCシリアルモニターツールを使用してマイクロコントローラーからのデータフレームを監視しましたが、すべてのデータは正常に見え、各8バイトフレームは一貫して送信されているようですこのパターンのデータの長さは 8 バイトです。
私が経験している問題は次のとおりです。
シリアル データを読み取るたびに、構造化された 8 バイト データ フレームの 1 番目のバイトが存在しません。
例:
各ループは以下のとおりです。
マイクロコントローラが 8 バイトのフレームを送信: 01 FF 8E 01 00 00 00 0A
最初のループ反復。
.NET Serial PORT がデータ フレームを受信: 01 00 00 00 00 00 00 00
読み取り (バフ、0、8); 読み取り 1 バイト読み取り
2 回目のループ反復。
.NET Serial PORT がデータ フレームを受信: FF 8E 01 00 00 00 0A 00 (7 バイト読み取り)
読み取り (バフ、0、8); 読み取り 7 バイト読み取り
sr.Read(buff, 0, 8) は、ループの反復ごとに常に 8 バイトの長さを読み取ることを期待しています。
シリアルポートから読み取るために使用するコードは次のとおりです
static void Main(string[] args)
{
using (SerialPort sr = new SerialPort("COM5"))
{
sr.BaudRate = 9600;
sr.DataBits = 8;
sr.Parity = Parity.None;
sr.StopBits = StopBits.One;
sr.Open();
StringBuilder sb = new StringBuilder();
while (true)
{
byte[] buff = new byte[8];
int r = sr.Read(buff, 0, 8);
Console.WriteLine("Number of bytes read : " + r);
for (int i = 0; i < buff.Length; i++)
{
var hex = string.Format("{0:x2}", buff[i]);
sb.Append(hex.ToUpper());
sb.Append(" ");
}
Console.WriteLine(sb);
sb.Clear();
}
}
前もって感謝します。
非常に有益なフィードバックをありがとう。
8 バイト フレームのバッファリング ロジックを次のように再構築しました。
すべてが、ポート モニターから見たデータ パターンと同期しているように見えます。最も重要なのは、マイクロコントローラーからのデータです。
重要な側面がまだ欠けています:
- フレーム CRC。
- 各バイトの順序を検証します。
....... など
ここに更新されたコードがあります
static void Main(string[] args) { using (SerialPort sr = new SerialPort("COM5")) { sr.BaudRate = 9600; sr.DataBits = 8; sr.Parity = Parity.None; sr.StopBits = StopBits.One; sr.Handshake = Handshake.None; sr.DtrEnable = false; sr.Open(); sr.ReceivedBytesThreshold = 1; StringBuilder sb = new StringBuilder(); byte[] buff = new byte[8]; byte[] temp_buffer = new byte[8]; while (true) { int r = sr.Read(temp_buffer, 0, 8); Console.WriteLine("Number of bytes read : " + r); // 1 - byte from the serial frame ? if (r == 1) { buff[0] = temp_buffer[0]; } // 7 - bytes from the serial frame ? if (r == 7) { // get the remaining 7 - bytes for (int i = 0; i <= temp_buffer.Length - 1; i++) { if (i != 0) buff[i] = temp_buffer[i]; // construct a complete frame } // okay, we ready to display the 8-byte serial frame. for (int i = 0; i < buff.Length; i++) { var hex = string.Format("{0:x2}", buff[i]); sb.Append(hex.ToUpper()); sb.Append(" "); } Console.WriteLine(sb); sb.Clear(); } } } }
また、16 バイトのシリアル フレームを読み取る、変更されたバージョンもここにあります。
using (SerialPort sr = new SerialPort("COM5"))
{
sr.BaudRate = 9600;
sr.DataBits = 8;
sr.Parity = Parity.None;
sr.StopBits = StopBits.One;
sr.Open();
sr.ReceivedBytesThreshold = 1;
StringBuilder sb = new StringBuilder();
byte[] io_buffer = new byte[16];
byte[] temp_buffer = new byte[16];
do
{
int data_length = sr.Read( temp_buffer, 0, 16 );
// 1 - Byte from the serial frame ?
if ( data_length == 1 && temp_buffer[ 0 ] == 0x28 )
{
io_buffer[ 0 ] = temp_buffer[ 0 ];
}
// 15 - Bytes from the serial frame ?
if (data_length == 15 && temp_buffer[14] == 0x29)
{
// Here we construct the 16- byte frame.(start from 1 as we already have our start frame stored) "x028" => ")"
for ( int i = 1; i < temp_buffer.Length; i++ )
{
io_buffer[ i ] = temp_buffer[ i - 1 ];
}
// okay, we ready to display the 16-byte serial frame.
for ( int i = 0; i < io_buffer.Length; i++ )
{
var hex = string.Format( "{0:x2}", io_buffer[ i ] );
sb.Append( hex.ToUpper() );
sb.Append( " " );
}
Console.WriteLine(sb);
sb.Clear();
}
} while (sr.IsOpen);
ここでは 16 バイトのフレーム出力、4 番目のバイトは (I/O 4 チャンネル アナログ - デジタル コンバーター) からのチャンネル 0 から 3 を示します。
28 FF FF 00 01 DB 00 00 00 00 00 00 0E 00 00 29
28 FF FF 01 01 02 00 00 00 00 00 00 0E 00 00 29
28 FF FF 02 01 02 00 00 00 00 00 00 0E 00 00 29
28 FF FF 03 01 A8 00 00 00 00 00 00 0E 00 00 29