WindowsでEtherCATマスター

Windows PCでLANポートを用いてEtherCATマスターを動作させる方法のメモ。
(2019/12/29 加筆修正)

SOEMとは?

SOEM (Simple Open EtherCAT Master) とは、Open EtherCAT Society が提供しているオープンソースの小規模なEtherCATマスターのスタック。ソースコードGitHubで公開されている。ちなみにEtherCATスレーブのスタックとして SOES (Simple Open EtherCAT Slave) も提供されている。

SOEMのファイル構成

f:id:licheng:20191229124419p:plain

SOEMのビルド

mkdir build
cd build
cmake .. -G "NMake Makefiles"
nmake
  • 成功するとbuild/test/linux/slaveinfo/slaveinfo.exe などのサンプルプログラムのバイナリができる
    • win32フォルダでなくlinuxフォルダだが気にしない

サンプルプログラム slaveinfo

サンプルプログラム slaveinfo はスレーブ機器の情報を取得するプログラムである。
まず引数なしで実行すると、ネットワークインターフェース一覧が表示される。

cd test\linux\slaveinfo
slaveinfo.exe

【実行結果1】

SOEM (Simple Open EtherCAT Master)
Slaveinfo
Usage: slaveinfo ifname [options]
ifname = eth0 for example
Options :
 -sdo : print SDO info
 -map : print mapping
