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