7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【設備制御プログラム】三菱PLC SLMP送信プログラム C#

Last updated at Posted at 2022-12-21

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

最近、PLCと通信するソフトを作成しましたが、記事が少なかったため投稿します。
本記事では、三菱電機のPLCと通信するためのプロトコル「SLMP」もしくは「MCプロトコル」の伝文作成について書きました。

伝文は条件により若干変わりますので条件書いときます。
PLCの型式:Qシリーズ(iQシリーズや他のシリーズではコマンドが変わることがあります。)
コードはASCIIとバイナリが可能ですが、本記事はバイナリで伝文を作成しています。

伝文フォーマットは下記の様な構成になっていますが、要求データを作成してから他の項目を作成していくようにしています。
伝文フォーマット = ヘッダ + サブヘッダ + アクセス経路 + 応答データ長 + 監視タイマー + 要求データ

要求データ作成(一括読出し)
/// <summary>一括読出し(batch read)</summary>
/// <param name="NumberOfDevicePoints">読出しデバイス点数</param>
/// <returns></returns>
public override byte[] ReadInBulkInWordUnits(int NumberOfDevicePoints) 
{

IEnumerable<byte> createCommand;

//コマンド
createCommand = new byte[]{0x01,0x04};

//サブコマンド
createCommand = createCommand.Concat(new byte[]{0x00,0x00});

//先頭デバイス番号
createCommand = createCommand.Concat(new byte[]{0x00,0x00,0x00});

//デバイスコード
createCommand = createCommand.Concat(new byte[]{0xA8}); 

//デバイス点数
byte upperHex = (byte)(numberOfDevicePoints / 256);
byte lowerHex = (byte)(numberOfDevicePoints % 256);
createCommand = createCommand.Concat(new byte[] {lowerHex,upperHex});

return createSendMessage((byte[])createCommand.ToArray());
}
要求データ作成(一括書込み)
/// <summary>一括書込み(ワード単位)(batch write)</summary>
/// <param name="WriteData">書込みデータ</param>
/// <returns></returns>
public override byte[] WriteInBulkInWordUnits(byte[] WriteData)
{

IEnumerable<byte> createCommand;

//コマンド
createCommand = new byte[]{0x01,0x14};

//サブコマンド
createCommand = createCommand.Concat(new byte[]{0x00,0x00});

//先頭デバイス番号
createCommand = createCommand.Concat(new byte[]{0x00,0x00,0x00});

//デバイスコード
createCommand = createCommand.Concat(new byte[]{0xA8}); 

//デバイス点数
createCommand = createCommand.Concat(createNumberOfDevicePoints(WriteData.Length / 2));

//書込みデータ
createCommand = createCommand.Concat(WriteData);

return createSendMessage((byte[])createCommand.ToArray());

        }
要求伝文作成
protected override byte[] createSendMessage(byte[] command)
{

IEnumerable<byte> createMessage;

//要求伝文フォーマット
//伝文フォーマット = ヘッダ + サブヘッダ + アクセス経路 + 応答データ長 + 監視タイマー + 要求データ 
//①TCPヘッダーの為、不要
//②サブヘッダ―
////サブヘッダ― = 要求伝文

createMessage = new byte[]{0x50,0x00};

//③アクセス経路
//アクセス経路 = ネットワーク番号 + PC番号 + 要求先ユニットI/O番号 + 要求先ユニット局番号
createMessage = createMessage.Concat(new byte[]{0x00});
createMessage = createMessage.Concat(new byte[]{0xFF});
createMessage = createMessage.Concat(new byte[]{0xFF,0x03});
createMessage = createMessage.Concat(new byte[]{0x00});

//④データ長
byte upperHex = (byte)((2 + command.Length) / 256);
byte lowerHex = (byte)((2 + command.Length) % 256);

if ((upperHex / 256) >= 1) { throw new Exception("データ長に不正な値が設定されました。(桁数オーバー)"); }
createMessage = createMessage.Concat(new byte[]{ lowerHex });
createMessage = createMessage.Concat(new byte[]{ upperHex });

//⑤監視タイマー
byte upperHex2 = (byte)((monitoringTimer) / 256);
byte lowerHex2 = (byte)((monitoringTimer) % 256);

if ((upperHex2 / 256) >= 1) { throw new Exception("監視タイマーに不正な値が設定されました。(桁数オーバー)"); }
createMessage = createMessage.Concat(new byte[]{ upperHex2 });
createMessage = createMessage.Concat(new byte[]{ lowerHex2 });

//⑥要求データ
//要求データ = コマンド + サブコマンド + 先頭デバイス + 
createMessage = createMessage.Concat(command);

//ログ出力
string tmp = "";
string text = "";
foreach (byte b in (byte[])createMessage){text = string.Format("{0,3:X2}", b);tmp = tmp + text;}
log.OutputDebug("[S]" + tmp);

return (byte[])createMessage.ToArray();

}
7
4
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?