powershellスクリプトで三菱電機(株)製PLC(シーケンサ)iQ-RシリーズとUDPイーサネット通信を行います。実行環境は、以下となります。
項目 | 内容 |
---|---|
対象としたイーサネットポート | iQ-R CPUのイーサネットポート |
通信手順 | MCプロトコル QnA互換3Eフレーム ASCIIコード |
GX Works3 ナビゲーションウインドウのプロジェクトから[R**CPU]の[ユニットパラメータ]をマウスダブルクリックし設定シートを
表示します。IPアドレスを設定し、RUN中の書込許可/禁止設定を「一括で許可する(SLMP)」に、交信データコードを「ASCII」とします。
次に「相手機器接続構成設定」の<詳細設定>をマウスダブルクリックしEthernet構成(内蔵Ethernetポート)ダイアログを開きます。
ユニット一覧より「SLMP接続機器」をマウス選択し左下の自局右にドラッグします。プロトコルを「UDP」としポート番号を設定します。
「設定を反映して閉じる」をマウスクリックしダイアログを閉じます。「適用」ボタンをマウスクリックします。
ここでは、IPアドレス「192.168.1.69」、ポート番号「9010」とします。
下記ソフトは、レジスタのD0100より10ワード読み込みを行ってます。エラー処理は行ってません。「q」キーで終了します。プログラムは、コンソールウインドウで実行して下さい。ISEでは、エラーとなります。
# MelEthudpASCII3E.ps1
# 三菱PLC MCプロトコルイーサネット通信
# UDP QnA互換3E ASCII
Set-StrictMode -Version latest
# キー入力
function Keyin{
$rtkey = $null
if ([Console]::KeyAvailable){
$rtkey = [Console]::ReadKey($true)
}
return $rtkey
}
# 受信 受信データ、受信データ長
function receive([ref][byte[]]$rcvDt, [ref]$ircvp){
$ir = 0
if ($ircvp.Value -eq 0){ # 受信開始
$Script:reqlen = 0
}
$ic = $Script:udpClient.Available # 受信データバイト数
if ($ic -gt 0){
[System.Net.IPEndPoint]$ipEndP = $null
$bywk = $Script:udpClient.Receive([ref]$ipEndP) # 受信データ取り込み ※1
$il = $bywk.Length
[System.Array]::Copy($bywk, 0, $rcvDt.Value, $ircvp.Value, $il)
$ircvp.Value += $il
if ($Script:reqlen -eq 0 -and $ircvp.Value -ge 18){
[byte[]]$bywk = New-Object byte[] 4
[System.Array]::Copy($rcvDt.Value, 14, $bywk, 0, 4) # 応答データ長
$sa = [System.Text.Encoding]::ASCII.GetString($bywk)
$Script:reqlen = [int]("0x" + $sa) + 18 # 受信長
}
if ($ircvp.Value -ge $Script:reqlen){
$ir = 1 # 受信完了
}
}
return $ir
}
$remoteHost = "192.168.1.69" # 接続先ホスト ipアドレス
$remotePort = 9010 # 接続先ポート番号
# ------- D100 から 10ワード読み込み
$itpadd = 100 # 読み込み先頭(デバイス番号)
$ireadsu = 10 # 読み込み個数
$ssbcmd = "0000" # サブコマンド
$sdv = "D*" # Dデバイス
# ------- M100 から 20 ビット読み込み
<# $itpadd = 100 # 読み込み先頭(デバイス番号)
$ireadsu = 20 # 読み込み個数
$ssbcmd = "0001" # サブコマンド
$sdv = "M*" # Dデバイス #>
$Script:udpClient = New-Object System.Net.Sockets.UdpClient($remoteHost, $remotePort) # script スコープ
# サブヘッダー Qヘッダー
$sched = "5000" + "00" + "FF" + "03FF" + "00" + "0000" + "0010"
$scscmd = "0401" + $ssbcmd + $sdv + $itpadd.ToString("D6") + $ireadsu.ToString("X4")
$ilen = $scscmd.Length + 4 # 要求データ長
$slen = $ilen.ToString("X4")
$bylen = [System.Text.Encoding]::ASCII.GetBytes($slen)
$bya = [System.Text.Encoding]::ASCII.GetBytes($sched + $scscmd)
[System.Array]::Copy($bylen, 0, $bya, 14, 4); # 要求データ長セット
[byte[]]$rcvData = New-Object byte[] 1024
$ircvlen = 0;
$istp = 1
while($true){
if ($istp -eq 1){
$ir = $Script:udpClient.Send($bya, $bya.Length) # 送信
$istp = 2
}
elseif ($istp -eq 2){
$ir = receive ([ref]$rcvData) ([ref]$ircvlen)
if ($ir -eq 1){ # 受信完了?
$srcv = [System.Text.Encoding]::ASCII.GetString($rcvData, 0, $ircvlen)
# Write-Host $srcv
$sdd = ""; $ik = 4
if ($sdv.Substring(0, 1) -eq "M"){$ik = 1}
for($iq = 0; $iq -lt $ireadsu; $iq++){
$sdd += $srcv.Substring(22 + $iq * $ik, $ik) + ","
}
Write-Host $sdd
$ircvlen = 0
$istp = 1
}
}
$inkey = Keyin
if ($inkey -ne $null -and $inkey.Key -eq "Q"){
break;
}
Start-Sleep -m 100
}
$udpClient.Close()
※1 $ipEndP には、接続先の IPアドレス、ポート番号がセットされます。