M5Stack Tab5で電子メモパッドを作ってみた

年も明けてより一層冷え込む今日この頃、皆様いかがお過ごしでしょうか。
私はお家に引きこもりこんなものを作っていました。

それがこちら

今日の成果物
m5stack tab5で電子ノートを作ってみた
手書き機能の他にSDカードへの読み書き、スリープ機能も付けました。

手書き電子メモパッドです。
仕事では紙とペンでメモを取るということがまぁまぁあるのですが、紙だとすぐ失くしたりして結局意味をなさなかったりすることがままありました。
そこで、電子化すればデータで保存できるから便利じゃないか!と思い至りまずは販売されている製品を探したところ、約3万円からという世界。
いやぁ、さすがに3万円は。しかもネットに繋いでくださいとかなんか微妙に要らない機能まで付いてくる。
さてどうしたものか…と考えていたら、ふと手持ちの中にM5Stack Tab5なるものがあったなと。
で、「おし、じゃあ作るか。」となったとさ。 相変わらず変な人ですね。

ということで本日はこちらの製作記録となります。
では早速参りましょう。

まずご用意したアイテムがこちら(リンクはamazonです。)
M5Stack Tab5 
・パソコン
・その辺に落ちてたmicroSDカード
モバイルバッテリー amazonにあった薄型のやつ。
3Dプリンタ Bambu Lab A1mini

スペシャルゲスト
・GitHub Copilotさん in VSCode

ご用意するものは以上になります。
私の場合はバッテリーだけ今回のために購入しました。
丁度いいサイズのものが手持ちには無かったので。

製作手順としては
①M5Stack Tab5に必要な機能を実装
②ハードウェアを設計
③組み立てて完成!!
簡単3分クッキングですね。(んなわけない。)

今回の電子メモパッドに実装した機能は下記の通り。
①手書きで快適なメモ
②SDカードに保存
③SDカードから呼び出して編集
④スリープモード
・・・こうやって書きだすと簡単そうに見えますが、結構ハマって苦労しました。
まぁ私があんまり知識無い人だからだと思いますが。

 

さて、それではまずM5Stack Tab5の開発環境を整えましょう。
今回私が使用した環境はVSCodeなので拡張機能でPlatform IOを使用しました。
基本的には下記の公式ドキュメントを読みながら環境を作ります。
https://docs.m5stack.com/ja/arduino/m5unified/intro_vscode

次に、PlatformIOの環境設定、PlatformIO.iniの中をTab5用に書き換えます。
Tab5の公式ドキュメントからコピペ。
https://docs.m5stack.com/ja/core/Tab5#platformio

ひとまずここまででビルド・書き込みができることを確認して実際に製作に入ります。

まず初めに、今回のテーマの一番根幹の部分である「手書きメモ」の部分を実装します。
そもそもタッチパネルの性能が実用的な反応速度を得られない場合この企画はボツになりますので。

で、コードを書いていくのですが当然私は公式ドキュメントも雑にななめ読みしかしていないので1文字も書けません。
ここで登場するのがgithub copilotさん。
「タッチパネルに手書きでメモをするためのプログラムを作って」
とお願いするとなんかそれっぽいコードをみるみる出力してきます。
出てきたコードをビルドしてTab5に書き込んで具合をテストし、その結果から修正点を再度伝えてコードを出してもらう。今回はこれの繰り返しで作っていきます。
10年くらい前にarduinoで遊んでいた頃は、いろいろな人書いたコードやサンプルコードを見ながらやっとこ作っていたものが、今はチャットで伝えると作ってくれる時代です。人類の進化を感じますね。

さて、出力してもらったコードで確認してみたところタッチパネルの追従性が悪くてまともに手書きできないものでした。
画面の更新が遅すぎて描いた線が点になってしまうという状態でした。
ここが一つ目のハマりポイント。

M5Stackではcanvasという方法とDisplayという2つの画面表示方法が用意されています。
上記の時、copilotさんはcanvasを採用してくれていたんですがこれは一度メモリに仮想描画してから画面に一括して映し出すという処理をするらしい。

