【設備制御プログラム】三菱PLC　SLMPデバイスコード　C#

こんにちは。テラロイドです。

前回、SLMPの伝文の作成方法について投稿しましたが、本日はデバイスコードを簡単に設定できるように関数を作ってみました。
1対1通信ではべた書きしそうですが、ライブラリ化などをご検討の方は、参考にしてみてください。
英語はMCプロトコルの英語版のマニュアル見たのでたぶんあってると思います！！

PLCのQシリーズとiQシリーズで桁が違うので要注意です。
※SLMPのマニュアルにはQとiQという言い方で分けてない(サブコマンドで分けてる)ので、使用時にはマニュアルを参考にしてください。MCプロトコルのマニュアルにはQとiQで別れてると書いてます。

```C#:デバイスコード列挙体
    /// <summary>デバイスコード</summary>
    public enum DeviceCode
    {
        /// <summary>特殊リレー</summary>
        /// <remarks>記号:SM</remarks>
        SpecialRelay,
        /// <summary>特殊レジスター</summary>
        /// <remarks>記号:SD</remarks>
        SpecialRegister,
        /// <summary>入力</summary>
        /// <remarks>記号:X</remarks>
        Input,
        /// <summary>出力</summary>
        /// <remarks>記号:Y</remarks>
        Output,
        /// <summary>内部リレー</summary>
        /// <remarks>記号:M</remarks>
        InternalRelay,
        /// <summary>ラッチリレー</summary>
        /// <remarks>記号:L</remarks>
        LatchRelay,
        /// <summary>アナンシェーター</summary>
        /// <remarks>記号:F</remarks>
        Annunciator,
        /// <summary>エッジリレー</summary>
        /// <remarks>記号:V</remarks>
        EdgeRelay,
        /// <summary>リンクリレー</summary>
        /// <remarks>記号:B</remarks>
        LinkRelay,
        /// <summary>データレジスター</summary>
        /// <remarks>記号:D</remarks>
        DataRegister,
        /// <summary>リンクレジスター</summary>
        /// <remarks>記号:W</remarks>
        LinkRegister,
        /// <summary>タイマー(接点)</summary>
        /// <remarks>記号:TS</remarks>
        TimerContact,
        /// <summary>タイマー(コイル)</summary>
        /// <remarks>記号:TC</remarks>
        TimerCoil,
        /// <summary>タイマー(現在値)</summary>
        /// <remarks>記号:TN</remarks>
        TimerCurrentValue,
        /// <summary>ロングタイマー(接点)</summary>
        /// <remarks>記号:LTS</remarks>
        LongTimerContact,
        /// <summary>ロングタイマー(コイル)</summary>
        /// <remarks>記号:LTC</remarks>
        LongTimerCoil,
        /// <summary>ロングタイマー(現在値)</summary>
        /// <remarks>記号:LTN</remarks>
        LongTimerCurrentValue,
        /// <summary>積算タイマー(接点)</summary>
        /// <remarks>記号:STS</remarks>
        RetentiveTimerContact,
        /// <summary>積算タイマー(コイル)</summary>
        /// <remarks>記号:STC</remarks>
        RetentiveTimerCoil,
        /// <summary>積算タイマー(現在値)</summary>
        /// <remarks>記号:STN</remarks>
        RetentiveTimerCurrentValue,
        /// <summary>ロング積算タイマー(接点)</summary>
        /// <remarks>記号:LSTS</remarks>
        LongRetentiveTimerContact,
        /// <summary>ロング積算タイマー(コイル)</summary>
        /// <remarks>記号:LSTC</remarks>
        LongRetentiveTimerCoil,
        /// <summary>ロング積算タイマー(現在値)</summary>
        /// <remarks>記号:LSTN</remarks>
        LongRetentiveTimerCurrentValue,
        /// <summary>カウンター(接点)</summary>
        /// <remarks>記号:CS</remarks>
        CounterContact,
        /// <summary>カウンター(コイル)</summary>
        /// <remarks>記号:CC</remarks>
        CounterCoil,
        /// <summary>カウンター(現在値)</summary>
        /// <remarks>記号:CN</remarks>
        CounterCurrentValue,
        /// <summary>ロングカウンター(接点)</summary>
        /// <remarks>記号:LCS</remarks>
        LongCounterContact,
        /// <summary>ロングカウンター(コイル)</summary>
        /// <remarks>記号:LCC</remarks>
        LongCounterCoil,
        /// <summary>ロングカウンター(現在値)</summary>
        /// <remarks>記号:LCN</remarks>
        LongCounterCurrentValue,
        /// <summary>リンク特殊リレー</summary>
        /// <remarks>記号:SB</remarks>
        LinkSpecialRelay,
        /// <summary>リンク特殊レジスター</summary>
        /// <remarks>記号:SW</remarks>
        LinkSpecialRegister,
        /// <summary>ステップリレー</summary>
        /// <remarks>記号:S</remarks>
        StepRelay,
        /// <summary>ダイレクトアクセス入力</summary>
        /// <remarks>記号:DX</remarks>
        DirectAccessInput,
        /// <summary>ダイレクトアクセス出力</summary>
        /// <remarks>記号:DY</remarks>
        DirectAccessOutput,
        /// <summary>インデックスレジスター</summary>
        /// <remarks>記号:Z</remarks>
        IndexRegister,
        /// <summary>ロングインデックスレジスター</summary>
        /// <remarks>記号:LZ</remarks>
        LongIndexRegister,
        /// <summary>ファイルレジスター(ブロック切換え方式)</summary>
        /// <remarks>記号:R</remarks>
        FileRegisterBlockSwitchingMethod,
        /// <summary>ファイルレジスター(連番アクセス方式)</summary>
        /// <remarks>記号:ZR</remarks>
        FileRegisterSerialNumberAccessMethod,
        /// <summary>拡張データレジスター</summary>
        /// <remarks>記号:D</remarks>
        ExtendedDataRegister,
        /// <summary>拡張リンクレジスター</summary>
        /// <remarks>記号:W</remarks>
        ExtendedLinkRegister,
        /// <summary>リフレッシュデータレジスター</summary>
        /// <remarks>記号:RD</remarks>
        RefreshDataRegister,
        /// <summary>ネットワークNo.指定デバイスリンクダイレクトデバイス</summary>
        /// <remarks>記号:J□\□</remarks>
        NetworkNumberSpecifiedDeviceLinkDirectDevice

    }
```

