食わず嫌いだった話【thonnyとatomと僕】

こ、こいつ...動くぞ!

# はじめに
- [前回](https://qiita.com/kei_tnk/items/f217e9fbb04c5a79ad30)、ラズパイ一家の異分子picoを愛でたとき、thonnyというpython用のIDEを動かしたらあっさりとpicoを動かすことが出来て、感動した。
- もしかしたらarduinoIDEよりも簡単かも！と思ったので、M5AtomMatrix（以下、atom）をおもむろに刺してみたら、なんかシリアルモニタな感じで出力を吐き出したので、もう少し弄ってみることにした。
![GIF_20240526_181257_891.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/4328db61-f2fb-04dc-5a92-71be17ee0039.gif)


# atomに入ってたarduinoIDEでのコード
- 元々、arduinoIDEで、こんな感じのプログラムを書いていた。シリアルモニタへの吐き出しがthonnyのシェルでも認識されるということだね。
```cpp
#include <M5Atom.h>

CRGB col[5] = { 0xff0000, 0x00ff00, 0x0000ff, 0xffffff, 0x000000 };  //赤、緑、青、白、黒

void setup() {
  M5.begin(true, false, true);//(serial,I2C,display)
}

void loop() {
  for (int j = 0; j < 5; j++) {
    for (int i = 0; i < 25; i++) {
      M5.dis.drawpix(i, col[j]);
      Serial.printf("色番号:%d,位置:%2d\n",j,i);
      delay(100);
    }
  }
}
```
- macでatomはこんな風に認識されている。
![スクリーンショット 2024-05-26 18.16.10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/73a97e51-800f-5459-6390-efbbd54fdce8.jpeg)
- この状態で、thonnyのインタプリタとしてatomを指定しただけで、thonnyがシリアルモニタとして機能した。まだ、atomにMicroPython(以下、MP)を入れてないけどね。
![スクリーンショット 2024-05-26 18.19.46.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/4a7079ce-2ada-32f3-7f02-f8851950b074.jpeg)

# 同じことをthonnyで実現してみる
- まず、atomにMPを入れないといけない。置いてある場所は、[ここ](https://micropython.org/download/ESP32_GENERIC/)で、最新版は、「ESP32_GENERIC-20240222-v1.22.2」。どうやら、[atomも対応済み](https://github.com/micropython/micropython/commit/a18f695e294baf22bd7862e5be57aa0c820c7c77)の模様。なお、ここでダウンロードしなくても良い。thonnyがやってくれるからね。男前だぜthonny!
- thonnyのインタプリタ設定画面を開くと矢印の先にインストール機能がある。Atomも選択肢に含まれている。あとは、インストールをポチッとな、と。
![スクリーンショット 2024-05-26 18.39.36.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/82230d72-8673-cd2e-9b13-26a66383eedd.jpeg)
![スクリーンショット 2024-05-26 18.44.30.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/3e3c11a9-a915-9f59-27d7-34caec350dfd.jpeg)
- とりあえずは、MPがatomにインストールされたか確認してみる。なんだか、３項演算子が特殊だ。あと、エディタのコード実行は、soft reboot後に結果が表示されるのね。まぁ、直接対話（1+3）の時と違うのは当然か。
![スクリーンショット 2024-05-26 19.14.07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/f34f0374-72a9-000a-f483-07492d7c0aa4.jpeg)
- 次は、atom用のコードを書くだけ！...あれ？どう書けばいいの？[ここ](https://github.com/micropython/micropython/commit/a18f695e294baf22bd7862e5be57aa0c820c7c77)をみると、このメソッドを使う感じかな？つか、メソッドを定義(define)するのに「def」を使うのね。whileやifだけでなく、defもスコープを閉じるお尻の}に相当するものがない。スコープをインデントで表現してるのね。
```py
    def set_pixel_color(self, num, r, g, b):
        if num <= self._np.n:
            self._np[num] = [r, g, b]
            self._np.write()

    def get_pixel_color(self, num):
        if num <= self._np.n:
            return self._np[num]

    def set_pixels_color(self, r, g, b):
        self._np.fill([r, g, b])
        self._np.write()
```
- さて、とりあえず、Lチカしてみるか。arduinoIDEでの`#include <M5Unified.h>`的な宣言はどうすんの？調べた感じ、module「atom.py」のclass「Matrix」を持ってくる感じらしい。
![スクリーンショット 2024-05-26 19.27.28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/0edb2b2d-1e03-fbcb-7e1a-605ab54042af.jpeg)
- だから、こんな感じかな？
```py
from atom import Matrix
mtx = Matrix()
mtx.set_pixels_color(10, 10, 10)
```
![スクリーンショット 2024-05-26 19.37.27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/2556eb3f-0a8b-3f7b-7b1f-e197f7662977.jpeg)

- うむ、動いた！...けど、`def set_pixels_color(self, r, g, b):`の第１引数selfはいらんの？まあ、`self`だから引数省略が当然ってことかな？
- とにかくこれで、arduinoでのコードを書き変えられる！
```py
import time #delayの代わりのsleepを使うため

#include <M5Atom.h>
from atom import Matrix

# CRGB col[5] = { 0xff0000, 0x00ff00, 0x0000ff, 0xffffff, 0x000000 };  //赤、緑、青、白、黒
col = [(255,0,0),(0,255,0),(0,0,255),(255,255,255),(0,0,0)] #赤、緑、青、白、黒

# void setup() {
#   M5.begin(true, false, true);//(serial,I2C,display)
# }
mtx = Matrix()

# void loop() {
while 1:

#   for (int j = 0; j < 5; j++) {
    for j in range(5):
    
#     for (int i = 0; i < 25; i++) {
        for i in range(25):
        
#       M5.dis.drawpix(i, col[j]);
            mtx.set_pixel_color(i, *col[j])
            
#       Serial.printf("色番号:%d,位置:%2d\n",j,i);
            print("色番号:{},位置:{:2}".format(j,i))
            
#       delay(100);
            time.sleep_ms(100)
            
#     }
#   }
# }
```
- よし、動いた!
- arduinoIDEで書くより文字数が少ないかな。
- 複数の引数をタプルに包んで渡すことも可能というのが面白いね。三つの引数を持つ関数`f(a,b,c)=a+b+c`に対して、例えば、`z = (5,10,15)`とした上で、`print(f(z))`のような事が出来る。
- 型に縛られたswiftに慣れた僕には想像できない感覚だ。あまり、気持ちのいいもんじゃないかも。初心者的なプログラムを書くにはいいかもしれないけど、色んなクラスや構造体が現れるプログラムを書くときには使われないね、コレ。
- あと、printfが使えないとか、面倒くさいなぁ。

# 終わりに
- 使ってみたら、MicroPythonもいいかも！と思ったね。
- やっぱり、食わず嫌いは良くない。
- これからしばらくは、以前作ったM5Stackのarduino仕様のプログラムをMP仕様に変えることをしてみようかな。