↓初めにcopilotさんが出してくれたコード

最初のコード
#include <M5Unified.h>

// 描画用のスプライト(メモリバッファ)
M5Canvas canvas(&M5.Display);

m5::touch_detail_t touchDetail;

// 前回のタッチ座標
int lastX = -1;
int lastY = -1;

// ペンの太さと色
const int PEN_SIZE = 3;
const uint16_t PEN_COLOR = TFT_BLACK;
const uint16_t BG_COLOR = TFT_WHITE;

void setup() {
  auto cfg = M5.config();
  M5.begin(cfg);

  // 画面を横向きに設定(縦向きなら M5.Display.setRotation(0) )
  M5.Display.setRotation(1);

  // スプライト作成(画面全体のサイズ)
  canvas.createSprite(M5.Display.width(), M5.Display.height());
  canvas.fillSprite(BG_COLOR);

  // 初期表示
  canvas.pushSprite(0, 0);

  Serial.begin(115200);
  Serial.println("TAB5 Touch Draw Started");
}

void loop() {
  M5.update();
  touchDetail = M5.Touch.getDetail();
  if (touchDetail.isPressed()) {
    while (true){
    touchDetail = M5.Touch.getDetail();
    M5.Display.fillCircle(touchDetail.x, touchDetail.y, 5, BLACK);
    M5.update();
    if(touchDetail.isReleased()){
      break;
    }
  }
  delay(1);
  }
}

で、これだと全然だめですと。
しかしcopilotさんに伝えてもいまいち解決の糸口がつかめなかったので公式ドキュメントとにらめっこしたところ、Displayで直接表示した方が早いらしいと分かり、それをcopilotさんに伝えて再度生成。
しかしDisplayにしただけではなめらかな手書き感が得られなかったためそこも試行錯誤。
結局、画面の更新頻度を上げるしかないとなり、タッチされている間は無限ループして画面更新をするというパワープレイに。

改良したコード
#include <M5Unified.h>

// 描画用のスプライト(メモリバッファ)
M5Canvas canvas(&M5.Display);

m5::touch_detail_t touchDetail;

// 前回のタッチ座標
int lastX = -1;
int lastY = -1;

// ペンの太さと色
const int PEN_SIZE = 3;
const uint16_t PEN_COLOR = TFT_BLACK;
const uint16_t BG_COLOR = TFT_WHITE;

void setup() {
  auto cfg = M5.config();
  M5.begin(cfg);

  // 画面を横向きに設定(縦向きなら M5.Display.setRotation(0) )
  M5.Display.setRotation(1);

  // スプライト作成(画面全体のサイズ)
  canvas.createSprite(M5.Display.width(), M5.Display.height());
  canvas.fillSprite(BG_COLOR);

  // 初期表示
  canvas.pushSprite(0, 0);

  Serial.begin(115200);
  Serial.println("TAB5 Touch Draw Started");
}

void loop() {
  M5.update();
  touchDetail = M5.Touch.getDetail();

  if (touchDetail.isPressed()) {
    while (touchDetail.isPressed()) {
      // タッチ情報を高速更新
      M5.update();
      touchDetail = M5.Touch.getDetail();

      int x = touchDetail.x;
      int y = touchDetail.y;

      // 前回座標から現在座標への中間点を補間して描画
      if (lastX >= 0 && lastY >= 0) {
        int dx = x - lastX;
        int dy = y - lastY;
        int steps = max(abs(dx), abs(dy));

        if (steps > 0) {
          for (int i = 0; i <= steps; i++) {
            int interpX = lastX + dx * i / steps;
            int interpY = lastY + dy * i / steps;
            M5.Display.fillCircle(interpX, interpY, PEN_SIZE, PEN_COLOR);
          }
        }
      } else {
        // 初回タッチは円を描画
        M5.Display.fillCircle(x, y, PEN_SIZE, PEN_COLOR);
      }

      lastX = x;
      lastY = y;
    }

    // タッチ終了時に座標をリセット
    lastX = -1;
    lastY = -1;
  }
}

