私はmodbus rs485 rs232
を介して2つの位相計に通信するためにC#を使用しています。Modbus通信
私は読み取り値を受信できるように、バスを介してデータを送信する必要があります。
通常のワイヤを接続して送受信を短絡しました。データを受け取っていると、このイベントが発生する
:
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
byte[] buff = new byte[sp.BytesToRead];
//Read the Serial Buffer
sp.Read(buff, 0, buff.Length);
string data= sp.ReadExisting();
foreach (byte b in buff)
{
AddBuffer(b); //Add byte to buffer
}
}
次に、このバッファは、このいずれかである別の関数に送信されます。
private void AddBuffer(byte b)
{
buffer.Add(b);
byte[] msg = buffer.ToArray();
//Make sure that the message integrity is correct
if (this.CheckDataIntegrity(msg))
{
if (DataReceived != null)
{
ModbusEventArgs args = new ModbusEventArgs();
GetValue(msg, args);
DataReceived(this, args);
}
buffer.RemoveRange(0, buffer.Count);
}
}
私はこの問題は、データであることを考えます完全性チェック:
public bool CheckDataIntegrity(byte[] data)
{
if (data.Length < 6)
return false;
//Perform a basic CRC check:
byte[] CRC = new byte[2];
GetCRC(data, ref CRC);
if (CRC[0] == data[data.Length - 2] && CRC[1] == data[data.Length - 1])
return true;
else
return false;
}
CRCチェックがありますが、奇妙なことは、本当ではない。 CRC計算:
private void GetCRC(byte[] message, ref byte[] CRC)
{
ushort CRCFull = 0xFFFF;
byte CRCHigh = 0xFF, CRCLow = 0xFF;
char CRCLSB;
for (int i = 0; i < (message.Length) - 2; i++)
{
CRCFull = (ushort)(CRCFull^message[i]);
for (int j = 0; j < 8; j++)
{
CRCLSB = (char)(CRCFull & 0x0001);
CRCFull = (ushort)((CRCFull >> 1) & 0x7FFF);
if (CRCLSB == 1)
CRCFull = (ushort)(CRCFull^0xA001);
}
}
CRC[1] = CRCHigh = (byte)((CRCFull >> 8) & 0xFF);
CRC[0] = CRCLow = (byte)(CRCFull & 0xFF);
}
一般的な通信セッションのトランスクリプトを持っていて、CRCを備えたオンラインリソースはありますか?そして、あなたは少なくともそれらのサンプルメッセージにあなたのアルゴリズムを適用して、あなたが同じCRCを思い付くかどうかを知ることができます。 –
"バッファ"変数とは何ですか?それはリストですか??あなたの "msg"変数が6より大きいと確信していますか?シリアルポートのバッファをバイト単位で分割するのではなく、リストで再構築してからグローバルバイト配列に変換するのはなぜですか?また、バッファの内容を読み込んだ直後にシリアルポートでReadExistingを呼び出すのはなぜですか? –
CRCは正しい@AndyzSmithのようです。 本当にどこかでreadexistingを呼び出すことは何ですか?はいバッファはリストです – Combinu