どうも、もももです。
MOXA社のioLogik E1200シリーズを利用してVB.NETでデジタル入出力を行う方法を紹介します。
MOXA社 ioLogik E1200シリーズとは
MOXA社のイーサーネットリモートI/Oです。
アナログ入出力やデジタル入出力、リレー出力など、対応しています。
今回はVB.NETでソケット通信-Modbus/TCPプロトコルを使用して通信を行います。
Modbus/TCPのデータフォーマット
Modbus/TCPのデータフォーマットについてまとめます。

- 転送ID:今回は使用せず。→0で固定
- プロトコルID:今回は使用せず。→0で固定
- 転送バイト数:Byte No=6のユニットID以下の総バイト数を指定する。
- ユニットID:今回は使用せず。→1で固定
- 機能コード:読み取り/書き込み内容に応じて設定する。※設定内容は機能コード(Byte)を参照
- 転送データ:対象ポート、対象範囲、出力内容等を設定する。
機能コード

Bit読み取りについて調べていると
- 1:Read Coils
- 2:Discrete Input
と、あったのですが今回は「2」を指定しないと読み取りを行えませんでした。
※詳細が分かり次第、追記します。
Bit読み取りデータサンプル

Bit読み取りメッセージの送受信例になります。
送信メッセージ:先頭のポートから1点のBit状態を読取ります。
受信メッセージ:ByteNo=8がデータのバイト数、ByteNo=9が読み取り内容となります。
※サンプルの例だと入力0ポートはON(=1)です。

対象アドレスが入力0ポートで範囲を今回最大の6点とした場合、読み取り値は上図のようにON箇所の値を合計した値になります。
例)入力1, 5ポートがONの場合⇒2+32=34が読み取り値になります。
Bit書き込みデータサンプル

Bit書き込みメッセージの送受信例になります。
送信メッセージ:先頭出力ポートに対してONを指定(255-0)、OFFの場合は0-0
受信メッセージ:送信メッセージと同じ内容になります。
構成イメージ

ioLogik E1200シリーズの電源はDC24VでEthernetケーブルでパソコンと接続します。
サンプルプログラム

