【M5Stack MP135】LivebookでLチカ（LED点滅）してみた

# はじめに

SWEST26に参加して、いろいろ収穫があったのですが、M5Stack MP135でLinuxが動作することを知りました。
今回は手始めに、Livebookを導入し、Lチカ（LED点滅）を行ってみました。

この検証に使用したM5Stack　MP135は、[コアジェニック](https://coregenik.com/ja/index)さんに御提供いただきました。ありがとうございました。

# OSのインストール

私が入手したものには、付属のSDカードにbuildroot版のOSがインストールされていて、電源を入れるとOSが起動しました。タッチスクリーンに画像が表示され、タッチパネルでメニュー操作が可能でした。
しかし、```apt```コマンド等は利用できずアプリケーションを追加でインストールする事はできませんでした。
当然、Elixirも使えません。

ベンダーから、Debian版とbuildroot版のOSイメージが提供されています。Debian版に入れ替え、Elixirを導入することにしました。

- [m5stackのサイトのDownload image](https://docs.m5stack.com/en/guide/linux/coremp135/image)から、M5_CoreMP135_debian12_20240628をダウンロード
- ```.7z```を解凍して```.img```ファイルにする
- balenaEtcher image burning toolでSDカードに書き込む

操作手順は本家サイトに図入りで詳しく説明されており、非常に分かりやすいです。

https://docs.m5stack.com/en/guide/linux/coremp135/image

# GPIOについての注意

GPIOが簡単に使えるだろうと思って取り掛かったのですが、簡単にはできませんでした。
というのは、ケースの外のコネクターに割り当てられているGPIOは、シリアルポートやi2cのポートとして割りあげられていて、GPIOとしては使えなない状態になっていたからです。

無理してつかわなくてもよいかと思いますが、簡単なON/OFF制御の場合はGPIOとして使いたい。ということもあると思います。
私の試した方法を紹介します。デバイスツリーと呼ばれるカーネルの設定を変更する必要があるので、詳しい事は、デバイスツリーに関する資料を参考にしてください。
操作手順のみ紹介します。詳細は、[別の記事](https://qiita.com/GeekMasahiro/items/ade32cb435608218ba0b)を参照してください。

# GPIOを使えるようにする

Port C/Port Aが直接CPUのGPIOピンに接続されており、GPIOとして使えます。
Port Cはシリアル通信、Port AはI2C通信の信号も兼ねており、これらの機能が有効な間はGPIOとして使用できません。
GPIOとして使用するには、これらの機能を無効にする設定が必要です。

以下の手順で、```/boot```パーティションにあるファイルを変更してPort CをGPIOとして使えるようにします。

### custom.dtsファイルを作成する

```
dtc -I dtb -O dts -o stm32mp135f-coremp135.dts /boot/stm32mp135f-coremp135.dtb
cp stm32mp135f-coremp135.dts custom.dts
```

### custom.dtsの修正

```custom.dts```
の
status =
を
status = "disabled";
に変更する

```
                serial@44003000 {
                        compatible = "st,stm32h7-uart";
                        reg = <0x44003000 0x400>;
                        interrupts-extended = <0x0c 0x1d 0x04>;
                        clocks = <0x08 0x81>;
                        resets = <0x08 0x354d>;
                        wakeup-source;
                        power-domains = <0x0d>;
                        status = "okay";<----この行を修正
                        pinctrl-names = "default\0sleep";
                        pinctrl-0 = <0x1d>;
                        pinctrl-1 = <0x1e>;
                        rx-tx-swap;
                        phandle = <0x85>;
                };
```

### custom.dtsの適用

編集したdtsファイルから、dtbファイルを作成し、/bootにコピーする
```
dtc -I dts -O dtb -o custom.dtb custom.dts
cp custom.dtb /boot
```

/boot/extlinux/extlinux.conf
の
devicetree /boot/stm32mp135f-coremp135.dtb
この行を
devicetree /boot/custom.dtb 
に変更する

```
label stm32mp135f-coremp135-buildroot
  kernel /boot/zImage
  devicetree /boot/custom.dtb <----この行を修正
  append root=/dev/mmcblk0p5 rw panic=5 quiet rootwait
```

### M5Stackを再起動する

再起動すると、GPIOが使える状態となります。

# Elixirのインストール

aptでのインストールすると、1.14.0 がインストールされました。このバージョンだとLivebookが動作しないという問題が起きました。
asdfを使ってインストールします。

erlangのインストール時に必要となる、パッケージのインストール
```
apt-get update
apt-get -y install build-essential autoconf m4 libncurses-dev libwxgtk3.2-dev libwxgtk-webview3.2-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libssh-dev unixodbc-dev xsltproc fop libxml2-utils openjdk-17-jdk
```

asdfを使って、elixirをインストール
```
git clone https://github.com/asdf-vm/asdf.git ~/.asdf
echo . $HOME/.asdf/asdf.sh >> ~/.bashrc
# ログインし直す
asdf plugin add erlang https://github.com/asdf-vm/asdf-erlang.git
asdf plugin add elixir
asdf list-all erlang
asdf install erlang 27.0.1
asdf list-all elixir
asdf install elixir 1.17.2-otp-27
asdf global erlang 27.0.1
asdf global elixir 1.17.2-otp-27
echo export LANG=en_US.UTF-8 >> ~/.bashrc
echo export LC_ALL=en_US.UTF-8 >> ~/.bashrc
# ログインし直す
```

# livebookをインストール

次のコマンドでlivebookをインストールします。
compileにかなりの時間がかかりますが待ちます。
```
mix do local.rebar --force, local.hex --force
mix escript.install hex livebook
```

.asdfのディレクトリ内にあるlivebook serverを起動する。
```
root@CoreMP135:~# /root/.asdf/installs/elixir/1.17.2-otp-27/.mix/escripts/livebook server --ip 0.0.0.0
[Livebook] Application running at http://localhost:8080/?token=eoinmphcfotxz3acetthy4bpcr4sfp3g
```

表示されたURLのlocalhostの部分を、M5StackのIPアドレスに書き換えたURLをブラウザで開くとlivebookが利用でます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/16835092-ea00-a29c-84f3-c2296ec125bd.png)



# Lチカ（LED点滅）をやってみる

## 配線

Port CのTXのポート（黄色のケーブル）はGPIOのPC7が割り当てられています（[PinMap](https://docs.m5stack.com/en/core/M5CoreMP135)参照）。
黄色と赤の間にLEDと抵抗を接続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/cf0e5216-91f0-beae-866e-dcd6b46bb3da.png)

## プログラム

PC7のピンの値を、1,0と100m秒毎に100回切り替えてみます。

```Elixir:Reconnect and setup
Mix.install([
  {:circuits_gpio, "~> 2.0.1"},
  {:kino, "~> 0.12.2"}
])
```

```Elixir
for _ <- 1..100 do
  Circuits.GPIO.write_one("PC7", 1)
  Process.sleep(100)
  Circuits.GPIO.write_one("PC7", 0)
  Process.sleep(100)
end  
```

## 実行結果

![無題の動画 ‐ Clipchampで作成.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/6fe2326b-5d0e-15e2-67f0-4666fa8e5428.gif)

LEDの点灯を制御する事ができました。

## ボタン入力も使ってみる

## 配線

Port CのRXのポート（白色のケーブル）はGPIOのPC6が割り当てられています。
白色と黒色にボタンの白色と黒色を接続します。
白色と赤色の間に抵抗を接続します。この抵抗をつけることで
ボタンが押されていない時は１
ボタンが押されている時は０
の値が取得できるようになります。

set_pull_mode(gpio_in,:pullup)でプルアップに指定したのですが、プルアップになりませんでした。
プルアップが有効になればこの抵抗は不要なのですが、指定してもならかなたので抵抗をつけています。

![DSC_0696.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/2109534b-6d6c-04a8-ba98-2a7a7fa3767d.jpeg)

## プログラム

```Elixir
defmodule LEDbrink do
  def init_gpio() do
    {:ok, gpio_in} = Circuits.GPIO.open("PC6", :input)
    {:ok, gpio_out} = Circuits.GPIO.open("PC7", :output)
    Circuits.GPIO.set_pull_mode(gpio_in,:pullup)
    {gpio_in, gpio_out}
  end

  def loop({gpio_in, gpio_out}) do
    button = Circuits.GPIO.read(gpio_in)
    Circuits.GPIO.write(gpio_out, button)
    Process.sleep(50)
    Circuits.GPIO.write(gpio_out, 1)
    Process.sleep(50)
    loop({gpio_in, gpio_out})
  end
  def start() do
    gpio = LEDbrink.init_gpio()
    LEDbrink.loop(gpio)
  end
end
```

## 実行結果

![無題の動画 ‐ Clipchampで作成 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/e6f94ceb-dd94-66c6-70fe-90bb242b2360.gif)

## 使用したパーツ

|部品|参考価格|
|---|---|
|[ブレッドボード](https://akizukidenshi.com/catalog/g/g105294/)| ￥370|
|[LED黄緑](https://akizukidenshi.com/catalog/g/g111637/) |￥10|
|[LED黄色](https://akizukidenshi.com/catalog/g/g111639/) |￥20|
|[LED赤色](https://akizukidenshi.com/catalog/g/g111577) |￥10|
|[LED青色](https://akizukidenshi.com/catalog/g/g111578) |￥20|
|[ケーブル　M5STACK-A096](https://switch-science.com/collections/m5stack/products/8305) |¥759| 
|[抵抗1KΩ 100個パック](https://akizukidenshi.com/catalog/g/g125102/)|￥100| 
|[ボタン M5STACK-DUALBUTTON-UNIT](https://switch-science.com/collections/m5stack/products/4048)|¥528|


LEDは、いろいろな色があるので例として挙げてみました。一つあればよいです。
ケーブルは、M5StackのPortA/Bのコネクタとブレッドボードを接続できるケーブルを使ってみたら、配線がやりやすかったです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/f99f4634-4da0-2ce8-09e9-f8de3a5de2db.png)

使用した抵抗は２つですが、ばら売りのURLが見つからず、100個パックのURLとなっています。店舗ではばら売りしていると思います。

# まとめ

- M5Stack MP135のDebian OSでElixirを導入できた
- GPIOを利用できることを確認した
- デバイスツリーを変えないとGPIOが使えず、GPIO使うのは、ちょっとOSの準備敷居が高いかも
- ラズパイと違ってケースに入っている事や、PORTの接続がコネクタなのは扱いやすい
- Livebookのインストールと、LivebookからのGPIO制御ができた

今後、I2Cセンサーも接続して試してみたいと考えています。また、buildrootイメージが公開されているので、Nervesを動かすことができるのかも試してみたいと思います。

参考
https://qiita.com/GeekMasahiro/items/3ff5276a552c4430439c
https://qiita.com/GeekMasahiro/items/ade32cb435608218ba0b