Raspberry PiとSimulinkでLチカ！

## この記事について
Simulinkにはサポートパッケージなるものがあって、"Arduino"や"Raspberry Pi"などの代表的な基板をサポートしています。よくある誤解で"Raspberry PiにSimulinkをインストールするの？"というのがありますが、そうではありません。SimulinkモデルからC/C++コードを生成して、Raspberry Pi上でビルトしてスタンドアローンで動作します。開発環境としてSimulinkがあるのであって、Raspberry Piにデプロイした後はSimulinkはいらない、というわけです。しかもRaspberry PiやArduino向けサポートパッケージに関しては、この実行ファイル生成が無償で利用できて大変お得！(Simulinkは必要)
というわけで、今回はまず手始めに"Lチカ"から初めますが、せっかくのRaspberry PiなのでゆくゆくはホームLEDに発展させたいと思います。

https://qiita.com/kureta90/items/d5fea1f81b79c8f1b2be

https://qiita.com/kureta90/items/edbbf899cd218fe5cdf5


## ソフトウエア
・MATLAB/Simulink
・Simulink Support Package for Raspberry Pi Hardware(アドオン、無償)

Simulink Support Package for Raspberry Pi Hardwareのインストールは、MATLABバージョンR2023a以降大きな変更がありました。R2023aより前はMathworksからRaspbian OSイメージが提供されていましたが、R2023a以降は通常のRaspbianをセットアップして、そこにSimulinkと接続したりハードウエア周りのライブラリを追加でインストールする構成に変更されています。
まず普通にRaspbianをインストール。既にbulleseye対応のRaspbianをインストール済みの場合は次の項は飛ばしてください。

## Raspberry Piのセットアップ
RaspbianのイメージファイルをダウンロードしてSDカードに起動ディスクを作成しますが、このあたりは多数記事があるので割愛します。今回はbullseye対応の64bit版をインストールしました(32bit版も可)。
https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-64-bit

インストール後、Raspberry Piを起動して、コンソールから
$ ip a 
でipアドレスを調べておいて(eth0やwlan0)、ホスト(Simulink開発PC)とEtherやWLANで接続できることをpingコマンド等で確認します。


## SSH開通
サポートパッケージではssh経由でRaspberry Piを遠隔操作するので、Raspberry Pi側でsshを起動しておきます。
$ sudo service ssh start 
開発中、サポートパッケージで接続する際はsshを起動しておく必要があります。Raspberry Pi起動の度に毎回sshを起動させるのは面倒なので、
$ sudo raspi-config
で　3 Interfacing Options　を選択し、次の画面でI2 SSHをEnableにしておくとよいでしょう。
![enb_ssh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/1e5cf98b-77bc-4cb7-f826-23656270e223.png)


## サポートパッケージの準備
MATLAB-ホーム-アドオンより以下をダウンロード
"Simulink Support Package for Raspberry Pi Hardware"
![add-on.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/3b625047-48fe-cec7-291c-7e30395a51ec.png)

続いて”ハードウエアセットアップ”に沿って現れるGUIに従って以下を順に実行します。
(Simulinkとの接続に必要ないくつかのライブラリをRaspberry Piにインストールします)

1.先に調べたRaspberry PiのIPアドレスとユーザー名/パスワードを入力
　"Test connection"を実行してMATLABからsshアクセスが可能なことを確認
![sp-setup1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/743a9a60-91e7-7766-9017-f6c761885889.png)

2.ライブラリのインストール状況を調査 ”Verify Installation”をクリック
![sp-setup2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/c0252c0b-2074-52ce-b68f-3e3dea80a4ca.png)

3."インストール"ボタンをクリック
![sp-setup3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/abc86f90-d724-1e45-3f05-7ec3c7c0c9a5.png)

4.ペリフェラルを有効に
![sp-setup4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/8bd53454-2dd2-bab6-7425-88a5cca98b95.png)


続いて必要に応じて以下をインストールします。今回のLチカには不要ですが、今後エッジAIや画像処理関連のアルゴリズムを実装するならGUIの案内に沿ってインストールしておきましょう。
1. ARM Compute Library
2. OpenCV Library

## ハードウエア
・Raspberry Pi本体　各種ラズパイ基板に対応していますが今回は4B+を使用
・ジャンパ、LED(抵抗)、スイッチ　LEDは抵抗で電流制限してもよいですが、今回は電流制限素子入りのもので楽をしました
![LED.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/0ba2978c-75f8-45ca-0871-25aefc1d86e8.png)
 https://akizukidenshi.com/catalog/g/gI-17578/ 

今後調光や色変更させたいので、3色のLEDを使用します。ちなみに上記のLEDは、3色RGBが一つのLEDに内蔵されていて、3色の明るさを変えることによって自由に色と明度を設定できます。ゆくゆく試していきますが、今回はこのうちRだけを使用します。電流制限素子が内蔵されているので、抵抗も不要です。
またスイッチは、下の回路図で2系統用意していますが、今回は1系統のみ使用します。
SW入力 gpio 23 とLED(R)出力 gpio 17 をラズパイのI/Oポートに結線します。
![hw-connection.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/2145f4ba-d5b9-c56e-d648-8d50c5c34ed1.png)

