EtherCAT開発方法 フレーム編（リードまで）

この記事は [EtherCATについて語る Advent Calendar 2019](https://adventar.org/calendars/4097) の9日目です。
昨日はlipoyangさんの [EtherCATマスターSOEMをマイコンに移植する - 滴了庵日録](https://lipoyang.hatenablog.com/entry/2019/12/08/101951) でした。

#はじめに

EtherCAT開発方法 フレーム編です。
EtherCATのフレームについて話を進めていきますが、フレームの概要については著者の書籍に記載されてますので、特別１ページ公開します。詳しく読みたい方は、以下のリンクより好評発売中です。
[★EtherCATマスターブック 第1巻](https://www.switch-science.com/catalog/5919/)

また、英語になりますが、原書とも言われるET1100の資料も合せて読むとわかりやすいです。
[EtherCAT Registers Section II](https://download.beckhoff.com/download/Document/io/ethercat-development-products/ethercat_esc_datasheet_sec2_registers_2i9.pdf)

そのフレームの知識を利用して、実際に開発する方法について後半話します。

この内容を実際に試すためには、以下の環境を用意する必要があります。
また、他の環境でも同様に試せると思いますが、試し方については各々で調整していただければと思います。

##ArtifactNoise開発モデル
- Raspberry Pi 3B+ (4BやJetson Nano、Ubuntuデスクトップなど)
- [PyEtherCAT](https://github.com/pyEtherCAT)
- [EtherCATスレーブ評価基板LAN9252使用](https://www.switch-science.com/catalog/5917/)
- [LED16モジュール](https://www.switch-science.com/catalog/5918/)

**※本ライブラリは、WindowsやMac OSでは、セキュリティーの関係で動作しません。**


#EtherCATのパケットについて
![C9613.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/4bf91d46-8a99-d18e-92ac-fe7cc6efbca7.png)

パケットについては[EtherCATマスターブック 第1巻](https://www.switch-science.com/catalog/5919/)に書きまとめてしまったので、その項目の１ページを公開します。


#EtherCATのコマンドについて
![C9617.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/2d7b2131-1f7a-fedf-fc04-3833cd42b047.png)

コマンドについても[EtherCATマスターブック 第1巻](https://www.switch-science.com/catalog/5919/)に書きまとめてしまったので、その項目の１ページを公開します。

#通信方法

では、そのフレームを使ってEtherCATスレーブにアクセスする方法についてです。

まず、EtherCATのスレーブICには**EtherCATコアレジスタ**という、スレーブ機器に共通のアドレス空間があり、どのスレーブ機器にもアクセス出来れば、大凡同じ内容と思われます。

以下はLAN9252のデーターシート内にあるレジスタの内容です。

![スクリーンショット 2019-12-08 20.17.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/47760f30-762d-9178-e84a-d9c0e36df86a.png)
http://ww1.microchip.com/downloads/jp/DeviceDoc/00001909A_JP.pdf

このレジスタアドレスに、先ほど説明したEtherCATフレームでアクセスしていきます。

[PyEtherCAT](https://github.com/pyEtherCAT)を元に話を進めていきます。

#製品IDレジスタの読み出し

![スクリーンショット 2019-12-08 20.30.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/f08b04b8-7d23-6cec-d8ff-73d0b4cbef0c.png)

コアレジスタの中に製品IDレジスタと製造者IDレジスタがあります。二つとも読出し専用ですので、固定値が読み出せます。
自作したフーレムが正しく動くかどうかを確認する際に、このレジスタは非常に便利です。
LAN9252では、以下のように説明があります。
![スクリーンショット 2019-12-08 20.31.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/df2644d3-20f8-14dd-68c8-e3e1e666d92e.png)
注意が必要なのは、レジスタの幅（サイズ）は可変長です。今回の製造IDは64ビットですが、8ビットや16,32ビットのバスもあります。このビット幅はコマンドで指定ができますが、64ビット幅のレジスタを16ビットで読み出すと最初の16ビット分しか読み出されません（指定したアドレスからプラスいくつで読みに行くため）

実際に動かして見ましょう。
Raspberry Pi で、以下のリポジトリをダウンロードします。　（Ubuntuならデスクトップでも動きます)

```
git clone  https://github.com/pyEtherCAT/EtherCAT_Master.git
cd EtherCAT_Master
```

それでは、以下の分を新規ファイルを作り、ソースを書き込んでいきます。

```python3:readtest.py
from pyEtherCAT import MasterEtherCAT #ライブラリの読出し
nic = "eth0" # ネットワークカードのアドレスを記載
cat = MasterEtherCAT.MasterEtherCAT(nic)  

ADP = 0x0000 #1台目
ADDR = 0x0E00 #コアレジスタのアドレス
cat.APRD(IDX=0x00, ADP=ADP, ADO=ADDR, DATA=[0,0,0,0,0,0,0,0]) #DATAは０を８個(64bit分)の枠を指示
(DATA, WKC) = cat.socket_read() #結果を読出し
print("[0x{:04X}]= 0x{:02x}{:02x},0x{:02x}{:02x},0x{:02x}{:02x},0x{:02x}{:02x}".format(ADDR, DATA[7],DATA[6],DATA[5],DATA[4],DATA[3],DATA[2],DATA[1],DATA[0]))
#読み出したデータを表示する

```

このソースを、sudoコマンドで実行します。
```
sudo python3 readtest.py
[0x0E00]= 0x0000,0x0004,0x9252,0x0001
```
読み出せましたね。

コマンドの部分を軽く説明すると、

- APRD(自動インクリメント物理リード)を使用して、レジスタの中身を読み出します。
- ADPは、自動インクルメントなので、機器に接続された１台目を読みにいきます。２台目を読む際は-1をします。
- ADDRは、コアレジスタのアドレスを指定します。製造IDは0x0E00なので、それを指定します。
- DATAが変なことになっていますが、配列サイズ（１行８ビット）で８配列分（64ビット）を指定します。
- socket_readが読み出しの関数です。
- DATAの中に８配列分（64ビット)が含まれるので、それを展開します。

以上の呼び出し方で、コアレジスタの中身を読みに行く事ができます。

同様に、製造者IDを読みに行くと、以下のようになると思います。

```
[0x0E08]= 0x0000,0x0000,0x0000,0x04D8
```

#続きは・・・

やばい、一日分では終わらない話だった。
次回はリードが出来たので、ライトについて説明します。

それでは！！
（宣伝が多いですが、他のモジュールを触った事無いしライブラリも触った事ないので、他の方の手法について説明が出来なくて申し訳ないです。他の手法については、他の方がきっとまとめてくれると思いますので、そちらもご覧いただければ幸いです。）

なお、本文章は、２月もしくは５月に発行予定の第２巻に記載予定の物が含まれます。


北神(@nonNoise )