Howto

Armadillo-X1, Armadillo-IoT G3の絶縁RS485アドオンモジュール RS02でModbusの通信をする

Armadillo-X1, Armadillo-IoT G3の絶縁RS485アドオンモジュール RS02を用いてModbus通信を行う方法をご紹介します。
今回は例として、Armadillo-IoT G3をマスタとし、渡辺電機工業製のデジタル入出力モジュール WMB-DIO8Rの制御を行います。

※Armadillo-IoT G3LでModbus通信を行う場合は、Howto : Armadillo-IoT G3LのRS422/RS485シリアルポートでModbusの通信をするを参照してください。

WMB-DIO8Rの通信仕様

WMB-DIO8Rの通信仕様は以下となります。

通信規格ModbusRTU
プロトコルRS-485に準拠
通信方法2線式半二重
エラー検出方式CRC-16
通信速度(設定可能)4800bps、9600bps、19200bps、38400bps
データ長8(固定)
スタートビット1(固定)
パリティービット(設定可能)偶数、奇数、なし
ストップビット(設定可能)1、2(パリティーなしの時のみストップビット2設定可)
スレーブID1~99
終端抵抗約120Ω

WMB-DIO8Rの設定

取扱説明書を参考に、WMB-DIO8Rの各種設定を行います。

通信速度19200bps
パリティビットなし
ストップビット1
スレーブID01

絶縁RS485アドオンモジュール RS02の設定

製品マニュアルを参考に、絶縁RS485アドオンモジュール RS02の設定を行います。

SW1設定値説明
1ON半二重
2ON半二重
3OFFRX 終端抵抗(120Ω) OFF
4ONTX 終端抵抗(120Ω) ON
rs02-RS485addon-setting

Armadillo-IoT G3とWMB-DIO8Rの配線

Armadillo-IoT G3とWMB-DIO8Rの配線を行います。

WMB-DIO8R側の配線

・WMB-DIO8Rの制御電源(電源+端子,電源-端子)に+24V、0Vを接続します。
・WMB-DIO8RのModbus通信端子(SG)にSG用の配線を接続します。
・WMB-DIO8RのModbus通信端子(通信+端子,通信-端子)に信号線DATA+、DATA-を接続します。
・WMB-DIO8RのModbus通信端子(通信+端子,通信-端子)の信号線DATA+、DATA-の間に120Ωの終端抵抗を接続します。

Armadillo-IoT G3側の配線

・Armadillo-IoT G3のCON4(ピン番号1)にSG用の配線を接続します。
・Armadillo-IoT G3のCON4(ピン番号2,3)に信号線DATA-、DATA+を接続します。

全体図

配線図

サンプルプログラムの作成

今回はC言語を用いて、WMB-DIO8RのDIGITAL OUTPUTのピン番号4をon/offさせるプログラムを作成します。

Armadillo-IoT G3の起動

Armadillo-IoT G3を起動します。

必要なパッケージのインストール

サンプルプログラムの実行に必要なライブラリをインストールします。

root@armadillo:~# apt-get update
root@armadillo:~# apt-get install libmodbus-dev

WMB-DIO8Rへの送信パケット

WMB-DIO8R 取扱説明書(Modbus通信仕様書)の「表 5.34 デジタル出力(DO)への出力制御 」を参考に、DIGITAL OUTPUTのピン番号4の制御するための送信パケットを書き出すと次のようになります。

送信パケットの内容
内容説明
スレーブID0x01WMB-DIO8RのスレーブID
機能コード0x05コイル 書き込み
開始アドレス(上位)0x00
開始アドレス(下位)0x03DIGITAL OUTPUTのピン番号4
データ(上位)0xFF または 0x00DIGITAL OUTPUTのon/off
データ(下位)0x00

送信パケットの内容を元に、サンプルプログラムを作成します。

サンプルプログラムのダウンロード

wmb-dio8r-ctrl.tar.gzをダウンロードします。

root@armadillo:~# wget http://download.atmark-techno.com/sample/armadillo-iot-x1-g3-modbus/wmb-dio8r-ctrl.tar.gz

wmb-dio8r-ctrl.tar.gzを展開します。

root@armadillo:~# tar zxvf wmb-dio8r-ctrl.tar.gz

wmb-dio8r-ctrlディレクトリに、wmb-dio8r-ctrl.cとMakefileがあることを確認して下さい。

root@armadillo:~# cd wmb-dio8r-ctrl
root@armadillo:~/wmb-dio8r-ctrl# ls
Makefile  wmb-dio8r-ctrl.c

サンプルプログラムの実装

サンプルプログラムwmb-dio8r-ctrl.cは、次のように実装されています。