```C#:デバイスコード作成(Qシリーズ)
        /// <summary>デバイスコード作成(Qシリーズ)</summary>
        /// <param name="deviceCode"></param>
        /// <returns></returns>
        private byte[] createDeviceCode(DeviceCode deviceCode)
        {
                switch (deviceCode)
                {
                    case DeviceCode.SpecialRelay: return new byte[] { 0x91 };
                    case DeviceCode.SpecialRegister: return new byte[] { 0xA9 };
                    case DeviceCode.Input: return new byte[] { 0x9C };
                    case DeviceCode.Output: return new byte[] { 0x9D };
                    case DeviceCode.InternalRelay: return new byte[] { 0x90 };
                    case DeviceCode.LatchRelay: return new byte[] { 0x92 };
                    case DeviceCode.Annunciator: return new byte[] { 0x93 };
                    case DeviceCode.EdgeRelay: return new byte[] { 0x94 };
                    case DeviceCode.LinkRelay: return new byte[] { 0xA0 };
                    case DeviceCode.DataRegister: return new byte[] { 0xA8 };
                    case DeviceCode.LinkRegister: return new byte[] { 0xB4 };
                    case DeviceCode.TimerContact: return new byte[] { 0xC1 };
                    case DeviceCode.TimerCoil: return new byte[] { 0xC0 };
                    case DeviceCode.TimerCurrentValue: return new byte[] { 0xC2 };
                    case DeviceCode.RetentiveTimerContact: return new byte[] { 0xC7 };
                    case DeviceCode.RetentiveTimerCoil: return new byte[] { 0xC6 };
                    case DeviceCode.RetentiveTimerCurrentValue: return new byte[] { 0xC8 };
                    case DeviceCode.CounterContact: return new byte[] { 0xC4 };
                    case DeviceCode.CounterCoil: return new byte[] { 0xC3 };
                    case DeviceCode.CounterCurrentValue: return new byte[] { 0xC5 };
                    case DeviceCode.LinkSpecialRelay: return new byte[] { 0xA1 };
                    case DeviceCode.LinkSpecialRegister: return new byte[] { 0xB5 };
                    case DeviceCode.StepRelay: return new byte[] { 0x98 };
                    case DeviceCode.DirectAccessInput: return new byte[] { 0xA2 };
                    case DeviceCode.DirectAccessOutput: return new byte[] { 0xA3 };
                    case DeviceCode.IndexRegister: return new byte[] { 0xCC };
                    case DeviceCode.FileRegisterBlockSwitchingMethod: return new byte[] { 0xAF };
                    case DeviceCode.FileRegisterSerialNumberAccessMethod: return new byte[] { 0xB0 };
                    case DeviceCode.ExtendedDataRegister: return new byte[] { 0xA8 };
                    case DeviceCode.ExtendedLinkRegister: return new byte[] { 0xB4 };
                    case DeviceCode.LongTimerContact:
                    case DeviceCode.LongTimerCoil:
                    case DeviceCode.LongTimerCurrentValue:
                    case DeviceCode.LongRetentiveTimerContact:
                    case DeviceCode.LongRetentiveTimerCoil:
                    case DeviceCode.LongRetentiveTimerCurrentValue:
                    case DeviceCode.LongCounterContact:
                    case DeviceCode.LongCounterCoil:
                    case DeviceCode.LongCounterCurrentValue:
                    case DeviceCode.LongIndexRegister:
                    case DeviceCode.RefreshDataRegister:
                    case DeviceCode.NetworkNumberSpecifiedDeviceLinkDirectDevice:
                    default:throw new Exception("指定のデバイスは使用できません。");
                }
        }
```

