見出し画像

Modbus TCPを使用してRS-485機器(Modbus RTU)から値を取得

目的

以下の構成で各RS-485機器から値を取得できるかどうか検証する。

システム構成図

検証環境

  • Armadillo(最終的に本機で通信する)

    • OS:Debian

    • Modbus通信ソフト:Python3.8、pymodbus

  • ノートPC(プログラム開発、テスト用)

    • OS:Windows10 Pro

    • Modbus通信ソフト:Python3.8、pymodbus

  • Moxa Mgate MB 3170(Modbusゲートウェイ)

  • OMRON電力計

  • OMRON温調

ArmadilloやPC、OMRON機器についての設定は割愛する

Moxa初期設定手順

マニュアルに従い、下記のように接続する。

電源(12V-48V・直流、赤が+、青が-)
RS-485(黄が+、青が-)

今回は短距離/テストのため終端抵抗を設定しないが、moxaの場合は側面のカバーを開けたところに終端抵抗設定用のディップスイッチ(110Ω)が存在する。

moxa以外の接続は割愛

電源を入れるとmoxaの横にデフォルトのIPアドレスが記載されているため、ブラウザでアクセスする。
http://192.168.127.254
ユーザー名:admin
パスワード:moxa

ログイン画面

ログインできたらHomeをクリック

Welcome画面
MainMenu画面

Basic Settingsを選択。Server nameを「MB3170」に変更してSubmit
(必要に応じてTime serverを設定すること)
※ここでいうServer nameは「ホスト名」では無い!

設定は変更したが、Rebootしないと反映されない。
今回は「Restart」としてRebootする。以後はまとめて変更するかどうかは状況に応じて行うこと。

再度ログインして、Home画面に移動してから「NetWork settings」
「DHCP」にしてから、「Submit」

RDYのLEDが赤点滅だと、DHCPでIPアドレスを取得中。
問題なく取得できるとRDYのLEDが緑点灯となる。
DHCPでIPアドレスが変更となってしまうので
同一ネットワークでの探索ツールを使用して、探す
(今回は192.168.130.19)
http://192.168.130.19
IPアドレス等を確認

「Serial Settings」をクリック
Modbus RTUの設定内容を入力し、Submit

ここまで行えば、最低限のModbus TCP通信が可能。

PCでのPythonプログラムの実行


PCからPythonプログラムを作成し、実行
Modbus TCPを使う。モジュールはpymodbusを採用

import threading
from pymodbus.client.sync import ModbusTcpClient
import time
import datetime

def get_modbus_tcp_DI():
    dt = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")

    try:
        result = client.read_holding_registers(8192, 1, unit=1)
        print(dt, ",", result.registers[0])

    except:
        print(dt, ",")

    try:
        result = client.read_holding_registers(0, 2, unit=5)
        print(dt, ",", result.registers[1])

    except:
        print(dt, ",")

if __name__ == '__main__':
    interval = 1
    # 基準時刻の生成
    base_time = datetime.datetime.now()

    client = ModbusTcpClient('192.168.130.19', 502, timeout=0.8)
    client.connect()

    while True:
        # 処理を別スレッドで実行する
        t1 = threading.Thread(target=get_modbus_tcp_DI)
        t1.start()

        # 基準時刻と現在時刻の差分から、次の実行時間を計算する
        current_time = datetime.datetime.now()
        diff_sec = (current_time - base_time).total_seconds()
        sleep_sec = interval - (diff_sec % interval)

        time.sleep(max(sleep_sec, 0))

    client.close()

注意点:今回はwhileループ前にコネクトし、それから実行をModbusコマンドを送信している(毎回コネクト、クローズを実行すると1秒以内に処理が終わらない。ADVANTECHのModbusTCPであれば毎回コネクト、クローズしても問題なかった)
注意点2:上記プログラムでしばらく通信してから、5分ほど放置し、再度接続すると接続できない状態(pingも返ってこない)になる。この場合、プログラム開始させると約2分後には復帰する。(無線スイッチ側の問題かも)

c:\\dys\\tmp>python main.py
2022/05/09 17:51:04 , 222
2022/05/09 17:51:04 , 1045
2022/05/09 17:51:05 , 222
2022/05/09 17:51:05 , 1045
2022/05/09 17:51:06 , 222
2022/05/09 17:51:06 , 1045

Armadilloでの実行


WinSCPでコピーする。

TeraTermで接続と実行


この記事が気に入ったらサポートをしてみませんか?