/* Copyright (c) 2018 Atmark Techno, Inc.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <modbus.h>

#define SERIAL_SPEED 19200
#define SERIAL_PARITY 'N'
#define SERIAL_DATABIT 8
#define SERIAL_STOPBIT 1

int main(int argc, char *argv[])
{
    static uint8_t raw_req[] = { 0x01, 0x05, 0x00, 0x03, 0x00, 0x00 }; /* 送信パケット */
    uint8_t rsp[MODBUS_TCP_MAX_ADU_LENGTH];
    int ret = EXIT_SUCCESS;
    int raw_req_size = sizeof (raw_req) / sizeof (raw_req[0]);
    int req_length;
    int rsp_length;
    modbus_t *ctx;

    if (argc <= 2) {
        printf("Usage: %s <device> <on/off>\n\n", argv[0]);
        return EXIT_SUCCESS;
    }

    if (!strcmp(argv[2], "on")) {
        raw_req[4] = 0xFF;
    } else if (!strcmp(argv[2], "off")) {
        raw_req[4] = 0x00;
    } else {
        printf("Usage: %s <device> <on/off>\n\n", argv[0]);
        return EXIT_SUCCESS;
    }

    ctx = modbus_new_rtu(argv[1], SERIAL_SPEED, SERIAL_PARITY, SERIAL_DATABIT, SERIAL_STOPBIT);
    if (ctx == NULL) {
        fprintf(stderr, "Unable to allocate libmodbus context\n"
            "modbus error\n");
        return EXIT_FAILURE;
    }

    modbus_set_debug(ctx, TRUE);
    modbus_set_error_recovery(ctx, MODBUS_ERROR_RECOVERY_LINK | MODBUS_ERROR_RECOVERY_PROTOCOL );
    if (modbus_connect(ctx) == -1) {
        fprintf(stderr, "Connection failed: %s\n"
            "modbus error\n",
            modbus_strerror(errno));
        modbus_free(ctx);
        return EXIT_FAILURE;
    }

    req_length = modbus_send_raw_request(ctx, raw_req, raw_req_size);
    if (req_length < 0 ) { 
        fprintf(stderr, "faild: %s\n"
            "modbus error\n",
            modbus_strerror(errno));
        ret = EXIT_FAILURE;
    }

    rsp_length = modbus_receive_confirmation(ctx, rsp);
    if (rsp_length < 0 ) { 
        fprintf(stderr, "faild: %s\n"
            "modbus error\n",
            modbus_strerror(errno));
        ret = EXIT_FAILURE;
    }

    modbus_close(ctx);
    modbus_free(ctx);

    return ret;
}

WMB-DIO8Rへの送信パケットの一部には、ベンダーが独自に定義したパケットが使われています。
libmodbusの標準関数ではベンダーが独自に定義したパケットを送信するための専用関数は用意されていません。そこで、本サンプルプログラムではmodbus_send_raw_request関数を使用し、ソースコード内に記載したパケットをそのまま送信するようにしています。

※libmodbusの標準関数を用いてパケットを送信する場合は、Howto : Armadillo-400シリーズでModbusの通信をするを参考にして下さい。

ビルド方法

ソースコードのビルドを行います。

root@armadillo:~/wmb-dio8r-ctrl# make

動作確認方法

WMB-DIO8Rの電源投入

WMB-DIO8Rの電源を入れて下さい。

サンプルプログラムの実行

サンプルプログラムを実行します。
※サンプルプログラムの引数に指定するデバイス名は、Armadillo-X1とArmadillo-IoT G3で異なるため注意して下さい。

Armadillo-X1でサンプルプログラムを実行する場合
root@armadillo:~/wmb-dio8r-ctrl# ./wmb-dio8r-ctrl /dev/ttymxc6 on 
Opening /dev/ttymxc0 at 19200 bauds (N, 8, 1)
[01][05][00][03][FF][00][7C][3A]
Waiting for a confirmation...
<01><05><00><03><FF><00><7C><3A>
root@armadillo:~# 
Armadillo-IoT G3でサンプルプログラムを実行する場合
root@armadillo:~/wmb-dio8r-ctrl# ./wmb-dio8r-ctrl /dev/ttymxc0 on 
Opening /dev/ttymxc0 at 19200 bauds (N, 8, 1)
[01][05][00][03][FF][00][7C][3A]
Waiting for a confirmation...
<01><05><00><03><FF><00><7C><3A>
root@armadillo:~# 

実行結果

DIGITAL OUTPUTのピン番号4がon(LEDが点灯)になれば、通信成功です。

注意点

・本Howtoは、渡辺電機工業株式会社製のデジタル入出力モジュール WMB-DIO8Rとの接続例を記載したものです。
 Modbus通信を行う全ての機器の動作を保証するものではありませんので、ご注意下さい。
・本Howtoは、簡易的な手順を示したものです。エラー処理等は考慮されていません。
 本格的に運用する際は、電気的特性、ノイズ等を考慮した回路設計、エラー処理、フェイルセーフ等のソフト設計を行う必要があります。