みそみそミサイル発射装置 MISO MODEL1とは?
これはMastodon Advent Calendar 2018の12日目の記事です。
みなさんみそみそ〜
さて、気さくな挨拶としてmstdn.jpにて定番となっている「みそみそ〜」ですが、その「みそみそ〜」の魅力を高めるためのハードウェアをつくってみようと作成したものがこの「MISO MODEL1」です。
はたして「MISO MODEL1」とは一体何なのでしょうか?
動作中の様子はこちらです(YouTube)。
みそみそって何だよ
まずマストドンについて簡単に説明しますと、ツイッターのようなマイクロブログサービスをどのご家庭でも運営することができる画期的なプログラムです。その一つのサーバをインスタンスといい、インスタンス同士はリモートフォローという仕組みでつながることができます。mstdn.jpはそのインスタンスの中でも世界的に見ても規模の大きいものの一つです。
マストドンはツイッターとは異なり、ローカルタイムライン(LTL)というものがあります。LTLではフォローした人以外の、そのインスタンスに所属するユーザのトゥート(マストドンではつぶやきのことをトゥートといいます)をみることができます。そのため、フォローしてなくても、「同じインスタンスいれば、ユーザ同士がすでにやんわりと繋がっている状態」になっています。そういうこともあってか、フォロワー以外でもトゥートに反応してくれることがよくあります。
mstdn.jpの住人のみなさんは「みそみそ〜」や「にゃーん」という発言に呼応してくれます。
ぬるかる氏がmstdn.jpを管理していた時代には、メンテナンス後のテスト投稿として「きつね」とつぶやいていました。それに呼応する人たちがいたのが、ルーツの一つになっているのかもしれません。
misomiso.exe 爆誕
「みそみそ〜」と書き込んで反応があるのはとても楽しいので、こちらも全部拾ってブースト(ツイッターでいうリツイート、タンブラーでいうリブログ)したくなります。しかし人力ですべて拾うのは到底困難。じゃあその手順を完璧にこなすことはできないか、このシステムはそのような発想から始まりました。
しかし、単純な自動ファボ・ブーストというのはあまり頻度がおおいと迷惑なものになってしまいます。完全な自動ブーストは向こう側に人間がおらず、無作為にブーストされていることが明らかなので、ブーストされた人はこれっぽっちも面白くありません。ブーストを楽しくするには、ブーストする側とされる側の信頼関係が大切です。
そのため、このシステムでは「制限時間を設ける」ことと「手動起動」という点に重きを置いています。
プリセットされたキーワードを選択し、発射すると一定期間「みそみそ〜」というキーワードをフォローした相手のトゥートが流れるホームタイムライン(HTL)、インスタンスに所属するトゥートが流れるローカルタイムライン(LTL)からフィルタし、発見したらライクしてブーストを行います。発見した場合は制限時間が延長されます。
キーワードの選択と起動のタイミング、さらにそれに呼応する人々がいるという関係性が成り立たないと、1分ほどで動作が停止してしまうことになります。「呼応してくれる相手がいないと成り立たない」という不完全さ重要で、「全てを完全にブーストするただのマシン」ではないのが大事だと考えています。
まずは go-mastodon を使ったプログラムの習作として misomiso.exe というものを作成しました。これはその名前の通り、Windowsアプリケーションですが、macOSで作成されています。Goでは他のOSのバイナリが簡単にビルドできるのが楽しかったのでこういった名前になったのです。しかし、CLIアプリケーションですし、Windowsで実際に動作させるとセキュリティー警告がでてしまうので、あまり役に立たないものでした。だったらいっそのことこれをハードウェアしてしまおうと考えてMISO MODEL1に至るわけです。
ハードウェアの構成
このハードウェアは自分なりにいくつかの技術を試すための実証実験としての役割を持っています。Raspberry Piをつかって電子工作的な何かを作りたいけど、これまでなにを作るべきか思いつかなかったので、活用できずにいました。
今回は、昔いくつか購入して使いきれなかったRaspberry Pi Model B+と、ATTiny13A, NJM386を主要部品としてつかっています。
ミサイルスイッチ
最初に述べたとおり、常時動作するボットでの自動ブーストというものはあまり面白いものではありません。一定時間の制限したとしても、発動させるぎると多くの人に迷惑をかけてしまいます。そのため、自動ブースト機能発動には、ミサイル発射のように慎重かつ大胆な決断の上で実行される必要があります。ですので、ミサイル武装機構を有効にするためには、不用意な発動を防ぐためにカバーのついたミサイルスイッチを使用しています。このスイッチはカバーがついていてカバーを引きあげないとスイッチをオンにすることができません。
このスイッチには先端にLEDがついているのですが、コモン端子がプラス側だったことを後から気付きました。プログラム側で対処してもよかったのですが、別の処理をいれたくなかったので、極小のNANDチップをNOTとして入れてLEDのマイナス側に接続し、信号の極性を逆転させることで対処しています。
Goによるプログラミング
Goをつかってなにかプログラムを書きたいというのがありました。このプログラムは2つの構成に分かれており、実際にみそイルを発射するmisomiso.exeとハードウェアコントロールを主に行うプログラムです。Goの場合GitHubに公開されたコードを容易にインポートすることができるので、コードの公開と共有の敷居が低い印象がありました。
また、Goルーチンによる非同期処理がやりやすいため、ハードウェアのコントロールがとても楽です。
悩ましかったのはGPIO, SPIライブラリとして何を使うかでした。結局GPIOライブラリとしてgo-rpio、SPIはBCM2835.cのラッパーであるbcm2835を使用しました。
AVRによるRaspberry Piの電源コントロール
電源をトグルスイッチで安全にブート・シャットダウンするために、8ビットマイコンであるATTiny13Aを使用しました。Raspberry PiのOS Raspbianでは、/boot/config.txtに設定を追記することで、シャットダウンコマンドと動作状態をGPIO経由で送受信することができます。これにOS起動状態を通知する機能を追加して、MOSFETで電源のオンオフを行っています。Raspberry Piは消費電力が高く、電源抵抗が高いと動作が不安定になるため、MOSFETは最短の距離で配線しています。電源オフ状態になるとAVR自体もスリープモードにはいるため、待機電力がとても低く抑えられます。ちなみに、電源ランプはAVRでコントロールしています。
LED
複数個のLEDを少ない端子でコントロールするため、2連結した74HC595を使用して16個のLEDを3本の線でコントロールしています。これをRaspberry PiのSPIでコントロールしています。GoからのSPIの操作にはいろいろなやみましたが、結局BCM2835.cのラッパーであるGoライブラリから呼び出して操作しています。Cのコードを使用しているため、Goの魅力である他のOSでのビルドができないのがちょっと残念なところです。
ロータリーエンコーダ
ロータリーエンコーダは直接Raspberry Piに入力しています。こちらは割り込みをつかって状態を受信するのが理想的なのですが、結局はポーリングで状態をチェックしています。ウエイトのタイミングを絶妙に調整しないと理想的な感じで動いてくれませんでした。動作時のCPU占有量も大きめです。
LEDの点滅もGoルーチンでコントロールすると大変便利なのですが、並列動作する処理が多くなってくると点滅具合が雑になってきます。LEDとロータリーエンコーダは一度別のAVRで受けて処理したほうがよかったかもしれません。
音声出力
音声出力はRaspberry Piのヘッドホン端子からとって、NJM386Dで増幅しています。なかなかノイズと歪みがよくならず大変でしたが、電源回路の見直し、フィルタの追加を行い、さらに発音するときにNJM386Dの電源をGPIOからMOSFETを通して電源オンオフすることで、常時聞こえるノイズがなくなり、かなりよくなりました。NJM386Dは5Vで動作させていますが、この電圧はけっこうギリギリのようです。
それでもノイズや歪みは大きいですし、NJM386Dの電源をオンオフしているので、発音のたびにポコポコ音がなります。しかしむしろそれがいい味になっています。音声データはボイスロイド結月ゆかりを使用し、WAVで出力したものをaplayで再生しています。
NJM386DはLM386の互換品で、電子工作アンプの定番品です。ただ、最近のD級アンプと比較すると圧倒的に歪みが多く、ノイズにも敏感なようです。
Raspberry Piのオーディオ回路はSoCからPWMで出力されていて、それをフィルタすることで音声出力になっていますが、PWMなのでバッファアンプとして安価なロジックバッファが使われているようです。Pi Zeroにはこのフィルタとバッファアンプがありません。最初はRaspberry Pi Zero WHで作成していましたが、オーディオ出力をいろいろテストしている過程で壊してしまいました。
回路の作成
回路はまずブレッドボードで作成し、その後蛇の目基板で作成しました。蛇の目基板上の配線はスズメッキ線とウレタン被服線を使用しています。ウレタン被覆線(UEW線)は半田でしっかり熱を加えることで被服を溶かすことができるので蛇の目基板配線には便利なのですが、直接つけようとするとうまくつきません。慣れれば直接つけることもできますが、確実につけるには、面倒でも予備はんだをすることがポイントです。また、フラックスをよく使うのも大事です。
シャーシ
シャーシは100円ショップセリアで買ってきたブリキの箱です。シンプルで値段も安く加工も容易で重宝します。簡単な図面をOmniGraffleで作成し、それを印刷し剥がせるテープで貼り付け、その上からルータで穴開け。その後ドリルやハンドニブラーで加工という手順をとりました。それほど面倒でもなく綺麗に穴を開けることができました。
ソースコード
MISO MODEL1で使用したソースコードはこちらです。
回路図も公開したかったのですが書けていません。そのうち書きたいと考えています。
これが俺のIoTだ!
電子工作というものは楽しいものです。かつてはハードウェアとインターネットをつなげるには多くのリソースが必要でしたが、Raspberry PiやArduinoの登場のおかげで、電子工作とインターネットの距離は一気に縮みました。ここ数年IoTという言葉がもてはやされていますが、それは決して高度な技術力を持った企業だけのものではありません。個人の趣味のレベルでもアイデア次第でなんだかよくわからない、へんてこでおもしろいものが生み出せるようになりました。みなさんももし興味があったら「俺のIoTデバイス」を作ってみるのはいかがでしょうか?