M5StickC Plusで６つのストーンが光るガントレットを製作する

# はじめに

IoTLTの2023年アドベントカレンダーに向けて書いた記事です。Internet要素が皆無ですが、M5StickC Plusを使ったので良しとして下さいw

https://qiita.com/advent-calendar/2023/iotlt

# 作ったもの

XのPostを見てもらうと早いと思います。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">完成したぞ🤌🏻´- <a href="https://t.co/Yi0x6ISmNe">pic.twitter.com/Yi0x6ISmNe</a></p>&mdash; ufoo68 (@ufoo_yuta) <a href="https://twitter.com/ufoo_yuta/status/1729372507390779813?ref_src=twsrc%5Etfw">November 28, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

手に力を込めると、某映画でお馴染みの６つのストーンが光るガントレットを作りました。

# 材料一覧

主に使ったマイコンや電子部品などです。押入れから引っ張り出してきたあまり部品も使ったので全部は載せていません。

- [M5StickC Plus（腕時計アクセサリー付き）](https://www.switch-science.com/products/7535)
- [GROVE - FSR402搭載 感圧センサ（円型）](https://www.switch-science.com/products/3989?variant=42382002028742)
- [KSC1815YTA](https://eleshop.jp/shop/g/gDAI124/)
- カラーLED（品名不明。多分よくあるやつ）
- 1/4Wカーボン抵抗(10kオーム２個と220オーム１個)
- ボタン電池（RC2032を２個）
- [某ガントレット](https://www.amazon.co.jp/gp/product/B07RL26D96/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&th=1)

# 製作過程

ここから工作ブログっぽくなりますが、実際の製作過程について簡単にまとめてみます。

## まずはガントレット購入

ゼロからガントレットを作るのは大変なので、コスプレ用に売っているものを買って改造することにしました。さきほどの材料一覧で載せたのですが、Amazonでちょうどいい感じのものが4000円ほどで売っていたのでポチりました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">さて、改造するぞー <a href="https://t.co/Uz6sR2nhLG">pic.twitter.com/Uz6sR2nhLG</a></p>&mdash; ufoo68 (@ufoo_yuta) <a href="https://twitter.com/ufoo_yuta/status/1722431633431973929?ref_src=twsrc%5Etfw">November 9, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

さてここで課題が、、、**指が曲がらない！！**
指が開いた形でがっちり固定されていて自由に動かせない。。。これでは某エンドゲームの指パッチンのマネができないのです。

## ガントレットを少し改造する

当初はガントレット製作に関しては既製品を使って追加の電子工作だけをやろうと思っていたのですが、ガントレットのハード部分も改造することにしました。

<blockquote class="twitter-tweet"><p lang="zxx" dir="ltr"><a href="https://t.co/XpfbKUfh7M">pic.twitter.com/XpfbKUfh7M</a></p>&mdash; ufoo68 (@ufoo_yuta) <a href="https://twitter.com/ufoo_yuta/status/1726808547764408598?ref_src=twsrc%5Etfw">November 21, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

↑とりあえず指は一旦切り落として↓手袋に貼り付けて指を曲げられるように改造しました。

<blockquote class="twitter-tweet"><p lang="zxx" dir="ltr"><a href="https://t.co/3yJU0w11bK">pic.twitter.com/3yJU0w11bK</a></p>&mdash; ufoo68 (@ufoo_yuta) <a href="https://twitter.com/ufoo_yuta/status/1726980043602288656?ref_src=twsrc%5Etfw">November 21, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 指に感圧センサーを仕込む

ここから電子工作パートです。とりあえずガントレットで何かしらインタラクティブなことをしたいと思っていたので、某映画で印象的な指パッチンの動作をトリガーにしようと思いました。
そこから思いついたのが指に感圧センサーを仕込むという方針でした。感圧センサーはハンダ付けなしで手軽に使えるGroveのタイプのものを選びました。マイコンについては、ウェアラブルなものが作りやすそうだなという理由から腕時計アクセサリー付きのM5StickC Plusを使うことにしました（別に性能面で考えるとPlusにする理由はなかったのですが、たまたま積み基板していたものがあったので使ってみました）。

<blockquote class="twitter-tweet"><p lang="zxx" dir="ltr"><a href="https://t.co/oYisBICcua">pic.twitter.com/oYisBICcua</a></p>&mdash; ufoo68 (@ufoo_yuta) <a href="https://twitter.com/ufoo_yuta/status/1727875843945582676?ref_src=twsrc%5Etfw">November 24, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 感圧メーターを可視化

まずは肩慣らしと圧センサーのテストを兼ねてプログラミングをしてみます。
開発環境はPlatformIOでやりました。M5StickC Plusでの開発環境の構築方法については↓で解説されている記事があります。

https://qiita.com/ume-bar/items/234014927ae0857baf51

とりあえず開発環境を構築後、感圧センサーの値を可視化するコードをChatGPTに相談しながら書いていきました。実際に書いてみたコードが↓です。

```cpp
#include <M5StickCPlus.h>

#define ANALOG_PIN 33  // アナログセンサーのピン番号

// 関数の宣言
void drawMeter(int value);

void setup() {
  M5.begin();
}

void loop() {
  // アナログセンサーの値を取得
  int sensorValue = analogRead(ANALOG_PIN);

  // メーター表示
  drawMeter(sensorValue);

  delay(100);
}

void drawMeter(int value) {
  M5.Lcd.fillScreen(TFT_BLACK);  // 背景を黒でクリア

  // メーターの描画
  M5.Lcd.drawRoundRect(60, 20, 20, 200, 5, TFT_WHITE);  // メーターの外側の枠

  // メーターの値に基づいて色を変更
  uint16_t color = TFT_GREEN;
  if (value < 300) {
    color = TFT_RED;
  } else if (value < 700) {
    color = TFT_YELLOW;
  }

  // メーターのバーを描画
  int barHeight = map(value, 0, 4095, 0, 200);
  M5.Lcd.fillRect(60, 220 - barHeight, 20, barHeight, color);

  // 数値を表示
  M5.Lcd.setTextSize(2);
  M5.Lcd.setTextColor(TFT_WHITE);
  M5.Lcd.setCursor(5, 5);  // 数値を表示する位置を調整
  M5.Lcd.printf("%d", value);
}
```

とりあえずM5StickC Plusでも問題なく感圧センサーが使えることがわかりました。

<blockquote class="twitter-tweet"><p lang="zxx" dir="ltr"><a href="https://t.co/YSheH809BP">pic.twitter.com/YSheH809BP</a></p>&mdash; ufoo68 (@ufoo_yuta) <a href="https://twitter.com/ufoo_yuta/status/1729044572377100696?ref_src=twsrc%5Etfw">November 27, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## LED点灯を制御

次に指先の感圧センサーの動きと連動して６つのストーンが光るようにしてみました。
実は改造前の状態でも各ストーンの中にLEDが仕込まれていたのですが、現状だと６つのストーンの光り方をまとめて制御することが難しかったので新たにLEDを仕込んでマイコンから制御することにしました。
LEDの光を制御するために外部電源としてCR2032（なるべくコンパクトにしたかったのでボタン電池に）を使ってトランジスタを使ってスイッチング回路を組みました。

<blockquote class="twitter-tweet"><p lang="zxx" dir="ltr"><a href="https://t.co/o81NUHGFdk">pic.twitter.com/o81NUHGFdk</a></p>&mdash; ufoo68 (@ufoo_yuta) <a href="https://twitter.com/ufoo_yuta/status/1729505219074007288?ref_src=twsrc%5Etfw">November 28, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

トランジスタで使ったのはKSC1815という2SC1815の互換品です。2SC1815を使ったスイッチング回路の組み方については↓で解説されていたのでそれを参考にしました。

https://www.petitmonte.com/robot/howto_transistor_npn.html

感圧センサーの値とLEDの光り方を連動させるためにコードを拡張しました↓

```cpp
#include <M5StickCPlus.h>

#define ANALOG_PIN 33   // アナログセンサーのピン番号
#define LED_PIN 32      // LEDのPWMピン番号
#define PWMCH 1         // PWMチャンネル番号

// 関数の宣言
void drawMeter(int value);

void setup() {
  M5.begin();
  pinMode(LED_PIN, OUTPUT);
  ledcSetup(PWMCH, 12000, 8);
  ledcAttachPin(LED_PIN, PWMCH);
}

void loop() {
  // アナログセンサーの値を取得
  int sensorValue = analogRead(ANALOG_PIN);

  // メーター表示
  drawMeter(sensorValue);

  // LEDの制御
  int brightness = map(sensorValue, 0, 4095, 0, 256);
  ledcWrite(PWMCH, brightness);
  delay(100);
}

void drawMeter(int value) {
  M5.Lcd.fillScreen(TFT_BLACK);  // 背景を黒でクリア

  // メーターの描画
  M5.Lcd.drawRoundRect(60, 20, 20, 200, 5, TFT_WHITE);  // メーターの外側の枠

  // メーターの値に基づいて色を変更
  uint16_t color = TFT_GREEN;
  if (value < 300) {
    color = TFT_RED;
  } else if (value < 700) {
    color = TFT_YELLOW;
  }

  // メーターのバーを描画
  int barHeight = map(value, 0, 4095, 0, 200);
  M5.Lcd.fillRect(60, 220 - barHeight, 20, barHeight, color);

  // 数値を表示
  M5.Lcd.setTextSize(2);
  M5.Lcd.setTextColor(TFT_WHITE);
  M5.Lcd.setCursor(5, 5);
  M5.Lcd.printf("%d", value);
}
```

これで指にかけた圧と連動して、ストーンの光が変わるようになりました。

<blockquote class="twitter-tweet"><p lang="zxx" dir="ltr"><a href="https://t.co/421lDxUAUY">pic.twitter.com/421lDxUAUY</a></p>&mdash; ufoo68 (@ufoo_yuta) <a href="https://twitter.com/ufoo_yuta/status/1729451500894912710?ref_src=twsrc%5Etfw">November 28, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# さいごに

以上までが某ガントレット製作の進捗状況となります。まだまだ課題はあると思っていて、

- 一部のLEDの点灯が弱い
    - 多分動画でも緑と青のストーンの光り方が弱いなーというのが見てわかるかと、、
    - 並列で複数のLEDを並べてしまうと緑や青のLEDが黄色や赤に比べて光りにくくなるようです
- 指パッチン関係ない
    - 現状のガントレットの仕様は指先に力を入れるだけで光ってしまう
    - でも現状の指の力で光の強弱を変えるという仕様も割と気に行っている
- 音を鳴らしたい
    - 本当は[M5StickC Plus用 Speaker 2 HAT](https://www.switch-science.com/products/8864)も購入している
    - 「指パッチンをしたら実際の指パッチンの音が出る」みたいなことをやりたいのだが、音の再生が思うように行かない。。。