手書きメモの根幹部分はとりあえずこれで完成となりました。
ここから、画面クリア機能、ペン-消しゴム切り替え機能の追加をcopilotさんに依頼してまずはひと段落。

続きまして、SDカードへの書き出し、読み出しを実装していきます。
SDカードへは画面の状態をBMP形式で保存することとしました。
で、ここでまたドハマり。copilotさんの出すコードではSDカードへのアクセスするための初期化がうまくいきませんでした。
M5Unifiedライブラリの機能にあるgetSD()とか使ってもうまくいかず。
色々模索したところ、SDカードにアクセスするためにはSPI接続を使っており、これのピン番号はハードウェアによって異なるためしっかりと記載してあげる必要がありました。
それも公式のドキュメントにありました。
https://docs.m5stack.com/ja/arduino/m5tab5/microsd

大体必要な内容は公式ドキュメントにまとまっているので、copilotさんが詰まったら公式ドキュメントを読み漁れば解決策が見つかります。M5Stack様様でございます。
SDカードへのアクセス方法が分かれば読み書きはcopilotさんがどーにかしてくれました。

ここまで来て、コードの行数としては300行を越えてきました。copilotさんの読み込みも大分しんどそうな感じで
括弧の付け忘れなどAIらしくないミスが発生しはじめました。

とはいえまだこれでは完成できないので、最後にスリープ機能を作ってもらいます。
Tab5には電源ボタンしかハードウェアボタンは付いていないので、画面上にスリープボタンを設置、
スリープとは言いつつ実のところはバックライトをOFFにするだけのものですが。
ボタンでスリープ、画面タッチで復帰をするようにお願いして、もろもろ微調整もして最終的にできたコードがこちら。
https://github.com/rgm79sf/m5stack-tab5-memopad.git

はい。コードの長さとしてはなかなかですが(自分比)なんだかんだ日曜日のお昼から初めて18時頃には完成しました。
しばらく遊んで、ついでにX(twitter)に投稿したらなんだかすごい反応をもらえました。
で、それを受けて調子に乗ってバッテリーの搭載とケースを作ることに。

何ということでしょう、公式ドキュメントには製品サイズの寸法まで載っているではありませんか。
https://docs.m5stack.com/ja/core/Tab5#製品サイズ
ということで4隅のM3ネジを利用して背面にバッテリーを仕込むためのケースを製作。
一応標準でNP-F550なるバッテリーを付けれるのですが、そこだけ飛び出す形になるのはちょっと格好が悪いなぁと思い、よさげなモバイルバッテリーを背面に装備することにしました。
ケースはこんな感じ。

なんか一か所だけ穴が破れかけのところがありますが、まぁご愛嬌ということで。使えればよかろうなのです。
ワンオフなので。

でこれを3Dプリンタで造形して、その辺に転がってたM3ネジで固定して完成したものがこちら。

ジャストフィットでございます。
厚みとしては本体合わせて20mmとなるので昨今のスマホとかと比べたら比較にならないくらい分厚いですが、
それでも自作したにしてはスマートに収まったのではないでしょうか。

持ち運びもギリギリできるサイズ感なので、しばらくはこれを会社に持ち込んで使ってみようと思います。
色々な人に見せびらかして自慢したりして。(よくない)

ということで長々と書いてまいりましたがTab5電子メモパッドの完成です。
ハードまで含めると大体1日って感じの製作時間でした。

今回の製作を通して、改めてAIの進化に驚くとともに、結局人間がドキュメントを見て補完することができないと完成させることはできないんだなぁと安心する部分もあったりしました。
また、今回はTab5のタッチパネルとSDカード機能しか使えていないので、今後wi-fiとかも使ったほかのアイテムを製作するのもいいなぁと次に向けての意欲もでてきました。
プラモと掛け合わせてなにかできないかなぁとアイデアを考えております。

また何か作る機会があればこんな形でブログにまとめたりして、誰かの役に立つことがあればいいなと思います。

それでは、長々とお付き合いありがとうございました。ノシ

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください