今年のGWは外で自転車を乗らず、ずっとZwiftをしていた。去年は自分のロードバイク買って初のGWだったので、箱根行ったりロングライドを楽しんでいた気がする。

今年は自転車以外にもやりたいことが増えてきて、かつ、まとまった学習の時間が取れてなかったので(子育てしてるといつも細切れ…)、ここぞとばかりにArduinoを使えるようにした。

マンションのゴミ捨て場が堅牢になった

うちのマンションは古いUR賃貸で、ゴミ捨て場もコンクリートの棚があるだけのオープンなやつで、猫やカラスがよくゴミを漁っていた。

ゴミ出しは「当日の朝8時までに出してね」と張り紙が出ていたものの、掃除のおばちゃんが「私らが片付けとくから別にいつでも出していいよ」と言っていて、ここの住民も適当なのでみんな雑に出していた。

ところが、年明けくらいからマンション全体の補修工事が始まって、ゴミ捨て場も厳重な鉄格子製になった。鍵はかかってないけど以前みたいにゴミを放り投げるわけに行かず、入口のドアを開けて、ゴミを置いて、ドアを閉める、という工程が必要になった。ゴミの収集日の表示も新しいものに変わり、目立つ位置に貼られている。違う日に出すのはなんか気まずい。

もう10年くらいここに住んでいるが、「火曜が燃えるゴミだったような気がする…」という意識の低さ。これをなんとか直したいと思うようになった。

ごみ収集カレンダーが役に立たない

三鷹市のごみ収集カレンダー

燃えるゴミは月曜だった。火曜と水曜は週によって回収するものがちょっと違う。有害ゴミは空き瓶コーナーと一緒になっていたのでまとめて出していたが、回収は金曜だった。

というように、収集場所のレイアウトの悪さもあって頭に全然入らない。カレンダーを玄関に貼ってもいいけど、見ている当日が光ってないと見つけられない。Googleカレンダーに入れれば…とちょっと思ったが、そもそもカレンダーをあんまり見ない。

Android向けにごみ出しアプリもあるが…

三鷹市のごみ収集アプリ

なんだかよくわからない。画面下に詳細が表示されるようだが、土日は回収がないので空白だった。「今週のごみ出し」と書いてある週間カレンダーもアイコンが多すぎてよくわからない。今日は5月4日なんだけどどこに書いてある?あと月曜始まりじゃないと脳が拒否するのでこの形式は読めない。アプリから通知が出せるっぽいけど、自宅警備員で出勤しないので、朝の決まった時間に通知されても困る(わがまま)。

というように既存の物では解決できなかったので、自分で作ることにした。

「Arduinoをはじめよう」を買ってから6年が過ぎていました

Arduinoをはじめよう、の注文履歴

2011年くらいにMakeでArduinoを知って、その後オライリーから本が出たので、スイッチサイエンスのキットと合わせて買っていた。Lチカはとりあえずやったものの、何ができるのかさっぱりわからず、面白くなくて触っていなかった。

去年の技術書典でNefryの展示があり、プラレールっぽい電車の中に入れて「電車の遅延を検知したら光る」という本を売っていた。子供(電車好き)も興味があったので買ってみた。中央線オレンジ総武線黄色東西線京王井の頭線レインボーという、車両に合わせた色でLEDを光らせる実装まではやったが、電車が遅延する頃に子供が家にいないという問題があり、あまり楽しんでもらえなかった。

あと、こないだなんとなく勢いでM5Stackも買っていて、参考書を買って満足する人みたいになってきている。作りたいものはいくつかあるので、仕様を決めて、本も新しく買い足して、まとまった時間をぶつけることにした。

まずはこの本で復習

みんなのArduino入門

オライリー本が家になかったので、入門書を新しく買った。「みんなの〜」がめちゃ分かりやすくてよかった。「たのしくできる〜」の方はもう少し実践向けで、センサー類を買い足さないといけないのでまだ途中。

ちなみに、オライリー本は三鷹図書館にあげちゃったような記憶がうっすらある。
読み終えた本を寄贈したいのですが? | 三鷹市立図書館

仕様を考える

今回やりたいことは「当日と翌日のゴミ出しの内容が見える」というもの。ゴミの収集は朝8時〜9時くらいなので、当日だけだとほぼ意味がない。翌日分が見えれば前日の夜から準備できる。

必要なのはディスプレイくらい。センサーも必要ないし、WiFiで通知とかも必要ない。内蔵の時計を見て曜日の判定をするだけで良さそう。

どれを使うか選ぶ

Arduino UNOにはディスプレイをまだ買ってなかった。M5Stackなら全部入りだから行けるけど高機能すぎてなんかもったいない気持ち。Nefryはディスプレイ無かったしな…と思って取り出したら ディスプレイ付いてた 。そういうセットを買ってたらしい。

あとは適当に実装する

JSで仮実装

なんか面倒くさいのは「奇数週/偶数週の時にほげほげ」みたいな所だけなので、そこだけ先にJSで書いた。

Atomからコンパイル&転送できるようにする

Arduinoの標準IDEは機能が少なくて使いづらいので、Atomでできるようにした。「Atom Arduino」で検索すると PlatformIO を使うとできる、という記事がいくつか出てくる。

