MicroPythonでM5NanoC6をプログラミング

## MicroPythonアップデート
2024年10月26日のアップデート（v1.24.0）でRISC-Vアーキテクチャのマイコンがいくつかサポートされました。

https://github.com/micropython/micropython/releases/tag/v1.24.0

具体的にはRaspberryPi Pico 2に搭載されているRP2350や、M5NanoC6に搭載されているESP32-C6です。

今までは、Arudino言語やCircuitPythonでプログラミングする必要がありました。
今後はとてもプログラミングしやすいMicroPythonでM5NanoC6を使うことができます。

RISC-Vは、企業がライセンスを持っているARMアーキテクチャの代わりとなる、無料で利用可能なオープンなCPUアーキテクチャです。
RISC-Vはまだまだ発展途上ですが、多くの企業や団体がサポートを表明しており、今後広がる可能性があります。

## MicroPythonをインストール

### ファームウェアをダウンロード
MicroPythonのウェブサイト上で最新のbinファイルをダウンロードしてください。
現時点では最新のファイルは`v1.24.0 (2024-10-25) .bin`でした。

https://micropython.org/download/esp32c6/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105381/5e3117f5-8712-4832-e240-9725133a2c62.png)

### esptool.pyをダウンロード

マイコンを通信してファームウェアを書き込むツールがesptool.pyです。
GitHub上の配布サイト上からダウンロードできます。
現時点での最新版は`v4.8.1`ですので、Windowsの場合は`esptool-v4.8.1-win64.zip`をクリックし、ダウンロードします。

https://github.com/espressif/esptool/releases

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105381/005958f3-2e2f-fdaa-0bed-fb801eacec4a.png)

ダウンロードされたZIPファイルを展開すると、いくつかのEXEファイルが入ったフォルダが作成されます。

### フォームウェアをマイコンに書き込み

M5NanoC6をPCとUSBケーブルで接続します。
接続すると、PC上でCOMポートとして認識されます。
デバイスマネージャ上で確認すると、COM8として認識されていました。
このCOMのあとの数字は、環境によって変わります。
また、「COM◯◯」というワードは、書き込みコマンドでも使いますので、メモしておいてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105381/64f436a9-5591-6ce2-ab1a-e828a9197359.png)

もしうまくPCで認識できない場合は、M5NanoC6の前面のボタンを押しながら、接続してみてください。

接続できたら、以下のコマンドでファームウェアを一度削除しましょう。
「COM8」の部分は自身のPCに接続したときのポートを指定してください。

```
esptool.exe --chip esp32c6 --port COM8 erase_flash
```

削除した後、ファームウェアを書き込みます。
コマンドの最後のファイルは、ダウンロードしたファイルを指定してください。
私の環境では、だいたい20秒くらいかかりました。

```
esptool.exe --chip esp32c6 --port COM8 --baud 460800 write_flash -z 0x0 M5STACK_NANOC6-20241025-v1.24.0.bin
```

## ThonnyでMicroPythonプログラミング

MicroPythonのIDEとしてThonnyを利用します。
以下のウェブサイトで配布していますので、ダウンロードしてインストールしてください。

https://thonny.org/

Thonnyを起動し、画面下側のステータスバーをクリックし、「MicroPython (ESP32)」をインタプリタとして選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105381/81ac2a8f-bf6a-c84b-9c48-296e65c43db2.png)

まずは、M5NanoC6に内蔵した青色LEDをチカチカ光らせる、Lチカを試してみます。

以下のプログラムをエディタに貼り付けてください。

```python
import machine
import time

led_pin = machine.Pin(7, machine.Pin.OUT)
while True:
    led_pin.value(1)
    time.sleep(1)
    led_pin.value(0)
    time.sleep(1)
```

ツールバーの緑色の再生マークをクリックすると、プログラムを実行します。
すると、下図の矢印の先のLEDが1秒ごとに点滅します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105381/62dba643-eec0-f5dc-2c40-7d8122b4fd5f.png)


## MicroPythonでM5NanoC6を使い倒す

M5NanoC6にはマイコン以外に、様々な電子部品を搭載しており、LEDもそのひとつです。
他には以下があります。

- ボタン
- RGB LED
- IR（赤外線の送信のみ）

また、Groveポートを1つ搭載していますので、そこからM5Stack用のユニットを接続し、機能を増やすことができます。

### ボタン
「M5」という文字が書いてある面（シールの反対側）にボタンがあります。
このボタンは、押している間は0で、離している間は1となります。

次のプログラムをエディタに貼り付け、プログラムを実行すると、ボタンの状態によって青色LEDの点灯状態が変わります。
すなわち、ボタンを押している間はLEDが消灯します。

```python
import machine
import time

led_pin = machine.Pin(7, machine.Pin.OUT)
button_pin = machine.Pin(9)
while True:
    button_value = button_pin.value()
    led_pin.value(button_value)
    time.sleep_ms(10)
```

### RGB LED

M5NanoC6にはRGBの3色の明るさを制御できる、NeoPixelという部品が搭載されています。
MicroPythonにはNeoPixelを制御するためのモジュールが入っているため、簡単に扱うことができます。
以下のプログラムでは、1秒ごとに色が変化し、ボタンのボタンの隙間からRGB LEDの光る色が見えます。
Pin19番にNeoPixelの電源がつながっているため、19番の出力を1にして、電源をつける必要がある点が注意です。

```python
import machine
import time
import neopixel

machine.Pin(19, machine.Pin.OUT).value(1)
np = neopixel.NeoPixel(machine.Pin(20), 1)
count = 0
colors = [(255,0,0), (0,255,0), (0,0,255)]
while True:
    np[0] = colors[count%3]
    np.write()
    count += 1
    time.sleep(1)
```

### IR
IRの受信ユニットを持っていないので、その動作を試すことができませんでした。

### Groveポート

M5NanoC6はGROVEポートを1つ搭載しています。
ここに、様々なユニットを接続できます。
試しに、温度や湿度、気圧の計測が可能なENV IVユニットを接続します。

電子部品とマイコンの間は様々な通信方法によって通信し、データをやり取りします。
このENV IVユニットには、SHT40とBMP280の2つのICが入っており、それぞれとI2C通信を行います。
今回は、気温と湿度を計測するSHT40と通信してみます。

以下がそのプログラムです。

```python
import machine
import time

i2c = machine.I2C(0)
i2c.writeto(68, b'\xFD')
time.sleep_ms(10)
rx_bytes = i2c.readfrom(68, 6)
t_ticks = rx_bytes[0] * 256 + rx_bytes[1]
rh_ticks = rx_bytes[3] * 256 + rx_bytes[4]
t_degC = -45 + 175 * t_ticks/65535
rh_pRH = -6 + 125 * rh_ticks/65535
if (rh_pRH > 100):
  rh_pRH = 100
if (rh_pRH < 0):
  rh_pRH = 0

print(f"temp:{t_degC:.2f} humid:{rh_pRH:.2f}")
```

このプログラムを実行すると、シェルに現在の気温（℃）と湿度（%）が出力されました。
おおよそ室温どおりの結果です。

```
temp:22.98 humid:29.87
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105381/c00ee505-b82d-4a16-15ba-f7498862d449.png)


このようにMicroPythonではArudino言語よりも簡単にマイコンを扱うことができます。