この記事は EtherCATについて語る Advent Calendar 2019 の9日目です。
昨日はlipoyangさんの EtherCATマスターSOEMをマイコンに移植する - 滴了庵日録 でした。
#はじめに
EtherCAT開発方法 フレーム編です。
EtherCATのフレームについて話を進めていきますが、フレームの概要については著者の書籍に記載されてますので、特別1ページ公開します。詳しく読みたい方は、以下のリンクより好評発売中です。
★EtherCATマスターブック 第1巻
また、英語になりますが、原書とも言われるET1100の資料も合せて読むとわかりやすいです。
EtherCAT Registers Section II
そのフレームの知識を利用して、実際に開発する方法について後半話します。
この内容を実際に試すためには、以下の環境を用意する必要があります。
また、他の環境でも同様に試せると思いますが、試し方については各々で調整していただければと思います。
##ArtifactNoise開発モデル
- Raspberry Pi 3B+ (4BやJetson Nano、Ubuntuデスクトップなど)
- PyEtherCAT
- EtherCATスレーブ評価基板LAN9252使用
- LED16モジュール
※本ライブラリは、WindowsやMac OSでは、セキュリティーの関係で動作しません。
パケットについてはEtherCATマスターブック 第1巻に書きまとめてしまったので、その項目の1ページを公開します。
コマンドについてもEtherCATマスターブック 第1巻に書きまとめてしまったので、その項目の1ページを公開します。
#通信方法
では、そのフレームを使ってEtherCATスレーブにアクセスする方法についてです。
まず、EtherCATのスレーブICにはEtherCATコアレジスタという、スレーブ機器に共通のアドレス空間があり、どのスレーブ機器にもアクセス出来れば、大凡同じ内容と思われます。
以下はLAN9252のデーターシート内にあるレジスタの内容です。
http://ww1.microchip.com/downloads/jp/DeviceDoc/00001909A_JP.pdf
このレジスタアドレスに、先ほど説明したEtherCATフレームでアクセスしていきます。
PyEtherCATを元に話を進めていきます。
#製品IDレジスタの読み出し
コアレジスタの中に製品IDレジスタと製造者IDレジスタがあります。二つとも読出し専用ですので、固定値が読み出せます。
自作したフーレムが正しく動くかどうかを確認する際に、このレジスタは非常に便利です。
LAN9252では、以下のように説明があります。
注意が必要なのは、レジスタの幅(サイズ)は可変長です。今回の製造IDは64ビットですが、8ビットや16,32ビットのバスもあります。このビット幅はコマンドで指定ができますが、64ビット幅のレジスタを16ビットで読み出すと最初の16ビット分しか読み出されません(指定したアドレスからプラスいくつで読みに行くため)
実際に動かして見ましょう。
Raspberry Pi で、以下のリポジトリをダウンロードします。 (Ubuntuならデスクトップでも動きます)
git clone https://github.com/pyEtherCAT/EtherCAT_Master.git
cd EtherCAT_Master
それでは、以下の分を新規ファイルを作り、ソースを書き込んでいきます。
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は0を8個(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台目を読みにいきます。2台目を読む際は-1をします。
- ADDRは、コアレジスタのアドレスを指定します。製造IDは0x0E00なので、それを指定します。
- DATAが変なことになっていますが、配列サイズ(1行8ビット)で8配列分(64ビット)を指定します。
- socket_readが読み出しの関数です。
- DATAの中に8配列分(64ビット)が含まれるので、それを展開します。
以上の呼び出し方で、コアレジスタの中身を読みに行く事ができます。
同様に、製造者IDを読みに行くと、以下のようになると思います。
[0x0E08]= 0x0000,0x0000,0x0000,0x04D8
#続きは・・・
やばい、一日分では終わらない話だった。
次回はリードが出来たので、ライトについて説明します。
それでは!!
(宣伝が多いですが、他のモジュールを触った事無いしライブラリも触った事ないので、他の方の手法について説明が出来なくて申し訳ないです。他の手法については、他の方がきっとまとめてくれると思いますので、そちらもご覧いただければ幸いです。)
なお、本文章は、2月もしくは5月に発行予定の第2巻に記載予定の物が含まれます。
北神(@nonNoise )