```C#:デバイスコード作成(iQシリーズ)
        /// <summary>デバイスコード作成(iQシリーズ)</summary>
        /// <param name="deviceCode"></param>
        /// <returns></returns>
        private byte[] createDeviceCode(DeviceCode deviceCode)
        {
               switch (deviceCode)
                {
                    case DeviceCode.SpecialRelay: return new byte[] { 0x91, 0x00 };
                    case DeviceCode.SpecialRegister: return new byte[] { 0xA9, 0x00 };
                    case DeviceCode.Input: return new byte[] { 0x9C, 0x00 };
                    case DeviceCode.Output: return new byte[] { 0x9D, 0x00 };
                    case DeviceCode.InternalRelay: return new byte[] { 0x90, 0x00 };
                    case DeviceCode.LatchRelay: return new byte[] { 0x92, 0x00 };
                    case DeviceCode.Annunciator: return new byte[] { 0x93, 0x00 };
                    case DeviceCode.EdgeRelay: return new byte[] { 0x94, 0x00 };
                    case DeviceCode.LinkRelay: return new byte[] { 0xA0, 0x00 };
                    case DeviceCode.DataRegister: return new byte[] { 0xA8, 0x00 };
                    case DeviceCode.LinkRegister: return new byte[] { 0xB4, 0x00 };
                    case DeviceCode.TimerContact: return new byte[] { 0xC1, 0x00 };
                    case DeviceCode.TimerCoil: return new byte[] { 0xC0, 0x00 };
                    case DeviceCode.TimerCurrentValue: return new byte[] { 0xC2, 0x00 };
                    case DeviceCode.LongTimerContact: return new byte[] { 0x51, 0x00 };
                    case DeviceCode.LongTimerCoil: return new byte[] { 0x50, 0x00 };
                    case DeviceCode.LongTimerCurrentValue: return new byte[] { 0x52, 0x00 };
                    case DeviceCode.RetentiveTimerContact: return new byte[] { 0xC7, 0x00 };
                    case DeviceCode.RetentiveTimerCoil: return new byte[] { 0xC6, 0x00 };
                    case DeviceCode.RetentiveTimerCurrentValue: return new byte[] { 0xC8, 0x00 };
                    case DeviceCode.LongRetentiveTimerContact: return new byte[] { 0x59, 0x00 };
                    case DeviceCode.LongRetentiveTimerCoil: return new byte[] { 0x58, 0x00 };
                    case DeviceCode.LongRetentiveTimerCurrentValue: return new byte[] { 0x5A, 0x00 };
                    case DeviceCode.CounterContact: return new byte[] { 0xC4, 0x00 };
                    case DeviceCode.CounterCoil: return new byte[] { 0xC3, 0x00 };
                    case DeviceCode.CounterCurrentValue: return new byte[] { 0xC5, 0x00 };
                    case DeviceCode.LongCounterContact: return new byte[] { 0x55, 0x00 };
                    case DeviceCode.LongCounterCoil: return new byte[] { 0x54, 0x00 };
                    case DeviceCode.LongCounterCurrentValue: return new byte[] { 0x56, 0x00 };
                    case DeviceCode.LinkSpecialRelay: return new byte[] { 0xA1, 0x00 };
                    case DeviceCode.LinkSpecialRegister: return new byte[] { 0xB5, 0x00 };
                    case DeviceCode.StepRelay: return new byte[] { 0x98, 0x00 };
                    case DeviceCode.DirectAccessInput: return new byte[] { 0xA2, 0x00 };
                    case DeviceCode.DirectAccessOutput: return new byte[] { 0xA3, 0x00 };
                    case DeviceCode.IndexRegister: return new byte[] { 0xCC, 0x00 };
                    case DeviceCode.LongIndexRegister: return new byte[] { 0x62, 0x00 };
                    case DeviceCode.FileRegisterBlockSwitchingMethod: return new byte[] { 0xAF, 0x00 };
                    case DeviceCode.FileRegisterSerialNumberAccessMethod: return new byte[] { 0xB0, 0x00 };
                    case DeviceCode.RefreshDataRegister: return new byte[] { 0x2C, 0x00 };
                    case DeviceCode.ExtendedDataRegister:
                    case DeviceCode.ExtendedLinkRegister:
                    case DeviceCode.NetworkNumberSpecifiedDeviceLinkDirectDevice:
                    default:throw new Exception("指定のデバイスは使用できません。");
                }
        }
```