電子工作初心者が謎の中華製サーマルプリンタをしばくまで

# ご挨拶
こんにちは〜。
皆さんはもうサンタさんに何をお願いするか決めましたか？
わたしはマシニングセンタをお願いします。

[42Tokyo Advent Calendar 2023](https://qiita.com/advent-calendar/2023/42tokyo) 20日目を担当します、ふるまい(komatsud)です。

## 昨日の記事

これから編集しますー

### おことわり

ある単一の情報についてまとめてある記事ではないです。

電子工作を始めたいなー という人に向けて、
わたしがどんな発想の元に、無理やり経験0から経験1になったかをまとめた記事です。
人生で初めて知らない人のリポジトリにプルリク出したりしました。
緊張した〜・・・

こういう発想でやっていたのかー ということが伝われば幸いです。

# 事の発端
時は2023年の6月まで遡ります。
わたしは42Tokyoで42電子工作部というものを作りました。

電子工作をやったことがないにも関わらず！ノリだけで！

しかし、リーダーのわたしがまともな成果もなくては部自体がマジお飾りになってしまうということで、何か役に立つものを作ろうと思いました。

で、42Tokyoの入学試験のテストの際、受験生の席をランダムで選び、席番をレシートに印字して払い出すマシンがあったら便利だろな〜（しかも試験のお手伝いもめちゃ楽できるよな〜）と思い、作ることにしました。

# アイデア
- 絶対サーマルプリンタがいい！
    - インクの補充を考えたくないから。
    - 印刷用紙も感熱紙だと安くていい！
- とりあえずプリンタ買うのに金がかかるので、購入したプリンタに合わせてデータの叩き込み方を考えよう。
    - 全くわからんので、とりあえず買ってから考えよう。

# プリンタ調達

というわけで、一番安いサーマルプリンタを探して購入しました。

電子工作の悪いところはどうあがいても金がかかるところ。

わたしは金がない学生です！

https://item.rakuten.co.jp/borderline/jxb115/?variantId=10405&s-id=ph_pc_itemname

![スクリーンショット 2023-11-15 14.13.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594257/975eb7f0-79da-1e2c-8f9a-1f1a0a313b05.png)

ロール10本つきで、じつに3,980円。

うむ、(比較的)安い！

そして、このプリンタをよくみると、なんと有線でデータ送受ができませんでした。
[Bluetooth Low Energy](https://www.bluetooth.com/learn-about-bluetooth/tech-overview/)規格対応らしい。データ送信には専用のスマホアプリがあるのみ。

当然パケットの説明などもない。

# どうにかする

この時点で想定していなかった問題が大量に発生しました。
- マイコンで無線通信する方法がわからない
    - BLEなんて聞いたこともない
- パケットとして何を送りつければいいのかわからない
    - 付属のスマホアプリの通信を読み取ってどういうパケットを送りつけてるか解析するしかないのか？


# マイコンで無線通信をやってみる
とりあえず、通信方式がBLEだということはわかっているので、マイコンでBLEを扱う先駆者を探します。
当然いくらでもいました。

Arduinoはわずかに触ったことがありました。というか、Arduinoしか触ったことがなかったので、「Arduino 無線通信」とか「Arduino Bluetooth」とかで検索しまくったと思います。

すると、ESP32というものを見つけました。

https://akizukidenshi.com/catalog/g/gM-15673/

![M-15673.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594257/8eb7e9a2-4e03-c026-7856-bc36dc4f4d03.jpeg)

ESP32というのはCPUの名前みたい。

Devkit、開発ボードだと、なんと元からアンテナがついていて、そのままパソコンに繋ぐだけでWifiやBluetooth通信ができ、しかもArduino互換らしい。

これだ！となって秋月に走りました。

## ESP32を使ってみる

Arduino IDEに入っていた、ESP32で無線通信をやるためのサンプルコードを動かしてみる。
近くのWi-fiルータを検索して、一覧で見ることができる！

なんとBLE関係のサンプルコードもあり、周辺に存在するアドバタイズ中のBLEデバイスの一覧を取得できた。

実際に見慣れたWi-fi一覧がターミナルに表示されるとかなりアツい。
おぉ〜・・・って気持ちになる！
つよい！

## BLEのドキュメントを調べる

もしBLEのドキュメント側でプリンタに対する通信方法が定められていたら、それに従ってパケットを送ることができるかもしれない。

これをBluetoothではプロファイルというらしい。

**Bluetooth SIG**という団体から、たくさんの標準プロファイルが公開されているので、この中から、BLEで、しかもプリンタのものを探す。

:::note
Bluetooth SIG（Bluetooth Special Interest Group）とは、近距離無線通信技術「Bluetooth」の規格策定や、Bluetooth技術利用に対する認証、普及推進などの活動を行う業界団体。
https://e-words.jp/w/Bluetooth_SIG.html
:::

https://www.bluetooth.com/specifications/specs/

![スクリーンショット 2023-12-09 16.58.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594257/f751b138-d8d4-0f1c-45ea-3d102569d1d9.png)


2日くらいかけて、検索窓(め)を皿にして探したのだが、なかった。

なかったので、なんかオリジナルのプロファイルで通信をやっているのだろう、ということがわかった。；；

# ESPとプリンターで通信する

さて、ここまでで無線通信をやる方法はわかりました。

しかし、肝心のこの猫プリンターにどんなパケットを送りつければいいのか、てんでわからないままです。

というわけでとりあえずたくさんググりました。

## プリンターと通信する方法

すると、どんなコトにも先駆者はいるもので・・・

なんとこのプリンター、激安ということで既に割っている人がいました。集合知！

https://github.com/bitbank2/Thermal_Printer
![スクリーンショット 2023-12-15 10.39.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594257/4c84bb19-1f0d-bb86-8da6-2d947b5f53c5.png)

ただこれだとなんだかうまく動かなくて。
最終的にこちらのライブラリを使わせていただきました。

https://github.com/TheNitek/CatGFX
![スクリーンショット 2023-12-15 10.43.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594257/7c46d03c-41b1-339c-04aa-ff5df315887c.png)

確かに、なんの生き物なのかわからないね〜。

## 実際に通信してみる

実際にESPにこのライブラリのテストコードを導入し、手元のプリンターを検索させてみました。

・・・が、見つからない。

いつまでたっても全然見つからない。マッチングしない。

なんでだろう？

## ライブラリのコードを見る

その謎はライブラリの中にあるだろう と思ったわたしは、また3日くらいかけてライブラリの中身のコードを漁り始めました。

そして、どこに問題があったか突き止めました。

## 見つけた問題点

BLEは、デバイスの名前で検索して接続先を決めることができます。（MACアドレスじゃなくてよい）

そして、この猫プリンターが持ちうるデバイス名は、3種類くらいしか知られていなかったらしく、
ライブラリの関数の外側から、プリンターのデバイス名を指定できるようになっていませんでした。
具体的には、ライブラリの中で、リテラルで書かれていました。

わたしの手元にある猫プリンターのデバイス名が、それらのどれとも一致しなかったので、検索で引っかからなかったようです。

## 解消

そのため、ライブラリに手を入れることにしました。

本当は、デバイス検索の関数に引数でデバイス名を渡せるようにしたかったのですが、関数のプロトタイプを変更すると今までのコードとの互換性がなくなり、テストコードまで書き換える必要が出てきてしまい、嫌です。

現状、探すデバイス名を複数配列で持たせる設定になっていました。
そのため、このリストにデバイス名を追加したり、リストを空にする関数を追加しました。

ついでにプルリクも出し、マージしてもらいました。

そのプルリク。
https://github.com/TheNitek/CatGFX/pull/5

## 結果

検索できるようにしたところ、
通信用のプログラムはライブラリのものをお借りし、無事通信できるように〜！

![IMG_20230818_191400.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594257/92fb50f3-a24b-8943-1878-8f97fead0708.jpeg)

![IMG_20230818_191705.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594257/618ffc53-e57d-6dc7-b265-abcab2ebd4b8.jpeg)

うれしいな〜！

# ランダムに席を選択するプログラムを作成する

した（割愛）

ざっくり説明すると、人を座らせたい席の総数をランダムで選び続け、被りなし選ばれないものなしで払い出すようにしたかったです。

Fisher–Yates shuffleというらしいです。

https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%83%E3%82%B7%E3%83%A3%E3%83%BC%E2%80%93%E3%82%A4%E3%82%A7%E3%83%BC%E3%83%84%E3%81%AE%E3%82%B7%E3%83%A3%E3%83%83%E3%83%95%E3%83%AB

この番号と、席の名前を対応づけるようにしました。
数時間もかからずにできました。

強いていうとデバッグがちょい面倒でした。

# 実証

実際に入学試験で使ってみました。

すると、席番を70枚ほど払い出したところで急にプログラムにリセットがかかってしまいました・・・

なぜでしょう？

# 原因追求

- プリンタは大丈夫そう。
    -  払い出す中身にリセットがかかっていた。
        -  Seed値が同じなら同じ枚数払い出せば再現性があるが、これをESPのピンのノイズから取得しており、一度リセットしてしまうと再現不可能
- マイコン側で何かがあった
    - 電源をノートパソコンから供給していた。
        - 急な電圧変化があり、リセットされた説。
    - 温度が上がりすぎた説。
        - 温度が手で触って熱っ！となるくらい上がっていた。
        - ヒートシンクなどをつけてどうにかなるのだろうか・・・。
    - いずれにせよ、ノートパソコンは完全に電源として使っており、ログを取っていなかったのでよくわからない・・・。
        - ログを取るべきであった。

## 問題解消

- Seed値がランダムなうえ、教えてくれないせいで結果が再現不可能である。
→　最初に払い出す紙に、今回の席一覧で採用したSeed値を書き込むようにした。また、プログラム側からSeed値を手動で設定することもできるようにした。

ついでにいろんな情報を追加しました。

![IMG_20230820_113523.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594257/d1c3d43d-096b-a3fd-e668-6e0bc89bfa69.jpeg)

- ノートパソコンから電源を供給するのはよくないかもしれない。

知らなかった・・・。
いろいろ調べて、ノートパソコンは、急に大きな電力を要求されると、自分を守るために供給する電力を制限することを知りました。
つまり、電源はコンセントから直接供給したほうがいいらしいです。

https://www.mgo-tec.com/blog-entry-trouble-shooting-esp32-wroom.html/5
http://nemuisan.blog.bai.ne.jp/?eid=221355

電源アダプタを買ってきた。

- 温度が上がりすぎた説。

多分よくないと思ったので、申し訳程度にヒートシンクを取り付けました。
温度が最大70度くらいまで達していたところ、６０度に届かない・・・くらいに抑えられたみたいです。

- ログを取るべきだった。

ノートパソコンにつないでいるときは取るようにしました。
しかし本番はコンセントから電源を供給するので取ることができません。それは諦めました。


# 結果2

試験は定期的にあるので、次の試験が行われる前に以上の修正を全て行い、もう一度試すことにしました。
当時の試験の参加者が120人ほどでした(確か)。

前回は70人分ほど払い出したところでマイコンがぶっ壊れていたのだが、
なんと、120人全員分のくじを払い出しても停止しないようになりました。

うれしいね〜。

今まですごい勢いで押しかけてくる受験生を、みんなが立ちっぱなしで流すように分担して席案内していたのが、
座っていてボタン押せ！というだけでよくなりました。
楽すぎる！

しかも、ボタンの押し心地が楽しく、券面が払い出されるということで、受験生からの評判もよかったので、嬉しかったです。

# 後記

以上です。ありがとうございましたー

# 明日の記事

未編集。