An open source ecosystem for IoT development · PlatformIO

トップページの Install PlatformIO Now を押すと思いっきり VSCode 用が出てくるが、よく見ると Atom 用もある。PlatformIO的にはVSCode推しらしい。 Install for Atom を押すとインストール方法が出てくる。プラグインとかを落とすのかと思ったら、エディタ内のパッケージから入れるらしい。慣れた手付きでインストールした。

PlatformIOを入れたAtom

なんか凄いことになってしまったので、即座にアンインストールしてVSCodeを入れて、そっちにインストールした。

VSCodeからArduinoのコードを触れるようになったが…

PlatformIOを入れたVSCode

ステータスバーの左のアイコンから検証や転送ができて、クラウドにも保存できたりする。シリアルモニタも出せるしなんか色々便利そう…なんだけど、新規プロジェクトを作ったら上のスクショみたいなファイルが作られて、Arduinoで使う .ino ファイルの代わりに .cpp というファイルになっている。C++…?

サンプルコードとかを試すとArduino UNOではうまく行ったが、Nefryはよく分からずできなかった。関係ない地雷を踏みそうだったのでおとなしく標準IDEを使うことにした。

時間がずれるらしい

古いWindowsでもよく時計がずれていたので、Arduinoもそうなんだろうな〜と思っていたが、そうだった。あと時間を保存するためにはRTCとかいう謎の部品が必要らしい。そもそも電源投入時にリセットされるから、どうやって時間設定するんだ…?

じゃあHTTPで日本標準時とかのAPI叩けばいいよね、と「Arduino json」で出てきたページのコードを貼り付けたら、ライブラリのバージョンが上がって書き方が変わったらしくエラーが出る。

その辺を調べるのも一苦労でなんとかパースできるようになったら、Arduinoは標準でNTPが使えるという記事を見つけて、そっちに乗り換えた。

日本語を出したい

自分が見るだけなら英語でもいいんだけど、Unburnable って出てても見慣れないから戸惑いそう。あと子供が読めないのでゴミ出しを手伝ってもらえない。そのため日本語を出したい。

Nefryの組み込み関数でディスプレイに文字を流せるが、3行まで、画面上部に「Nefry Printdialog」という文字が勝手に出てしまう、という制約があった。あとそもそも日本語が使えない。

NefryBTで日本語表示させてみる - Qiita というそのまんまな記事を試して表示することができたが、好きな位置にレイアウトするのがちょっと面倒そう。座標の絶対値、position: absolute;みたいな感じでやれるけど、文字のサイズとか調べるの面倒くさい。じゃあ画像でやろうか。

XBMフォーマットがなぜか反転する

Nefryのディスプレイを使おう - Qiita という記事を参考にしてXBMフォーマットの画像を作って表示した所、なぜか白黒反転してしまった。

Photoshop上ではこうなってるのになぜか反転する。上の記事の人は黒背景に白文字を出せていたのでしばらく悩んでいた所、背景が透過になった画像を変換サービスに通すとこうなってしまう のがわかった。Photoshopの PNGでクイック書き出し をやっていたので全然気づけなかった。丁寧に書き出したらうまく行った。

ちなみに、フォントはドラクエフォントを使った。手持ちのビットマップ系フォントのサイズとか雰囲気が合わなくて、ふと思い出したのがこれだった。

こうすると雰囲気が出ていい。

ディスプレイの解像度は 128x64 で、Photoshop上でレイアウトしてみたけどかなり狭い。いろいろ出したかったけど、上下2分割にして日付とゴミの種類を出すだけにした。

C++がまったくわからん

  • switch文の判定に文字列を入れたい → 数値しか使えない(enumだったら行けるとあった。enumって何?)
  • 画像の大きさ(int)、埋め込み画像データ(char)をまとめて配列に入れたい → 入らない
  • ゴミの日の判定ロジックで trash_type = "plastic" って出して、それを eval(trash_type + "_xbm") みたいに使いたい → 使えない
  • 似たような感じで img[trash_type][width] とかアクセスしたい → できない
  • 画像の大きさが縦横あるので、 return width, height としたい → 受け取り方がわからない
  • * って何?

基本的な文法もさっぱりわからんので全然駄目だった。書き方が間違ってるだけでできそうな気もするけど、JSやPHPみたいにやってうまく行かず地雷を踏むたびにひっくり返っていた。赤ちゃんだからしょうがない。

そんな感じで4日消費したら完成した

まだ回路図の見方がわからないし、上のようにC++の常識がないのだけれど、とりあえず動かせるようになった。フリスクケースに入れて、サランラップで適当にカバーを付けて、台所のゴミ箱の近くに貼った。

NefryはGroveモジュールが使えるので、Grove規格のセンサー類も見ている。4つある白い差込口に挿せるらしい。1,000円くらいで火炎センサーとかが売っているので、台所に置いてるしガスの消し忘れ機能とか足したい。

あとはじめからスイッチが1個付いてるが、今のところ使っていない。押したらAlexaが子供に向かって「宿題やった?」って聞くようにしようかな、親が言うと角が立つけど、機械の言うことは聞いてくれるしな、と思っているが、Alexaが親に言わされてるって気づいたらどうなるんだ…?