テクセル
RubyでPLC TCP/IP通信(Qシリーズ)

三菱電機(株)製PLC(シーケンサQシリーズ)のEthernetインターフェースユニットへRubyによりTCP通信を行います。 実行環境は、以下となります。

項目 内容
Rubyのバージョン  ruby 2.6.3p62 (RubyInstaller x86)
対象としたユニット Ethernetインターフェースユニット QJ71E71-100または、ユニバーサルモデルCPUの内蔵Ethernet
通信手順  MCプロトコル QnA互換3Eフレーム

■ EthernetインターフェースユニットQJ71E71-100での設定

GX Wroks2によりネットワークパラメータ Ethernet/CC IE/MELSECNETで設定します。

1)動作設定

項目 内容
交信データコード設定 「ASCIIコード交信」を選択
イニシャルタイミング設定 「常にOPEN待ち(STOP中交信可能)」を選択
IPアドレス設定 入力形式「10進数」を選択
IPアドレスをここでは、「192.168.1.78」と設定します。
送信フレーム設定 「Ethernet(V2.0)」を選択
RUN書き込み チェックマークあり(許可)とします。
TCP生存確認設定 「Pingを使用」を選択

2)オープン設定

いずれかの番号行に以下を設定します。

項目 内容
プロトコル 「TCP」を選択
オープン方式 「Unpassive」(受動的オープン)を選択
固定バッファ 「送信」を選択 MCプロトコルの場合は、「送信」、「受信」どちらでも良い
固定バッファ交信手順 「手順あり」を選択
ペアリングオープン 「ペアにしない」を選択
生存確認 「確認する」を選択
自局ポート番号 ここでは、「9000」(10進)と設定します。
交信相手IPアドレス 設定不要
交信相手ポート番号 設定不要

■ Ethernetポート内蔵CPUユニバーサルモデルでの設定

GX Works2によりPCパラメータの内蔵Ethernetポート設定で設定します。

項目 内容
IPアドレス設定 IPアドレスをここでは、「192.168.1.99」と設定します。
交信データコード設定 ASCIIコード交信を選択します。
RUN書込みを許可する チェック入り(許可)とします。

「オープン設定」ボタンでオープン設定ダイアログを表示します。

項目 内容
プロトコル TCPを選択します。
オープン方式 MCプロトコルを選択します。
自局ポート番号 ここでは、「9010」(10進)とします。

■ サンプルソフト

下記サンプルソフトは、レジスタのD0100より10ワード読み込みを行ってます。エラー処理は行ってません。「q」キーで終了します。

「wincons.rb」の説明及びダウンロード


# coding: utf-8
# QJ71E71 TCP MC QnA互換3E
require 'socket'
require "./wincons"

htcp = TCPSocket.open("192.168.1.78", 9000)
#htcp = TCPSocket.open("192.168.1.99", 9010)

iflg = 0
src = 0

thr = Thread.start{ #受信スレッド
  loop{
     src = htcp.recv(100)
#    src,ipad = htcp.recvfrom(100)
    iflg = 1
  }
}

cons1 = Console.new(__ENCODING__)
istep = 1

# サブヘッダー Qヘッダー
ched = "5000" + "00" + "FF" + "03FF" + "00" + "0000" + "0010"
# コマンドサブ コマンド D100より10ワード読み込み
srsbcmd = "0000"        #サブコマンド
sdv = "D*"              #Dデバイス
itopad = 100            #読み込み先頭
ireadsu = 10            #読み込み個数
# コマンドサブ コマンド M100より20ビット読み込み
#srsbcmd = "0001"        #サブコマンド
#sdv = "M*"              #Mデバイス
#itopad = 100            #読み込み先頭
#ireadsu = 20            #読み込み個数

cscmd = "0401" + srsbcmd + sdv + sprintf("%06d",itopad) + sprintf("%04X",ireadsu)
ilen = cscmd.length + 4  #要求データ長
ched[14,4] = format("%4.4X",ilen)
sa = ched + cscmd

loop{
  case istep
    when 1
      iflg = 0
#      p sa
      htcp.send(sa,0)
      istep = 2
    when 2
      if iflg == 1
#        p src
        sd = ""; ik = 0
        if sdv == "D*" then ik = 4 end
        if sdv == "M*" then ik = 1 end
        for ia in 0..(ireadsu - 1)
          sd += src[22 + ia * ik,ik] + ","
        end
        cons1.cprint sd + "¥r¥n"
#        sleep 0.2  #表示遅延用
        istep = 1
      end
  end
  ca, = cons1.inkey
  if ca == "q" || ca == "Q"
    thr.exit #kill
    thr.join
    htcp.close
    break
  end
  sleep 0.01
}
   
参考資料
・Q対応Ethernetインターフェースユニット ユーザーズマニュアル(基本編)(三菱電機(株))
・Q対応MELSECコミュニケーションプロトコル リファレンスマニュアル(三菱電機(株))
・QnUCPU ユーザーズマニュアル(内蔵Ethernet ポート通信編)(三菱電機(株))
Rubyユーティリティ
©2005-2019 TEXCELL CORPORATION
テクセル株式会社