Available adapters
Description : NICの名前1: \Device\NPF_{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
Description : NICの名前2: \Device\NPF_{YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY}
Description : NICの名前3: \Device\NPF_{ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ}
End program

次に下記のようにネットワークインターフェースを指定して実行する。

slaveinfo.exe \Device\NPF_{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}

【実行結果2】
スレーブ機器が未接続の場合は No slaves found! となる。

SOEM (Simple Open EtherCAT Master)
Slaveinfo
Starting slaveinfo
ec_init on \Device\NPF_{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} succeeded.
No slaves found!
End slaveinfo, close socket
End program

【実行結果3】
スレーブ機器としてArduino Uno + EasyCAT Shield (詳しくはこちらの記事を参照) を2台接続した場合。
2台のスレーブ機器の情報が表示される。

SOEM (Simple Open EtherCAT Master)
Slaveinfo
Starting slaveinfo
ec_init on \Device\NPF_{B6BA5E14-3DA8-4D53-A579-7557EC6F1195} succeeded.
2 slaves found and configured.
Calculated workcounter 6

Slave:1
 Name:EasyCAT 32+32 rev 1
 Output size: 256bits
 Input size: 256bits
 State: 4
 Delay: 0[ns]
 Has DC: 1
 DCParentport:0
 Activeports:1.1.0.0
 Configured address: 1001
 Man: 0000079a ID: 00defede Rev: 00005a01
 SM0 A:1000 L:  32 F:00010064 Type:3
 SM1 A:1200 L:  32 F:00010020 Type:4
 FMMU0 Ls:00000000 Ll:  32 Lsb:0 Leb:7 Ps:1000 Psb:0 Ty:02 Act:01
 FMMU1 Ls:00000040 Ll:  32 Lsb:0 Leb:7 Ps:1200 Psb:0 Ty:01 Act:01
 FMMUfunc 0:1 1:2 2:0 3:0
 MBX length wr: 0 rd: 0 MBX protocols : 00
 CoE details: 00 FoE details: 00 EoE details: 00 SoE details: 00
 Ebus current: 0[mA]
 only LRD/LWR:0

Slave:2
 Name:EasyCAT 32+32 rev 1
 Output size: 256bits
 Input size: 256bits
 State: 4
 Delay: 740[ns]
 Has DC: 1
 DCParentport:1
 Activeports:1.0.0.0
 Configured address: 1002
 Man: 0000079a ID: 00defede Rev: 00005a01
 SM0 A:1000 L:  32 F:00010064 Type:3
 SM1 A:1200 L:  32 F:00010020 Type:4
 FMMU0 Ls:00000020 Ll:  32 Lsb:0 Leb:7 Ps:1000 Psb:0 Ty:02 Act:01
 FMMU1 Ls:00000060 Ll:  32 Lsb:0 Leb:7 Ps:1200 Psb:0 Ty:01 Act:01
 FMMUfunc 0:1 1:2 2:0 3:0
 MBX length wr: 0 rd: 0 MBX protocols : 00
 CoE details: 00 FoE details: 00 EoE details: 00 SoE details: 00
 Ebus current: 0[mA]
 only LRD/LWR:0
End slaveinfo, close socket
End program

さらに下記のようにオプションに -map を指定して実行する。

simple_test.exe \Device\NPF_{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} -map

スレーブ機器の情報に追加してPDOマッピング情報が表示される。

(前略)
Slave:1
 Name:EasyCAT 32+32 rev 1
(中略)
PDO mapping according to SII :
  SM0 RXPDO 0x1600 Outputs
     addr b   index: sub bitl data_type    name
  [0x0000.0] 0x0005:0x01 0x08 UNSIGNED8    Byte0
  [0x0001.0] 0x0005:0x02 0x08 UNSIGNED8    Byte1
  [0x0002.0] 0x0005:0x03 0x08 UNSIGNED8    Byte2
(中略)
  [0x001D.0] 0x0005:0x1E 0x08 UNSIGNED8    Byte29
  [0x001E.0] 0x0005:0x1F 0x08 UNSIGNED8    Byte30
  [0x001F.0] 0x0005:0x20 0x08 UNSIGNED8    Byte31
  SM1 TXPDO 0x1A00 Inputs
     addr b   index: sub bitl data_type    name
  [0x0040.0] 0x0006:0x01 0x08 UNSIGNED8    Byte0
  [0x0041.0] 0x0006:0x02 0x08 UNSIGNED8    Byte1
  [0x0042.0] 0x0006:0x03 0x08 UNSIGNED8    Byte2
(中略)
  [0x005D.0] 0x0006:0x1E 0x08 UNSIGNED8    Byte29
  [0x005E.0] 0x0006:0x1F 0x08 UNSIGNED8    Byte30
  [0x005F.0] 0x0006:0x20 0x08 UNSIGNED8    Byte31

Slave:2
(後略)

サンプルプログラム simple_test

サンプルプログラム simple_test は簡単な通信テストのプログラムである。
下記のようにネットワークインターフェースを指定して実行する。

cd test\linux\simple_test
simple_test.exe \Device\NPF_{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}

するとスレーブとの通信が周期的に行われ、その様子が表示される。

SOEM (Simple Open EtherCAT Master)
Simple test
Starting simple test
ec_init on \Device\NPF_{B6BA5E14-3DA8-4D53-A579-7557EC6F1195} succeeded.
2 slaves found and configured.
Slaves mapped, state to SAFE_OP.
segments : 1 : 128 0 0 0
Request operational state for all slaves
Calculated workcounter 6
Operational state reached for all slaves.
^Cocessdata cycle 2818, WKC 6 , O: 00 00 00 00 00 00 00 00 I: 02 14 00 00 02 4b 00 41 T:630773536452882240

…が、正直なところこの表示だけを見てもピンと来ない。
ソースファイルはtest\linux\simple_test\simple_test.cにあるので、ソースを解読したり書き換えて実験したりして理解を深める。

おまけ:ネットワークインターフェース名の取得方法いろいろ

ネットワークインターフェース名は、PowerShellで下記を実行しても取得できる。

Get-NetAdapter | select Name,DeviceName

【実行結果】

Name                DeviceName
----                ----------
NICの名前1 \Device\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
NICの名前2 \Device\{YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY}
NICの名前3 \Device\{ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ}

また、ネットワークインターフェース名は、C#アプリからは下記のようにして取得できる。

using System;
using System.Net.NetworkInformation;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var interfaces = NetworkInterface.GetAllNetworkInterfaces();
            foreach (var ni in interfaces)
            {
                Console.WriteLine($"{ni.Id},{ni.Name}");
            }
        }
    }
}

【実行結果】

{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX},NICの名前1
{YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY},NICの名前2
{ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ},NICの名前3