## Simulinkモデル
新規にSimulinkモデルを作成する際、用途に応じたテンプレートを利用できます。
MATLAB - ホーム メニュー右端の"Simulink"ボタンを押すと 
![ML-Menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/ff99b114-fefe-b0b7-4e5f-dc0ba414b2f4.png)
以下のようなテンプレートが開くので、"Simulink Support Package for Raspberry Pi Hardware"から用途に応じて空のモデルを作成します。今回はエクスターナルモード(後述)を選択します。
![ext-mode-template.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/48819655-bdcb-05f3-b98d-8582f51d3526.png)
すると空のモデルができますが、テンプレートのおかげで基本的な設定は完了しています。
このモデルのメニューから"ライブラリブラウザ"を開くと、Raspberry Piに関連するブロックを選択できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/ea8e5619-7436-3f2f-a6fa-e932fb3c99ce.png" width="400">


今回は入出力ともにON/OFFの2値なので、gpioですね。さらにSimulinkではシミュレーション用の仮の入力を発生させることができて、gpioなどのハードウエア入力の代わりに使用することができます。今回は"Lチカ"だけなので、シミュレーションで機能確認する必要もなさそうですが、仮の入力として"push botttun"ブロックを配置すると、実機のスイッチを押したのと同じ入力を得ることができます。またその結果をscope画面で確認できます。

シミュレーション用の仮の入力と、結果確認用のScopeを含んだモデルは以下のようになります。
上半分がシミュレーション用、下半分が実機動作用です。もちろん下半分だけで"Lチカ"は実施可能です。一方、このモデルからコード生成する際、実機動作に関係のないシミュレーション入力が邪魔になるのでは？との懸念があるかもしれませんが、シミュレーション入出力はコード生成の際、自動的に無視されます。
![L-model.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/e09b9e4b-0348-74ac-b81f-ecd11c87cd14.png)
GPIO入出力ブロックをクリックすると、接続したピン番号を指定できます。スイッチとLEDを接続したピン番号を指定します。

## シミュレーション
"Lチカ"では全くありがたみはありませんが、Simulinkの　"シミュレーション"タブの"実行"ボタンを押すとシミュレーションを開始します。ボタンを押すと、Scopeでの波形観察が変化する様子が確認できます。
![sim_mode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/f8481021-80dd-5bed-de77-dec7bec1742c.png)
この際、シミュレーションが一瞬で終わらないよう、終了時間を'=inf'(無限)、シミュレーションペーシングを'=1'(実世界と同じペース)に設定しておきましょう
![pacing.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/858a7da3-cc63-97b3-b37a-9ffaa55b6cb9.png)

## エクスターナルモード
エクスターナルモードはシミュレーションと実機実装のいいとこどりです。コード生成してターゲット(Raspberry Pi)上で動作しつつも、ターゲットでのハードウエア入力をはじめ、内部変数をモニタできる特殊なモードです。
"ハードウエア"タブの"ハードウエア ボード"タブで、ターゲットとしてRaspberry Piを指定します。また、"ハードウエア設定"のボタンから"コンフィギュレーションパラメーター"を開きます。
![button_hardware_settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/bd564925-8645-a8cf-11c5-f1f6d31dcacc.png)

"ハードウエア実行"の"Target hardware resources"の中の"Edit"ボタンを押して、
![conf_param.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/efb439d1-5bf0-a685-1239-eef6e0aa00ad.png)
Raspberry PiのIPアドレス、ユーザー名、パスワードを設定します。
![conf_rasp_id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/cde239bc-6f07-d962-6f8e-7dc82f3a0d0c.png)

以上の設定が終了すると、Raspberry Piと接続できます。"ハードウエア"タブの"監視と調整"ボタンでエクスターナルモードを開始できます。このモードでは実機入力を使いながら、シミュレーション入力やデバッグ用のモニタ機能も活用できます。シミュレーション用のボタンを押すと、LEDが光ります。また、ハードウエアのスイッチ入力の様子をscope画面から確認できます。デバッグやパラメータ調整に非常に便利です。
![ext_mode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/42d4478a-175d-9f0d-08f1-8e14b24dd662.png)

なお、エクスターナルモード時に生成 & Raspberry Pi上で実行されるコードは、内部の情報を取得してSimulinnkからモニターするために、デプロイ時に最終的に生成されるコードよりも冗長な部分を含みます。若干実効レートも遅くなりますが、Lチカ程度であれば遅延を感じることはないでしょう。

## 実機実装
エクスターナルモードでデバッグやパラメータ調整が終わったら、"ハードウエア"タブの"ビルド、展開、起動"ボタンで、アルゴリズムをRaspberry Pi上にデプロイします。Raspberry Pi上に実行ファイルが生成され、実行します。デプロイ後は、Simulinkと切り離して、スタンドアローンで動作します。
![dep_mode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/4fd19e41-a0f1-f38e-c24d-e1f0a23b4743.png)

なお、生成された実行ファイルを、Raspberry Pi起動時に自動的に実行するには、"コンフィギュレーションパラメーター"で"Run on boot"にチェックを入れます。
![run_on_boot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583335/ae1bc32a-3a0c-2246-8b96-bd2a2f88da26.png)
もちろん一般的に行われるように、Linuxのcrontabコマンド等で実行ファイルを呼びだして、起動時や一定時間間隔で実行させることも可能です。

## 参考記事
こちらの記事で"Simulink+Arduino+Lチカ"について、

https://qiita.com/juraruming/items/cd5be0f238af35a5d362

またこちらの記事では"MATLAB+Raspberry Pi+Lチカ"について分かりやすく解説されています。

https://qiita.com/aoimidori/items/514b069cece37e9be4cf

本記事はそれぞれ、"Arduino"を"Raspberry Pi"に、あるいは"MATLAB"を"Simulink"に置き換えただけで大きな違いはありません。