テクセル

RubyでPLCシリアル通信(三菱iQ-R,Qシリーズ)


Rubyで三菱電機(株)製PLC(シーケンサ)iQ-R,Qシリーズとシリアル通信を行います。実行環境は、以下となります。

項目 内容
Rubyのバージョン ruby 2.7.2p137 (RubyInstaller x86)
対象としたシリアルポート シリアルコミュニケーションユニット:RJ71C24,RJ71C24-R2,QJ71C24N,QJ71C24N-R2 QCPUのシリアルポート(RS-232C)
通信手順 MCプロトコル、QnA互換3Cフレーム形式4、サムチェックあり
通信仕様 通信速度9600bps、データ長8ビット、1ストップビット、奇数パリティ

□ PLCでの設定

1.シリアルコミュニケーションユニット RJ71C24,RJ71C24-R2 での設定例 (iQ-Rシリーズ)

GX Works3のナビゲーションウインドウのプロジェクトから[パラメータ]-[ユニット情報]-[****:RJ71C24]の「ユニットパラメータ」を マウスダブルクリックし設定シートを表示します。(RJ71C24は、ユニットパラメータに登録されているものとします。) CH1に設定します。交信プロトコル「MCプロトコル(形式4)」、通信速度「9600bps」、動作設定「独立」、データビット「8」、 パリティビット「あり」、奇数/偶数パリティ「奇数」、ストップビット「1」、サムチェックコード「あり」、RUN中書込み「許可」 と設定します。

2.シリアルコミュニケーションユニット QJ71C24N,QJ71C24N-R2 での設定例 (Qシリーズ)

GX Works2のナビゲーションウインドウのプロジェクトからインテリジェント機能ユニット「QJ71C24N-R2」の「スイッチ設定」を マウスダブルクリックしスイッチ設定ダイアログを表示します。(QJ71C24N-R2は、インテリジェント機能ユニットに登録されている ものとします。)
CH1に設定します。データビット「8」、パリティビット「あり」、奇数/偶数パリティ「奇数」、ストップビット「1」、 サムチェックコード「あり」、RUN中書込み「許可」、通信速度「9600bps」、交信プロトコル「MCプロトコル(形式4)」 と設定します。

3.QシリーズCPUのRS-232Cシリアルポートでの設定例

GX Works2のナビゲーションウインドウのプロジェクトから PCパラメータ マウスダブルクリックでQパラメータ設定ダイアログを表示します。 シリアルコミュニケーション設定ダブを選択します。
「シリアルコミュニケーション機能を使用する」にチェックを入れます。伝送速度を「9.6kBPS」、サムチェック「あり」にチェックを入れ、 伝送ウエイト時間を「ウエイト無し」、RUN中書込設定を「許可する」にチェックを入れます。

■ サンプルソフト

下記サンプルソフトは、レジスタのD0100より10ワード読み込みを行ってます。受信時のサムチェック及び その他のエラー処理は行ってません。「Q」キーで終了します。

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


# coding: utf-8
# QnA互換3Cフレーム形式4 '21.07

require "./wincons"
require "./wincom"

class C24com

  def initialize
    @cons1 = Console.new(__ENCODING__)
    @comp1 = Serial.new
    @icstep = 0
    @irstep = 1
    @srcmd = "0401"          #読み込みコマンド
# Dデバイス読み込み
    @srsbcmd = "0000"        #サブコマンド
    @sdv = "D*"              #Dデバイス
    @itopad = 100            #読み込み先頭
    @ireadsu = 10            #読み込み個数
# Mデバイス読み込み
#    @srsbcmd = "0001"        #サブコマンド
#    @sdv = "M*"              #Mデバイス
#    @itopad = 100            #読み込み先頭
#    @ireadsu = 20            #読み込み個数
  end

  def open
    @comp1.comno = 4
    @comp1.bRate = Serial::CBR_9600
    @comp1.byteSize = 8
    @comp1.parity = Serial::ODDPARITY
    @comp1.fOutxDsrFlow = 0
    @comp1.fDtrControl = Serial::DTR_CONTROL_DISABLE
    ir = @comp1.open
    if ir == nil
       ir = @comp1.escapeCommFunc(Serial::SETDTR)
    end
    return ir
  end

  def rclose
     @comp1.close
  end

  def receive
    sr = @comp1.receive
    if sr != nil
      sr.each_byte{ |c|
        ic = c.to_i
        if @icstep == 1 && (ic == 0x02 || ic == 0x15) #STX,NAK
          @crcvchr = c.chr
          @icstep = 2
        else
          if @icstep == 2
            @crcvchr += c.chr
            if ic == 0x0a
              @icstep = 3
              break
            end
          end
        end
      }
    end
  end

  def sccal(cchr) #サムチェック
    isc = 0
    cchr.each_byte{|c| isc += c }
    sa = format("%4X",isc)
    return sa[2,2]
  end

  def hexchar(cmj)
    srs = ""
    cmj.each_byte{ |c|
      if c >= 0x1f || c <= 0x7b
        srs += sprintf("%#04x",c)
      else
        srs += c.chr
      end
    }
    return srs
  end

  def main
    ir = nil
    case @irstep
      when 1
        csa = "F90000FF00" + @srcmd + @srsbcmd + @sdv + sprintf("%06d",@itopad) + sprintf("%04X",@ireadsu)
        cschar = "¥x05" + csa + sccal(csa) + "¥r¥n"
        @comp1.send(cschar)
#        p hexchar(cschar)
        @icstep = 1
        @irstep = 2
      when 2
        receive
        if @icstep == 3
#          p hexchar(@crcvchr)
          sd = ""; ik = 0
          if @sdv == "D*" then ik = 4 end
          if @sdv == "M*" then ik = 1 end
          for ia in 0..(@ireadsu - 1)
             sd += @crcvchr[11 + ia * ik,ik] + ","
          end
          @cons1.cprint sd + "¥r¥n"
          @irstep = 1
        end
      end
    ca, = @cons1.inkey
    if ca == "q" || ca == "Q"
      rclose
      @irstep = 0
      ir = 1
    end
    return ir
  end

end

c24com1 = C24com.new
ic = c24com1.open
if ic != nil
  print "openエラー " + ic.to_s
end
while ic == nil
  ic = c24com1.main
  sleep 0.01
end
   
参考資料
・MELSECコミュニケーションプロトコルリファレンスマニュアル(三菱電機(株))
Rubyユーティリティ
©2005-2021 TEXCELL CORPORATION
テクセル株式会社