日記；回すだけⅣ ⑤ ラズパイ＋EPOS4、C++でプログラミング＜ライブラリの準備＞


　C++はラズパイに入っています。必要なEPOS4のライブラリをインストールします。

### 環境
- Raspberry Pi 4 Model B 2GB
- Raspberry Pi OS with desktop。Release date: April 4th 2022
　最新の環境にします。

```cpp
sudo apt-get update
sudo apt-get upgrade -y
reboot
uname -a
Linux pi2 5.15.32-v7l+ #1538 SMP Thu Mar 31 19:39:41 BST 2022 armv7l GNU/Linux
```

　maxonのWebです。

![maxon1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/b8927c3b-a1e5-45ea-dd9b-1a6773a09073.png)

　筆者は、Windows PCでダウンロードしたのち解凍し、USBメモリでラズパイにコピーしました。

![68747.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/f42a476a-22d1-2257-300e-413e7a357ff4.png)
　インストールは、[EPOS Command Library Documentation](https://maxonjapan.com/wp-content/uploads/manual/epos/EPOS_Command_Library.pdf)の「9.2 Linux」から記述があります。

 　ラズパイのデスクトップにEPOS-Linux-Libraryフォルダごとコピーします。
　``cd EPOS_Linux_Library``
　でディレクトリに入り、
　``sudo bash ./install.sh``
でインストールします。
　プログラミングの作業は、worksフォルダを作ってその中で行おうと思います。デスクトップに置いてあるサンプルHelloEposCmdフォルダの中身（四つある）をworksへコピーします。
　　home/xxx/Desktop/EPOS-Linux-Library/EPOS_Linux_Library/examples/HelloEposCmd
　Definitions.hはヘッダ・ファイルです。HelloEposCmd.cppはサンプルのソースです。Makefileはmakeの時に使うファイルです。CMakeLists.txtは使いません。
　ターミナルで、worksフォルダに入り、
　``make``
でコンパイルとリンクすると、実行ファイルHelloEposCmdができます。ヘルプを実行します。
　``./HelloEposCmd -h``

　なお、HelloEposCmdプログラムは、後半の接続やドライバ類のインストールが終わっていないと、途中で止まります。

```shell
-----------------------------------------------------------------
Epos Command Library Example Program, (c) maxonmotor ag 2014-2019
-----------------------------------------------------------------
Usage: HelloEposCmd
        -h : this help
        -n : node id (default 1)
        -d   : device name (EPOS2, EPOS4, default - EPOS4)
        -s   : protocol stack name (MAXON_RS232, CANopen, MAXON SERIAL V2, default - MAXON SERIAL V2)
        -i   : interface name (RS232, USB, CAN_ixx_usb 0, CAN_kvaser_usb 0,... default - USB)
        -p   : port name (COM1, USB0, CAN0,... default - USB0)
        -b   : baudrate (115200, 1000000,... default - 1000000)
        -l   : list available interfaces (valid device name and protocol stack required)
        -r   : list supported protocols (valid device name required)
        -v   : display device version
```


### 接続
　CANインターフェースは、アマゾンで、CANインターフェース（CAN-HAT）を購入しました。40ピンのピンヘッダに乗せるだけで接続は完了です。ボードのもつRS485の機能は使っていません。
　CANバスとはHとL端子につなぎます、GNDは用意されていません。

　　[3.3V RS485通信 CAN BUS バス モジュール HAT 拡張ボード スターターキット for RPI ラズベリーパイ ゼロ ラズパイ Raspberry Pi Zero 2 W WH 3 Model B+ Plus 4 4B 電子工作 半二重通信](https://www.amazon.co.jp/gp/product/B08LCKLHBX/)

　最終的には、図の赤い線の経路でアクセスします。

![EPOS4-raspai03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/a049a957-0834-7917-ca59-42cc5da3140f.png)

### CANインターフェースのデバイス・ドライバのインストール
　CANバスの用意をします。
``sudo nano /boot/config.txt``
でエディタを起動します。
　次の2行を最後に記述します。
``dtparam=spi=on``
``dtoverlay=mcp2515-can0,oscillator=12000000,interrupt=25``

　dtparam=spi=onは、メニューのPreferances-Raspberry Pi Configurationからインターフェースでspiを有効にしたら、すでに入っていると思います。[解説のページ](https://copperhilltech.com/blog/pican2-pican3-and-picanm-driver-installation-for-raspberry-pi/)にはもう1行``dtoverlay=spi-bcm2835``ありますが、現時点では不要です。たぶんラズパイ4が出たころから、システムに組み込まれてしまい、添付されなくなっています。追加しても、組み込み時に見つからないとしてはねられるだけです。
　12000000は水晶発振子の周波数です。25はGPIO25ピンで、int信号で使われます。物理的には22番ピンです。mcp2515-can0は、SPIバスのピンの接続指定です。CE0（チップ・セレクト信号で物理ピンでは24番）を使います。残りは標準的に使われる、MOSI；19番ピン、MISO；21番ピン、SCK；23番ピンです。



　CTRL+Oで上書き、CTRL-Xでエディタを抜けます。rebootします。
　``dmesg | egrep "can|spi"``
を実行して、

```
mcp251x spi0.0 can0: MCP2515 successfully initialized.
```

だと、ドライバが組み込まれています。

```
mcp251x spi0.0: MCP251x didn't enter in conf mode after reset
mcp251x spi0.0: Probe failed, err=110
mcp251x: probe of spi0.0 failed with error -110
```

とかだと、ハードを認識していません。err=110はタイムアウトです。

### 接続①
　EPOS4のマイクロUSBとラズパイのUSBコネクタをつなぎます。EPOS4はCANバスへのブリッジ（ゲートウェイ）になります


![EPOS4-raspai04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/80bc15f9-f450-a4a7-d7f1-4596ec90c067.png)


　CANインターフェースの情報を調べるので、CANインターフェースCAN-HATもつないでおきます。


### サンプルのコンパイル
　サンプルではnodeIdが1ですが、今回のEPOS4では5に設定しているので、変更します。
　cd worksで作業用ディレクトリに移り、HelloEposCmd.cppをテキスト・エディタでオープンします。``g_usNodeId = 5;``に変更し、保存します。保存できないときは、HelloEposCmd.cppの属性を確認してください。本人とそのグループの所有が正しいです。

```cpp
void SetDefaultParameters()
{
	//USB
	g_usNodeId = 5;
	g_deviceName = "EPOS4"; 
	g_protocolStackName = "MAXON SERIAL V2"; 
	g_interfaceName = "USB"; 
	g_portName = "USB0"; 
	g_baudrate = 1000000; 
}
```

　makeでコンパイルします。
　``./HelloEposCmd``で実行します。モータが動きます。

![2022-06-05 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/1dba99ec-2fd9-c2e2-4d39-08b87cb9b7b1.png)

　最終的にはCANバス経由でモータを制御したいのですが、CANバスを使用するときのinterface nameはダウンロードしたマニュアル類のどこにも書かれていませんし、/sys/busなどのディレクトリのファイルを全部開いても記述されていません。使えることだけは書かれています。下記のパラメータを引っ付けて実行します。maxonのサポートに聞いたパラメタです。

```shell
$ ./HelloEposCmd -l -s "CANopen"
-----------------------------------------------------------------
Epos Command Library Example Program, (c) maxonmotor ag 2014-2019
-----------------------------------------------------------------
default settings:
node id             = 5
device name         = 'EPOS4'
protocal stack name = 'MAXON SERIAL V2'
interface name      = 'USB'
port name           = 'USB0'
baudrate            = 1000000
-----------------------------------------------------------------
interface = CAN_mcp251x 0
            port = CAN0
-----------------------------------------------------------------
```

　interface nameが``CAN_mcp251x 0``であることがわかりました。

### 接続②
　CANインターフェースCAN-HATのCAN_HとCAN_L端子を、EPOS4のCANバスにつながっていることを確認します。USBケーブルはつないだままでかまいません。終端抵抗はEPOS4の1か所だけで動かしています。1mほどの距離だと、1個でも通信できます。本来CANバスの両端に入れるものですが。


![EPOS4-raspai05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/97791967-9275-d97e-fe9e-34e9522e71d0.png)



### CANバス対応にプログラムを変更
　HelloEposCmd.cppの次の部分を変更、保存します。

```cpp
void SetDefaultParameters()
{
	//USB
	g_usNodeId = 5;
	g_deviceName = "EPOS4"; 
	g_protocolStackName = "CANopen"; 
	g_interfaceName = "CAN_mcp251x 0"; 
	g_portName = "CAN0"; 
	g_baudrate = 1000000; 
}
```

```shell
make
./HelloEposCmd
```

で実行します。CANバス経由でサンプルのHelloEposCmdが実行され、モータが動きます。

![2022-06-05 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/c5960130-7bc1-1d55-14b8-db8513cc09e0.png)

　同様に、ID6を振ったEPOS4とラズパイ4をUSBケーブルでつなぎ、``g_usNodeId = 6;``に変更して、HelloEposCmdを実行します。反対側のモータが回りました。
![2022-06-05 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/bad6d3bb-85f7-f826-867d-40ca93c0e43a.png)



（※）このサンプル・プログラムは、ステータスやエラー・フラグをしっかりチェックしてプログラムが組まれています。C++の記述なので、Cだけを学んだ筆者には少し難解です。
　モータは、PPM（Profile Position Mode）でCW；5000、CCW；10000、CW；5000の3回回転します。PVM（Profile Velocity Mode）では、100、500、1000と速度を変化させます。エラー処理も含まれているので、実際の応用プログラムに必要な処理が学べます。

### 二つの状態
###### NMT
　CANopenではNMTというネットワークの状態を管理する機構が存在します。
　電源が入ると、Initialization状態に入ります。GUIのツールだと、ここで待っていることがありますが、EPOS4のライブラリを使うと、初期化がすむとPre-operational状態に自動的に移ります。このモードは、センサのデータを読み書きしたりできます。ユーザが作ったプログラムが動くときは、Operational状態です。
　トラブルがあれば、多くは、Initialization状態に戻ります。
　リモート・ノードを止めたり動かしたりするStopped状態があります。
　これらの遷移によって、エラーが起こった時に適切にシャットダウンさせたりすることができるようです。
　トラブルがなければ、エンドユーザのプログラムはOperational状態で動いています。
　今回は関係ないですが、PDOマッピングをプログラムで変更したいときは、Pre-operational状態で行うようです。
　裏ではハートビートなどの機構が動いていますが、表立って気にして使う場面はないと思います。

![NMT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/49c7851f-ac50-9914-9a8e-4d92228ec873.png)

###### Status Machine
　モーションはCiA 402という規約で、サーボ・モータやステッピング・モータのオブジェクト・ディクショナリの項目が定義されています。これらデバイスをコントロールするために、Status Machineという状態が管理に使われます。
　オブジェクト "Controlword (6040h) "によって制御され、Status Machineの状態は、オブジェクト "Statusword (6041h) "で現在の状態を見れます。
　何らかの理由でFaultになっていたら、Switch on disabled -> Ready to switch on -> Switched on -> Operation enabled状態に移行してから、モータの移動コマンドなどを発行します。GUIツールなどでは、S-ONとか、一気に状態を変更してくれるのもあります。

![state.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/e1e0f8a5-5ed8-96c6-e067-d54df41b5c7d.png)


##### 目次
- [① ラズパイ＋EPOS4、C++でプログラミング＜準備＞](https://qiita.com/jamjam/items/f6acf1128c6020b27059)
- [② ラズパイ＋EPOS4、C++でプログラミング＜車体の用意＞](https://qiita.com/jamjam/items/a9d400baaa5909bb0885)
- [③ ラズパイ＋EPOS4、C++でプログラミング＜モータのチューニング＞](https://qiita.com/jamjam/items/9266eb684d8a2bec7ac6)
- [④ ラズパイ＋EPOS4、C++でプログラミング＜モータのチューニング2＞](https://qiita.com/jamjam/items/93a57e9356bb1f9d1e6a)
- [⑤ ラズパイ＋EPOS4、C++でプログラミング＜ライブラリの準備＞](https://qiita.com/jamjam/items/be97d25e90c7aa9b92c5)
- [⑥ ラズパイ＋EPOS4、C++でプログラミング＜オブジェクト・ディクショナリを読み出す＞](https://qiita.com/jamjam/items/0cd6c5363c851c3c0e3c)
- [⑦ ラズパイ＋EPOS4、C++でプログラミング＜モータの回転 PPM＞](https://qiita.com/jamjam/items/725047121f582bb30937)
- [⑧ ラズパイ＋EPOS4、C++でプログラミング＜モータの回転 CSP その1＞ベータ版](https://qiita.com/jamjam/items/d58bf9affbd980e1735b)
- [⑨ ラズパイ＋EPOS4、C++でプログラミング＜モータの回転 CSP その2＞ベータ版](https://qiita.com/jamjam/items/ea611e552c5787ed5de0)