Imports System.Net.Sockets
Public Class Form1
Dim _socket As Socket =
New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim ipAddress As String = "192.168.127.254"
Dim portNo As Integer = 502
_socket.Connect(ipAddress, portNo)
End Sub
Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
_socket.Close()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'送信メッセージ作成
Dim sendMessage(11) As String
sendMessage(0) = "00" '0で固定
sendMessage(1) = "00" '0で固定
sendMessage(2) = "00" '0で固定
sendMessage(3) = "00" '0で固定
sendMessage(4) = "00" '0で固定
sendMessage(5) = "06" 'Byte6 以降の総バイト数
sendMessage(6) = "01" '1で固定
sendMessage(7) = "02" 'Modbus/TCPの機能コード 02/05
sendMessage(8) = "00" '開始アドレス1
sendMessage(9) = "00" '開始アドレス2
sendMessage(10) = "00" ' 範囲 1点のみ 00-01
sendMessage(11) = "01" ' 範囲 1点のみ 00-01
'メッセージ送信&受信
Dim byteReciveMessage = SendAndRecieve(sendMessage)
Me.TextBox1.Text = byteReciveMessage(9)
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
'送信メッセージ作成
Dim sendMessage(11) As String
sendMessage(0) = "00" '0で固定
sendMessage(1) = "00" '0で固定
sendMessage(2) = "00" '0で固定
sendMessage(3) = "00" '0で固定
sendMessage(4) = "00" '0で固定
sendMessage(5) = "06" 'Byte6 以降の総バイト数
sendMessage(6) = "01" '1で固定
sendMessage(7) = "05" 'Modbus/TCPの機能コード
sendMessage(8) = "00" '開始アドレス1
sendMessage(9) = "00" '開始アドレス2
If Me.RadioButton1.Checked Then
sendMessage(10) = "FF" ' FF-00でON
sendMessage(11) = "00" ' FF-00でON
Else
sendMessage(10) = "00" ' 00-00でOFF
sendMessage(11) = "00" ' 00-00でOFF
End If
'メッセージ送信&受信
Dim byteReciveMessage = SendAndRecieve(sendMessage)
End Sub
Private Function SendAndRecieve(sendMessage As String()) As Byte()
'送信メッセージを変換 String⇒Byte
Dim byteSendMessage As Byte() = StringsToBytes(sendMessage)
'メッセージ送信
_socket.Send(byteSendMessage, byteSendMessage.GetLength(0), SocketFlags.None)
'応答メッセージを受信
Dim byteReciveMessage As Byte()
Dim reciveSize As Integer = 0
Do
byteReciveMessage = New Byte(_socket.Available - 1) {}
reciveSize =
_socket.Receive(byteReciveMessage, byteReciveMessage.GetLength(0), SocketFlags.None)
Loop While reciveSize = 0
Return byteReciveMessage
End Function
Private Function StringsToBytes(src() As String) As Byte()
Dim returnBytes(src.Length - 1) As Byte
'1要素ずつ変換
Dim i As Integer
For i = 0 To src.Length - 1
returnBytes(i) = Convert.ToByte(src(i), 16)
Next
Return returnBytes
End Function
End Class
コード解説
上記は「Bit読み取り」ボタンを押下すると、先頭入力ポートの内容を「Bit読み取り」 テキストに表示し、「Bit書き込み」ボタンを押下するとラジオボタンの状態に応じて先頭出力ポートをON/OFFするサンプルプログラムです。
・フォーム ロードイベント(8~13行)
画面起動時にソケット通信を確立します。
MOXA社のioLogik E1214の デフォルトIPアドレスは「192.168.127.254」で使用するポート番号は「502」です。
・フォーム クローズドイベント(15~17行)
画面終了時にソケット通信をクローズします。
・Bit読み取りボタン クリックイベント(19~42行)
Bit読み取りの要求メッセージをString配列で作成⇒送信し、応答メッセージの内容をテキストボックスに反映します。(ONの場合は1、OFFの場合は0)
・Bit書き込みボタン クリックイベント(44~69行)
Bit書き込みの要求メッセージをString配列で作成⇒送信しています。
・メッセージの送受信処理(71~100行)
引数のString配列をByte配列に変換して要求メッセージとして送信し、応答メッセージを戻り値として返します。
今回のサンプルでは分かりやすいようにあえて、要求メッセージをString配列で作成しましたが、最初からByte配列で作成した方がプログラムはシンプルになると思います。
また、ソケット通信の詳細については下記でも紹介しています。
まとめ
MOXA社のioLogik E1200シリーズを利用してVB.NETでデジタル入出力を行う方法についてまとめました。
このリモートI/Oを活用することで、PLCが無くてもパソコンでセンサやスイッチの入力を取り込めるようになります。
簡単な計測アプリケーションの信号入力などに大活躍です。
下記はアプリケーションの作成例になります。



コメント
はじめまして コブラツイストと申します。
参考になる説明、プログラムありがとうございます。
最近、このユニットを購入してマニュアルを調べてたところです。
下記の内容について記載されてましたがマニュアルとかあるのでしょうか
(※公式WEBサイトを見ても なかった感じでしたので)
転送ID:プロトコルID:転送バイト数:ユニットID:機能コード:転送データ:
色々調べたのですが
MODBUSのフォーマットって決まってるの知りませんでした。
MCプロトコルみたいな感じでメーカ独自のフォーマットが
あるのかと思いました。
サンプルプログラムをVB6でテストしたら 通信できました。
コメントありがとうございます。
仰る通り「ModbusTCP」という通信プロトコルをソケット通信で使用しています。
サンプルプログラムがお役に立てたようで良かったです!