IoTClient開発5 - ModBusRtu契約

序文

私たちの前でModBusTcp契約今日、私たちはその後、ModBusRtu契約をご紹介します。ModbusTCP ModBusRtu差がシリアル通信に基づいており、ModBusTcp TCPがイーサネット通信に基づいています。
だから我々は最初のModBusRtu契約を説明する前に、シリアル通信をご紹介します。

串口通信

1980年に登場したシリアルは、オリジナルの主な目的は、マウス、キーボードなどなど、コンピュータの周辺機器を接続するために使用されています。今、最新のコンピュータは、ゆっくりと元のシリアルインタフェースを削除しますが、まだ広く産業用制御や計測機器に使用されます。

シリアル通信パラメータ

送受信バイトシリアル通信ポートビット単位(ビット)を参照して、シリアル通信のボーレート、データビット、ストップビット、パリティビットの主なパラメータ。

ボーレート

ボーレートをシリアル通信で表され、信号ユニットの数(シンボル)は、1秒間に送信されます。図10は、典型的には信号ユニット(7個のデータビット、1パリティビット、1または2ストップビット)を含みます。注:ボーレートとの距離に反比例

データビット

実際のデータ通信、7,8有効な値。

ストップビット

最後に、単一のパケットが1,1.5及び2の実効値を示すために使用されます。ストップビットは、送信クロック同期及びキャリブレーションの終了を表すために使用されます。注意:より多くのストップビットは、より大きな許容範囲のクロック同期の度合いが、データ転送速度が遅くなります。

パリティビット

通信方式としてパリ​​ティエラー検出、再送エラーが見つかった場合。

サンプルデータ 偶数パリティビット 奇数パリティビット
0000000 00000000 00000001
1010001 10100011 10100010
1101001 11010010 11010011
1111111 11111111 11111110

データのパリティから分かるように、データ1の数に加え、最後の一つは偶数または奇数の維持です。

ボー・レート及びビットレート(拡張された知識)

ビットレートは、我々は、ブロードバンドレートで表現するために使用される方法です。ボーレートのように見えるが、ボーレート、次いで、それらの間に送信された信号要素のみ1ビット(「ビット)が等しい場合。送信信号要素のボーレートは、10ビットの場合、ボーレートは、10倍のビットレートです。したがって、ボーレートとビットレートの発現の意義は同じではありませんが、混同しないでください。

ブロードバンドビットレートの実際のダウンロード速度(拡張知識)

MbpsおよびMbit / sの等価、キロビット/秒と同等物のkbpsの、BPSおよびビット/ sの等価
最大1Mbps(メガビット/秒)。1 = 1024キロビット(-kbit / S)= 1 1024 * 1024BPS(ビット/秒)、それら留意単位はビット(ビット)ではなく、バイト(バイト)であるので、実際のダウンロード速度を8で除算します。8分の1024 = 128キロバイト/秒 。

CRC16チェックサム

CRCは、巡回冗長は巡回冗長検査は、データが送信または伝送エラー中に変化するかどうかをチェックするためのデータの有効性確認コードのセットに基づいて計算されるチェック。ModBusRtu使用CRC16チェックの一つです。
原理を算出、基準とすることができる123
以下で反転さCRC16アルゴリズムModBusRtuは、CRC計算で使用するために試験しました。

public class CRC16
{
    /// <summary>
    /// 验证CRC16校验码
    /// </summary>
    /// <param name="value">校验数据</param>
    /// <param name="poly">多项式码</param>
    /// <param name="crcInit">校验码初始值</param>
    /// <returns></returns>
    public static bool CheckCRC16(byte[] value, ushort poly = 0xA001, ushort crcInit = 0xFFFF)
    {
        if (value == null || !value.Any())
            throw new ArgumentException("生成CRC16的入参有误");

        var crc16 = GetCRC16(value, poly, crcInit);
        if (crc16[crc16.Length - 2] == crc16[crc16.Length - 1] && crc16[crc16.Length - 1] == 0)
            return true;
        return false;
    }

    /// <summary>
    /// 计算CRC16校验码
    /// </summary>
    /// <param name="value">校验数据</param>
    /// <param name="poly">多项式码</param>
    /// <param name="crcInit">校验码初始值</param>
    /// <returns></returns>
    public static byte[] GetCRC16(byte[] value, ushort poly = 0xA001, ushort crcInit = 0xFFFF)
    {
        if (value == null || !value.Any())
            throw new ArgumentException("生成CRC16的入参有误");

        //运算
        ushort crc = crcInit;
        for (int i = 0; i < value.Length; i++)
        {
            crc = (ushort)(crc ^ (value[i]));
            for (int j = 0; j < 8; j++)
            {
                crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ poly) : (ushort)(crc >> 1);
            }
        }
        byte hi = (byte)((crc & 0xFF00) >> 8);  //高位置
        byte lo = (byte)(crc & 0x00FF);         //低位置

        byte[] buffer = new byte[value.Length + 2];
        value.CopyTo(buffer, 0);
        buffer[buffer.Length - 1] = hi;
        buffer[buffer.Length - 2] = lo;
        return buffer;
    }
}

プロトコルパケット解析

データ[読み取り - Requestパケット]:01 03 00 04 00 01 C5 CB

  • ステーションNo. 01
  • 03機能コード
  • 読み出し開始アドレスレジスタ0004
  • 00 01レジスタの数が読み込ま
  • CRC16チェックサムCRC16としてC5 CB [上記計算結果を用いて、クラス、CRC16.GetCRC16([01,03,00,04,00,01])]

データ[リード - 応答パケット]:01 03 02 00 21 78(c)

  • ステーションNo. 01
  • 03機能コード
  • 02データのバイト長
  • 0021データ
  • 78(c)は、チェックサムCRC16あります

[書き込みデータ - 要求パケット]:01 10 00 04 00 01 02 00 21 67 CC

  • ステーションNo. 01
  • 10機能コード
  • スタートアドレスレジスタ0004を書きます
  • 番号0001は、レジスタに書き込まれます
  • 書き込みバイトの02数
  • 0021データが書き込まれます
  • 67 CCは、CRC16チェックサムです

データが書き込ま[ - ]メッセージに応答して:0,110,000,400,014,008

  • ステーションNo. 01
  • 10機能コード
  • スタートアドレスレジスタ0004を書きます
  • 番号0001は、レジスタに書き込まれます
  • 4008は、チェックサムCRC16です

パケット解析で、具体的な合意を達成することは難しいことではありません。完全な実装では、参照してくださいhttps://github.com/zhaopeiym/IoTClient/blob/master/IoTClient/Clients/ModBus/ModBusRtuClient.cs

ModBusRtu契約の利用IoTClient

インストール

Nugetのインストール Install-Package IoTClient
やグラフィカルインストール

使用

//1、实例化客户端 - [COM端口名称,波特率,数据位,停止位,奇偶校验]
ModBusRtuClient client = new ModBusRtuClient("COM3", 9600, 8, StopBits.One, Parity.None);

//2、写操作 - 参数依次是:地址 、值 、站号 、功能码
client.Write("4", (short)33, 2, 16);
client.Write("4", (short)3344, 2, 16);

//3、读操作 - 参数依次是:地址 、站号 、功能码
var value = client.ReadInt16("4", 2, 3).Value;
var value2 = client.ReadInt32("4", 2, 3).Value;

//4、如果没有主动Open,则会每次读写操作的时候自动打开自动和关闭连接,这样会使读写效率大大减低。所以建议手动Open和Close。
client.Open();

//5、读写操作都会返回操作结果对象Result
var result = client.ReadInt16("4", 2, 3);
//5.1 读取是否成功(true或false)
var isSucceed = result.IsSucceed;
//5.2 读取失败的异常信息
var errMsg = result.Err;
//5.3 读取操作实际发送的请求报文
var requst  = result.Requst;
//5.4 读取操作服务端响应的报文
var response = result.Response;
//5.5 读取到的值
var value3 = result.Value;

参照

おすすめ

転載: www.cnblogs.com/zhaopei/p/12047465.html
おすすめ