tag:blogger.com,1999:blog-24544139449845264632024-02-03T09:14:04.213+09:00niccolliveniccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.comBlogger78125tag:blogger.com,1999:blog-2454413944984526463.post-35289983106848146722021-12-10T20:09:00.007+09:002021-12-10T20:13:20.533+09:00Bangle.jsを購入して電源を入れるまで<h4>Banlge.jsを買いました</h4>
<p>興味本位でBangle.jsのKickstarterプロジェクトにBackしまして、実機が2020年に届きました。</p>
<p><ul>
<li>Javascriptが動き、自分でコードを書いてアプリが作れる。</li>
<li>アプリのインストールはWeb Bluetooth APIを通してブラウザから。</li>
</ul></p>
<p>と、なかなかにおもしろそうだったのですが、この時点で工事設計認証の取得は明確になっていませんでした。ダメならダメで電源を入れなければいいだろうと思いBackすることに。</p>
<h4>総務省の特例制度を活用することに</h4>
<p>「<a href="https://www.watch.impress.co.jp/docs/topic/1221095.html">技適未取得のWi-Fi機器が180日使える。実験等の特例制度に申請</a>」</p>
<p>Bluetoothを動かすにあたり、工事設計認証を取得していない機器でも正直かつ適切に申請すれば実験を認めてくれる制度を活用することとしました。実物が届くまでの間に始まったような気がしています。<a href="https://www.espruino.com/files/Bangle.js-FCC.pdf">FCCの申請は済んでいてIDが発行されている</a>ことから、総務省に申請書類を持参して数日後にメールでOKの連絡を受け取りました。総務省で書類を受けてくださった方が「近々オンラインで完結するようにします」と話していましたが、今ならもう<a href="https://exp-sp.denpa.soumu.go.jp/public/">そのようになっている</a>ようです。ありがたいですね。</p>
<h4>実機を動かしてみる</h4>
<p><div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEj8YlpTufvLXepRZiG3GK2sWqwRk2fDXUqKy6Ogq02RJd2c0cRvZo_HbOzoxDx1uTczhRW8h7UHcr6DrJ7tQBuJiUcTRsOShcmYH5i-RhLloBcvZDOXX3kjDgyPkzSr6G1v5qpWRfKJ8hNBR7bbNbk1E8hJBOGYQpJ5EqOT1xb4hbtpsLbe8wQ_JxYL=s2048" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" height="320" data-original-height="2048" data-original-width="1536" src="https://blogger.googleusercontent.com/img/a/AVvXsEj8YlpTufvLXepRZiG3GK2sWqwRk2fDXUqKy6Ogq02RJd2c0cRvZo_HbOzoxDx1uTczhRW8h7UHcr6DrJ7tQBuJiUcTRsOShcmYH5i-RhLloBcvZDOXX3kjDgyPkzSr6G1v5qpWRfKJ8hNBR7bbNbk1E8hJBOGYQpJ5EqOT1xb4hbtpsLbe8wQ_JxYL=s320"/></a></div><div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjk7CeRVA-GeCPKWWAaVrmj8q05wpdvGVprzYk2h96o4NETYrhwFsgRVYNycSMt3M9gD4_NQPsQ3npht-jfZn9f9rPZ3jtAq7w3EAz0mXJZ0J83Vg4ceOaPvFDErLIsTYdLBzgki6Wf36pO_Jbmo_4E8pP6ilZL2BMbOpbkRl-jnvlv1TNAN0HKKwsD=s2048" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="1536" data-original-width="2048" src="https://blogger.googleusercontent.com/img/a/AVvXsEjk7CeRVA-GeCPKWWAaVrmj8q05wpdvGVprzYk2h96o4NETYrhwFsgRVYNycSMt3M9gD4_NQPsQ3npht-jfZn9f9rPZ3jtAq7w3EAz0mXJZ0J83Vg4ceOaPvFDErLIsTYdLBzgki6Wf36pO_Jbmo_4E8pP6ilZL2BMbOpbkRl-jnvlv1TNAN0HKKwsD=s320"/></a></div></p>
<p>アプリを動かしたり心拍数をはかったりなんかして使い心地・動作感を見たりなどしました。Web Bluetooth APIの是非は別にして、アプリのインストールもすべてブラウザから直接Bluetoothで制御するのは、機能としてはおもしろかったです。スマホだと対応機種を持っていなかったため、常にノートパソコンとともに使う機種ではありました。</p>
<h4>少し触ったあとの廃止届出と管理措置</h4>
<p>わりとすぐ飽きたというか、Web Bluetooth APIが前提なのはちょっと勝手が悪いなというのもあって、半月くらい触ったあと、一応実験期間いっぱいまで自宅に放置していました。仕組みがよく整えられていて、期間終了が近づくと登録したメールアドレスに総務省からお知らせが届きました。廃止届出はWebで完結するようになっており、メール受信後忘れないうちに済ませることができました。その後、Bangle.js本体は自宅で電源を入れることなく保管しています。今はもうリチウム電池が過放電しているかもしれず、そろそろ廃棄してもいいかなと思ってきました。総務省の特例制度はとても便利かつ擦り寄ってきてくれている印象があって、互いの信頼感を損ねないよう襟を正して活用していきたいと思います。</p>
niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-78856426946491188562021-10-14T22:40:00.001+09:002021-10-14T22:40:07.993+09:00Raspberry Pi 4をTime Capsuleにする<p><div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKuVFjduRwZlKLsYf5GKO5JUZyXgGxkI8u7DUlURvD0_PmIKLvrCklx3WBDc6o4FX-ltQaNXHPcDuVVntOxiam_HG42_8mklw_wQ1JXFimd1LXgWz1AkEWbxbt6L_M7wWPgqCtmBHx2ns/s2048/IMG_9849.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="1536" data-original-width="2048" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKuVFjduRwZlKLsYf5GKO5JUZyXgGxkI8u7DUlURvD0_PmIKLvrCklx3WBDc6o4FX-ltQaNXHPcDuVVntOxiam_HG42_8mklw_wQ1JXFimd1LXgWz1AkEWbxbt6L_M7wWPgqCtmBHx2ns/s320/IMG_9849.jpg"/></a></div></p>
<p>長年Macのバックアップとして使っていたTime Capsuleだったが、AC電源直結の勝手の悪さ・発熱・フットプリントのでかさから、Raspberry Pi 4で置き換えることにした。下記の順序で実装できた。64bitのOSを使いたかったので、Raspberry Pi OSではなく、Ubuntu Server 20.04をもとにしている。</p>
<p><ol>
<li>avahiのインストールと設定</li>
<li>ハードディスクの設定</li>
<li>sambaのインストールと設定</li>
</ol></p>
<h4>avahiのインストールと設定</h4>
<p>
<code>
$ sudo hostnamectl set-hostname RPi4 <br />
$ sudo apt-get install avahi-daemon <br />
$ sudo mv samba.service /etc/avahi/services/samba.service <br />
$ sudo service avahi-daemon restart <br />
</code>
</p>
<p>hostnameを設定することで、MacのFinderに表示される名前が決まる。わかりやすい名前にするとよい。</p>
<p>3行目でコピーしている設定ファイルは<a href="https://github.com/niccolli/RPi4ConfigBackup/blob/master/SMB/samba.service">こちら</a>。設定ファイル内にTime Capsule対応を謳うことで、Mac側から認識できるようにする。<a href="https://www.reddit.com/r/linuxquestions/comments/juyue6/samba_share_as_time_machine_backup_getting/">Redditのスレッドに書いてあった</a>が、参考になった投稿が見つからない。</p>
<h4>ハードディスクの設定</h4>
<p>
<code>
$ ls -lha /dev/disk/by-uuid # Time Capsule用HDDのUUIDを確認<br />
$ sudo vi /etc/fstab # fstabにUUIDを記載。オプションはリポジトリ内のfstabを参考に。
</code>
</p>
<p>USB 3.0対応の外付けハードディスクを接続した。ハードディスクのファイルシステムは、Macからは関係ないのでなんでもいい。Linuxなのでext4にしている。ハードディスクのUUIDをfstabに記載することで、特定のハードディスクが接続されたときだけ定位置にマウントできることを知った。</p>
<h4>sambaのインストールと設定</h4>
<p>
<code>
$ sudo apt-get install samba<br />
$ sudo adduser timemachine # パスワードは自分がわかるもの、アカウント情報は空白でよい。<br />
$ sudo smbpasswd -a timemachine # SMBパスワードの設定<br />
$ sudo mkdir /mnt/timemachine<br />
$ sudo chown -R timemachine: /mnt/timemachine<br />
$ sudo mv smb.conf /etc/samba/smb.conf<br />
$ sudo service smbd reload<br />
</code>
</p>
<p>Raspberry Pi側に、samba用のユーザーを作成する。ユーザー用・SMB用のそれぞれにパスワードを設定する。SMB用パスワードは、Macから接続するときに使用する。</p>
<p>マウントポイントはfstabに記載したとおりの場所にする。マウントポイントのオーナーをsamba用アカウントに設定しないと、ファイル書き込みのできない共有になってしまうので注意する。</p>
<p>コピーしている設定ファイルは<a href="https://github.com/niccolli/RPi4ConfigBackup/blob/master/SMB/smb.conf">こちら</a>。ファイル末尾のfruit行がTime Capsule用設定となっている。</p>
<h4>おわりに</h4>
<p><div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5ui_7_VIPLufc097reH0UN3ys0UrRyowxXzPcZI0tIAmprlGQQz7jU51QJlfkzlQd5TE2g_itQHwACOet9WvrR8kycQNOUtOIWTg5Tz2gYg3Ty3H8tr4pCHtRbEcmcVqTYjVc9J42_Ic/s1560/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2021-10-14+22.35.56.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="1136" data-original-width="1560" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5ui_7_VIPLufc097reH0UN3ys0UrRyowxXzPcZI0tIAmprlGQQz7jU51QJlfkzlQd5TE2g_itQHwACOet9WvrR8kycQNOUtOIWTg5Tz2gYg3Ty3H8tr4pCHtRbEcmcVqTYjVc9J42_Ic/s320/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2021-10-14+22.35.56.png"/></a></div></p>
<p>これでRaspberry PiをTime Capsuleとして設定することができた。Raspberry PiはSDカードが壊れるので、<a href="https://github.com/niccolli/RPi4ConfigBackup/tree/master/SMB">GitHub</a>に何も考えずに復旧できるよう手順をまとめている。今後はAnsible等で自動的に展開できるようにしたい。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-57080775669246088292020-06-04T00:21:00.000+09:002020-06-04T00:21:04.873+09:00ゲームボーイの画面にアニメーションを表示する<p><blockquote class="twitter-tweet"><p lang="ja" dir="ltr">在宅勤務の間はずっと動かしておこう。変な落ち着きがある。 <a href="https://t.co/muFD0k7j5c">pic.twitter.com/muFD0k7j5c</a></p>— niccolli (@niccolli) <a href="https://twitter.com/niccolli/status/1264759545177333761?ref_src=twsrc%5Etfw">May 25, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p>おもしろ半分でParty Parrotをゲームボーイで動かしたら、結構な数の皆さんに回覧いただきました。せっかくなので、仕組みをまとめておきます。</p>
<h4>実装までの流れ</h4>
<p>次のフローで組み立てていきます。</p>
<p><ol>
<li>絵を用意する</li>
<li>ゲームボーイの表示データに変換する</li>
<li>順番に表示する</li>
</ol></p>
<h4>絵を用意する</h4>
<p>Party Parrotは<a href="https://ja.wikipedia.org/wiki/ファイル:Party_Parrot.gif">Wikipedia</a>のものを使いました。gifアニメを各コマに分解し、4階調に変換します。これはimagemagickを使いました。</p>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYRc_MTf_qlnFTZ_RMZQ5j7Ve-aPA7W7d8XRUUI01ehRhjVxXsfHVZJ3OYTq7_6mdYUUta_1CKlEd6nmGn8ceDU4Tw-L_jlwQNsDLvlpAQwZ2tklO-DmGgyzwmfM7OJ6f9dwk614pesV8/s1600/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2020-06-03+22.55.29.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYRc_MTf_qlnFTZ_RMZQ5j7Ve-aPA7W7d8XRUUI01ehRhjVxXsfHVZJ3OYTq7_6mdYUUta_1CKlEd6nmGn8ceDU4Tw-L_jlwQNsDLvlpAQwZ2tklO-DmGgyzwmfM7OJ6f9dwk614pesV8/s320/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2020-06-03+22.55.29.png" width="500" height="311" data-original-width="1600" data-original-height="995" /></a></p>
<p>この白黒画像を、ゲームボーイの画面表示に合わせたビット列に変換していきます。</p>
<h4>ゲームボーイの表示データに変換する</h4>
<p><a href="https://note.com/lasto/n/n1f2c603697d5">任意の絵をゲームボーイにする方法が例示されている</a>ので、それに従います。リンク先の解説でいくつか挙げられている注意点がさらに厳しくなるので気をつけてください。</p>
<p><ul>
<li>8x8サイズのパーツが255種類に収まるように絵を描きます→127種類に収めてください</li>
<li>Pic2Tilesで生成されたC言語のファイルからconstを外すよう記載がありますが、一部を除き外してはいけません。</li>
</ul></p>
<p>パーツを127種類に収める点について。1枚絵の表示であれば255種類すべて使えるのですが、アニメにする関係で半分に制限されます。1枚表示している間にもう一方の絵を用意し、整ったところで一気に表示を切り替える方法をとっているため、このもう一方を用意するために半分ずつしか使えないということになります。</p>
<p>constを外してはいけない点について。現時点のGBDKではコンパイルエラーが出なくて問題がないことと、constなしでは起動時にRAMに展開されるために今回のように10コマ使用すると、5コマ以上でRAMがオーバーフローするためゲームボーイが落ちます。画像のデータそのものは動的に変化する必要がないので、基本的にconstのままROMにとどめておくようにしてください。例外はmap.Cのうち偶数枚目のコマのものです。変換時に生成されるCファイルには「タイル内のデータ」と「どの位置にどのタイルを並べるかを定義したデータ」が含まれています。後者のデータは常にタイル内データが専用の領域の先頭から並んでいる前提で生成されるので、偶数コマのデータは128個分のオフセットが必要になります。あらかじめ数字を書き換えておくか、constを外してゲームの起動時に初期化の一環として一気に書き換える必要があります。今回のParty Parrotでは面倒だったので起動時に書き換えましたが、コマが多かったり他の用途でRAMを使っていたりで容量が逼迫しているとconstのまま書き換えておいたほうがよいです。</p>
<h4>順番に表示する</h4>
<p>GBDKに用意されているタイル表示用の関数を使います。基本的に下記のコードを繰り返すだけです。</p>
<p><code>
set_bkg_data(0,100,TileData_pp0);
set_bkg_tiles(0,0,20,18,MapData_pp0);
delay(50);
set_bkg_data(100,100,TileData_pp1);
set_bkg_tiles(0,0,20,18,MapData_pp1);
delay(50);
</code></p>
<p>set_bkg_dataでタイル内のデータを専用領域にコピーします。第1引数の数字がコピー位置のオフセットです。Party Parrotの場合はどのコマもタイル数が100以下だったので100としています。set_bkg_tilesは、指定した範囲をマップデータに従って書き換えるものです。</p>
<p>次のコマのタイルデータを書き込む際、多少時間を空けないと表示が崩れることがあったのでdelayを入れています。</p>
<h4>さいごに</h4>
<p>ポケットカメラの撮影時プレビューを見ると、明らかにタイルデータでは間に合わなさそうなドット画像の動画が表示されているので、まだ改善の余地はあるのかもしれません。この記事のやりかたでも、タイルとマップデータをカートリッジに入りきるだけ用意すれば、それなりの時間のアニメーションを表示させることもできるなど、可能性は残しています。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-36417689205008698672020-05-16T17:35:00.000+09:002020-05-16T17:35:27.553+09:00Nordic SDKのサンプルコードにないHIDサービスを実装する<p>Nordic nRF5 SDKには、HIDの実装例としてキーボードとマウスが公開されています。HIDはそれ以外の使われ方も定義されていますが、サンプルは公開されていないうえインターネットでも実装例は少ないです。Gamepadの実装をやってみたところいろいろな苦労があったので、参考のためにまとめておきます。</p>
<h4>マウスを参考にして、USBのHIDを載せる。</h4>
<p>と<a href="https://devzone.nordicsemi.com/f/nordic-q-a/43358/please-provide-a-bluetooth-joystick-gamepad-example-in-the-sdk/169666#169666">フォーラムに書いてあります</a>。基本的に、次の流れで調整すると動きます。</p>
<p><ol>
<li>レポートディスクリプタの中身を整える (コード内ではrep_map_data[]に定義)</li>
<li>レポートディスクリプタに記載したルールに従ってバイト列を作る</li>
<li>データを送信する (コード内ではble_hids_inp_rep_send()関数で送信)</li>
</ol></p>
<h4>レポートディスクリプタの中身を整える</h4>
<p>レポートディスクリプタは、送信したビット列のデータをどのように解釈するかを定義したものです。なので、中身は自分で必要なものをきちんと定義する必要があります。Gamepadの場合はどのように指定すればいいのかは、下記のリンクが参考になりました。</p>
<p><ul>
<li><a href="https://qiita.com/toyoshim/items/59c1af01919cb3494512">*PiをUSBゲームパッドとして動作させる - Qiita</a></li>
<li><a href="https://github.com/Shyri/gba-bt-hid/blob/master/esp32/main/hc05.c">gba-bt-hid/hc05.c at master · Shyri/gba-bt-hid</a></li>
</ul></p>
<p>今回は下記のように指定しています。ゲームボーイのキー操作を入力としたいので、8ビットの入力を4つのボタンと1つの方向キーとして扱います。</p>
<p><pre><code>static uint8_t rep_map_data[] ={
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x05, // USAGE (Gamepad)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x39, // USAGE (Hat switch) // 十字キー
0x15, 0x00, // LOGICAL MAXIMUM (0) // このデータは0〜7の範囲
0x25, 0x07, // LOGICAL MAXIMUM (7)
0x35, 0x00, // PHYSICAL MINIMUM (0) // 0〜7が
0x46, 0x3b, 0x01, // PHYSICAL MAXIMUM (315) // 0〜315に対応
0x75, 0x04, // REPORT SIZE (4) // SIZEとCOUNTで
0x95, 0x01, // REPORT COUNT (1) // 4ビットが1個の意味
0x65, 0x14, // UNIT (Degrees) // 単位は角度
0x81, 0x42, // INPUT (DATA, VARIABLE, ABS, NULL)
0x05, 0x09, // USAGE_PAGE (Button) // ボタン単体
0x15, 0x00, // LOGICAL MINIMUM (0) // このデータは0〜1の範囲
0x25, 0x01, // LOGICAL MAXIMUM (1)
0x19, 0x01, // USAGE MINIMUM (1)
0x29, 0x04, // USAGE MAXIMUM (4)
0x75, 0x01, // REPORT SIZE (1) // SIZEとCOUNTで
0x95, 0x04, // REPORT COUNT (4) // 1ビットが4個の意味
0x81, 0x02, // INPUT (DATA, VARIABLE, ABS)
0xc0, // END_COLLECTION
};
</code></pre></p>
<h4>ルールに従ってバイト列を作る</h4>
<p>レポートディスクリプタで指定したルールに従った値を並べます。レポートディスクリプタに記載した順序がそのままバイト内のビット列になるので、下位4ビットが十字キー・上位4ビットがボタン単体となるよう組み立てます。</p>
<h4>データを送信する</h4>
<p>組み立てたデータは、関数ひとつで送信できます。</p>
<p><pre><code>err_code = ble_hids_inp_rep_send(&m_hids,
INPUT_REP_BUTTONS_INDEX,
INPUT_REP_BUTTONS_LEN,
buffer);
</code></pre></p>
<p><ul>
<li>INPUT_REP_BUTTONS_INDEX: マウスのサンプルのように、レポートディスクリプタのなかに複数のIDがある場合はここで指定します。今回の例ではひとつしかないので、0になります。</li>
<li>INPUT_REP_BUTTONS_LEN: 送信するデータのバイト数です。今回は1バイトなので1です。</li>
<li>buffer: データ本体のポインタ。</li>
</ul></p>
<h4>動作例</h4>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ゲームボーイを無線のGamepadとして使えるようになったぞ。自画自賛だけど一番実用的なんじゃないか。 <a href="https://t.co/pRsnPJu6jd">pic.twitter.com/pRsnPJu6jd</a></p>— niccolli (@niccolli) <a href="https://twitter.com/niccolli/status/1259021630409330688?ref_src=twsrc%5Etfw">May 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><h4>データの受信側で確認する方法</h4>
<p><a href="https://html5gamepad.com/">HTML5 Gamepad Tester</a>を使っています。ペアリングし、レポートディスクリプタの指定もうまくいっている場合は、キー操作に反応します。</p>
<p>ペアリングできていてもキー操作に反応しない場合、レポートディスクリプタの記載内容がきちんと合っていない可能性があります。バイト列が送信されているかどうかは、Macを使っていると確認が楽です。Appleの開発ツールとして公開されているPacket Loggerを使うと、どのデバイスからどのデータが飛んでいるかを確認できます。バイト列の中身をPacket Loggerで確認できれば、ペアリングと通信はうまくいっているので、おかしいのはディスクリプタだと推測できます。</p>
niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-91002856094734818242020-02-08T18:58:00.001+09:002020-02-08T18:58:54.927+09:00ポケットカメラの画像をM5Stackに送信して表示する<p><a href="https://log.niccol.li/2020/01/blog-post.html">前回の記事</a>で、ポケットカメラの画像をPCに送信することができました。でもこれではPCとNucleoボードが必要で、若干大掛かりだなと思っていました。これをM5Stackで受信できれば、画面に映せるし無線LANでTwitter等にアップロードも可能だなと思い、移植してみました。</p>
<h4>M5Stackと通信ケーブルを接続する</h4>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLGKj42xONeHV_fyrHSK4XaStq4P_bMgXX8dAAiP_1KYQBHMPFl4H7M5uAGyYgjpJgpmgMHJa6W9b1sbbRRsjDPbyfAJK1nwiG4B7L7fjxnLzWUJpDEaeeWw1EBXEUIskoTzkf0DZg3lg/s1600/IMG_1275.HEIC" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLGKj42xONeHV_fyrHSK4XaStq4P_bMgXX8dAAiP_1KYQBHMPFl4H7M5uAGyYgjpJgpmgMHJa6W9b1sbbRRsjDPbyfAJK1nwiG4B7L7fjxnLzWUJpDEaeeWw1EBXEUIskoTzkf0DZg3lg/s320/IMG_1275.HEIC" width="320" height="240" data-original-width="1600" data-original-height="1200" /></a></p>
<p>ゲームボーイの通信ケーブルの信号線は5V駆動なので、5VトレラントではないM5Stackでは、とりあえず分圧抵抗で降圧します。M5Stack→ゲームボーイの方向は、昇圧せずとも動くことはカートリッジ自作の際にわかっているのでとりあえずそのままにしました。</p>
<p>M5Stackに接続する際、当初は向かって上側(21〜23のピン)に接続していたのですが、23番が内部でディスプレイ制御に使われているのに気付くまでディスプレイが動かないと困りました。GPIOとしても使用できますが、ディスプレイ初期化後にGPIOとして設定してしまうため、それ以降はディスプレイの信号を受け付けなくなります。</p>
<h4>M5Stackでデータを受信し画像として表示する</h4>
<p>データ受信までは、<a href="https://github.com/Dhole/gb-link-stm32f411">DholeさんのSTM32側コード</a>の移植で済みました。移植の際、Arduinoではうまく動かず、ESP-IDFの環境を使っています。データ受信後、ドット情報を抽出しビットマップに整えてから画面に表示するのですが、表示の際はM5.Lcd.drawBitmap()が必要になり、ESP-IDFにArduinoライブラリを追加しました。バージョンが異なるとうまく動かないらしく困りましたが、<a href="https://another.maple4ever.net/archives/2615/">こちらの記事</a>が参考になりました。結局、この方のリポジトリをクローンしてアプリを作っています。</p>
<h4>動作の様子</h4>
<p><blockquote class="twitter-tweet"><p lang="ja" dir="ltr">やったー ポケットカメラの画像をM5Stackで表示できるようになったよ <a href="https://t.co/6ZEP3jcADC">pic.twitter.com/6ZEP3jcADC</a></p>— 技術書典8 Day2 か13 (@niccolli) <a href="https://twitter.com/niccolli/status/1225983387761987584?ref_src=twsrc%5Etfw">February 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-40048001487318663512020-01-13T19:12:00.001+09:002020-01-13T20:05:20.672+09:00ポケットカメラの画像を取り出す<p>かつてゲームボーイのカートリッジからカメラが伸びている<a href="https://ja.wikipedia.org/wiki/ポケットカメラ">ポケットカメラ</a>というソフトがありました。撮影した画像は通信ケーブルを使い、ポケットプリンタからロール紙に印刷するという形で現像していましたが、印刷部を適宜加工することで画像を他環境へ転送することができます。例によって<a href="https://dhole.github.io/post/gameboy_serial_2/">Dholeさんの実装例</a>があったので、まずはそれを後追いして検証しました。</p>
<h4>動作までの流れ</h4>
<p>下記のフローで実装を行いました。</p>
<p><ol>
<li>通信ケーブルを改造する</li>
<li>疑似ポケットプリンタ基板を実装する</li>
<li>基板が出す画像データを受け取るアプリを実装する</li>
</ol></p>
<h4>通信ケーブルを改造する</h4>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglHMBDmooDRUi-dsny-8C-0NkkeZg-HMtR6q00lSl7flYNXJh6CmliP80X2wZj4j7y79L6xM92DWj3An0S8pbQlmgenEok1rXy8_jVQTWpM8jlU_5Y06nXpM0TGg5UrTROmVq0a81hM2I/s1600/IMG_1033.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglHMBDmooDRUi-dsny-8C-0NkkeZg-HMtR6q00lSl7flYNXJh6CmliP80X2wZj4j7y79L6xM92DWj3An0S8pbQlmgenEok1rXy8_jVQTWpM8jlU_5Y06nXpM0TGg5UrTROmVq0a81hM2I/s320/IMG_1033.jpg" width="320" height="240" data-original-width="1600" data-original-height="1200" /></a></p>
<p>通信ケーブルのデータを基板で受信するために、通信ケーブル本体を切断しています。通信ケーブル用のソケットがAliexpress等で購入できればよかったのですが、初代ゲームボーイ用の大きいサイズはさすがに作られていないようで、泣く泣くカットしました。配線はGNDを含めて4本なので、秋月電子の<a href="http://akizukidenshi.com/catalog/g/gP-08895/">USBコネクタDIP化基板</a>を利用して扱いやすくしました。</p>
<h4>疑似ポケットプリンタ基板を実装する</h4>
<p>ポケットプリンタのフリをして、ゲームボーイ側には正しい応答を返し続け、PC側に画像信号を転送する基板を実装します。基本的に<a href="https://github.com/Dhole/gb-link-stm32f411">Dholeさんのリポジトリ</a>のコードを使用しますが、ヘッダファイルだけがなかったりフレームワークの内容に変更があったりするのでその点だけ修正しました。修正後のリポジトリは<a href="https://github.com/niccolli/gb-link-stm32f411">こちら</a>です。例ではNucleo-F411REでしたが、手元にあったのはF401REだったのでクロックを遅くするよう設定しています。</p>
<h4>基板が出す画像データを受け取るアプリを実装する</h4>
<p>こちらも<a href="https://github.com/Dhole/gb-link-host">Dholeさんのサンプル</a>を使用します。基板がシリアル通信でデータを渡すので、それを受信し画像に変換して保存します。</p>
<h4>動かしてみる</h4>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVYmGlRbJtd65af3bEeTrtM_La0sd4KDsAgHQVei-9YVKsXhZUgF4k3LT4mxB-eu2azwPLGf92oMNY27M5rzRT6pS-ZEV-D0S3Cus2hQbeTCqX5-aP_Ucqk_P17Y3zuwuIOEu5wgKqZGE/s1600/IMG_1040.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVYmGlRbJtd65af3bEeTrtM_La0sd4KDsAgHQVei-9YVKsXhZUgF4k3LT4mxB-eu2azwPLGf92oMNY27M5rzRT6pS-ZEV-D0S3Cus2hQbeTCqX5-aP_Ucqk_P17Y3zuwuIOEu5wgKqZGE/s320/IMG_1040.jpg" width="320" height="240" data-original-width="1600" data-original-height="1200" /></a></p>
<p>疑似プリンタ基板が接続されているPCで受信アプリを起動し、ポケットカメラ側で印刷を実行します。各部が正常に接続・動作している場合、ゲームボーイの画面はデータ送信中となり、PCに画像が保存されます。</p>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1bZCZzIdInBdsD1zvxhhKAINAi_fPkxNnr9AIXZVqmiE6yX9Yyn-FYl1p-gsy9KYimIpJBuoN2e_0pkoJiiLPIRG01hsgb3Se0AmU9uNwQoJjf2rqHB99HFEt5nHUsaTOOa2B4kb84GE/s1600/gb_printer_2020-01-13T185435.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1bZCZzIdInBdsD1zvxhhKAINAi_fPkxNnr9AIXZVqmiE6yX9Yyn-FYl1p-gsy9KYimIpJBuoN2e_0pkoJiiLPIRG01hsgb3Se0AmU9uNwQoJjf2rqHB99HFEt5nHUsaTOOa2B4kb84GE/s1600/gb_printer_2020-01-13T185435.png" data-original-width="160" data-original-height="144" /></a></p>
<p>印刷される画像そのものが出てくるので、写真+フレームのPNG画像で保存されます。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-15980655566480636172019-12-08T20:58:00.001+09:002019-12-08T20:58:20.975+09:00STM32のUARTのDMA送信におけるバッドノウハウ<p>STM32F4のDMAを使ったUART送信、下記の仕様なのでちょっと勝手の悪いところがありました。</p>
<p><dl>
<dt>Circular</dt>
<dd>一度Enableにすると、メモリ上のデータを繰り返し送信し続ける。</dd>
<dt>Normal</dt>
<dd>送信後、各種フラグをクリアする必要があり、CPUの命令を消費してしまう。</dd>
</dl></p>
<p>ゲームボーイのカートリッジでRAMの値を外部に送信しようとすると、NormalではCPUを使う時間が増えるため、動作に支障が出ます。かといってCircularでは、同じ値を送信し続けるので受信側に工夫が必要になってしまいます。最低限必要なデータを、最低限のCPU消費で送信したいのです。</p>
<h4>今回のバッドノウハウ</h4>
<p>今回は1バイトだけ送信したいので、Circularモードに設定したうえで次のようにENABLEの直後にDISABLEを続けると、ちょうど1バイトだけ送信したところでDMAが止まり、Circularモードなので何事もなく再開します。</p>
<p><code>DMA_Cmd(DMA1_Stream6, ENABLE);<br />
DMA_Cmd(DMA1_Stream6, DISABLE);</code>
</p>
<p>ただこれはボーレートとの兼ね合いもたまたまちょうど良かっただけかもしれません。複数のバイト列を送信する場合には使えないので、そのときは改めて方法を考える必要があります。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-82054826770430746532019-11-09T16:51:00.000+09:002019-11-09T16:51:00.729+09:00ゲームボーイの上で動くソフトウェアと通信をする<p>ゲームボーイのカートリッジを自分で作って遊んでいます。いままで<a href="https://log.niccol.li/2019/02/lsdj.html">カートリッジ側のROM・RAM・MBCをすべてマイコンに実装したもの</a>を作って遊んでいましたが、カートリッジの外からRAMにデータを書き込む方法が見つからず難儀していました。</p>
<h4>マイコン側CPUの処理を使うとゲームボーイが止まる</h4>
<p>このカートリッジでは、ゲームボーイに対するROMデータの出力をマイコンのCPUがまかなっています。</p>
<p><ol>
<li>ゲームボーイ側がカートリッジにアドレスを渡す。</li>
<li>マイコンがアドレスを受け取る。</li>
<li>Read/Writeのどちらか、バンク設定があるのかを判断して、返すべきデータを決める。</li>
<li>マイコンがデータを出力する。</li>
</ol></p>
<p>1バイトとはいえ、どのデータを返すかが決まるまでにいくつかの条件分岐が入ります。なので、外部通信等で他の処理がCPUを使用すると、このデータを返す処理が間に合わずゲームボーイ側がハングアップします。</p>
<h4>外部通信の受信をDMAに任せたらどうか</h4>
<p>今回、受信したデータをそのままカートリッジRAMの領域に直接書き込む形にしたら問題が解決しました。DMAのサンプルコードをみると、受信したあとそのデータを確かめるためのコールバック関数があったりしますが、その部分が動くとCPUを使ってしまうため、その部分は絶対に使わないようにします。ゲームボーイのソフト側は、DMAの書き込み先に合わせた特定のアドレスだけを読むようにすれば、カートリッジRAMに書き込んだデータをゲームボーイ内で扱うことができます。</p>
<h4>実装例</h4>
<p>ゲームボーイのカートリッジRAMにMIDIデータを書き込み、MIDIノートオンのときにゲームボーイ側で音を鳴らす仕組みです。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">やったー<br>鍵盤からゲームボーイの音を鳴らせるようになったよ <a href="https://t.co/FaVdR5hRL9">pic.twitter.com/FaVdR5hRL9</a></p>— niccolli (@niccolli) <a href="https://twitter.com/niccolli/status/1192812738898284545?ref_src=twsrc%5Etfw">November 8, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>MIDIは、フォトカプラで受信後はbaudrateが31250のUARTとしてそのまま扱えるので、マイコンのDMAで直接RAMに書き込むことができます。書き込まれる予定のアドレスをゲームボーイ側は常時監視し続け、MIDIノートオンのメッセージを受信したら、ノート番号に合わせた音程で音を鳴らすという仕組みになっています。</p>
niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-77440630872966949632019-07-01T20:24:00.000+09:002019-07-01T20:39:00.239+09:00大量のセンサーデータの可視化にKibana+Elasticsearchが最適だった話<p><a href="https://iotlt.connpass.com/event/132887/">第52回のIoTLT</a>で話した内容を、改めて記載します。</p>
<p>センサーの測定値を数分おきに取得していたんですが、2年ほど動かしていると結構な量になりまして、CSVに変換してExcelでグラフにしようとすると描画まで強烈に待たされるようになってました。何かいい方法はないかと困っていたところ、同じく3月のIoTLTで発表のあった<a href="https://speakerdeck.com/wamisnet/ke-shi-hua-ganbatutemiyou">Kibanaを使って可視化をがんばる話</a>を聞き、これは良さそうと思って試しました。</p>
<h4>Kibanaについて</h4>
<p>Kibanaは全文検索エンジンElasticsearchのフロントエンドとして動くWebアプリなので、Kibanaを使うにはElasticsearchも合わせて使います。Elasticsearchにどんどんデータを溜め込み、ブラウザ経由でKibanaに接続してグラフを設定します。</p>
<p>基本機能はオープンソースになっていて無料で使えるのもありがたいです。</p>
<h4>Linuxだと環境構築がすごく楽</h4>
<p>たまたま持て余していたPCにLinux (Ubuntu 18.04) を載せて動かしています。公式に記載の<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/deb.html">aptを使った手順</a>に従うと、光の早さで構築できました。最初はもともと入っていたWindows 10で動かそうとしたのですが、特にKibanaのZipパッケージはNode.jsのモジュールがまるっと入っており(KibanaはNode.jsのWebアプリとして動作する)、解凍で何年も待つくらい遅くてあきらめました。</p>
<h4>数万件のセンサーデータからのグラフ描画が速い</h4>
<p>まずElasticsearchが全文検索エンジンなので、溜め込んだデータの中から特定の条件にマッチするデータの抽出が非常に速いです。さらに、すべての時系列データを描画するのではなく、細かい範囲ごとに最大最小や平均などでデータを間引きしてから描画するので、長期間の動きをサクッと確かめることができます。</p>
<h4>データの追加について</h4>
<p>今手元で生成され続けているデータは、コマンド出力結果そのままのテキストだったりバイナリ生データだったりするので、Elasticsearchに投げ込むには一手間加えてJSONにする必要があります。今この部分はNode.jsを使って変換しています。これはNode.jsが使い慣れているだけで、実際はどの言語を使ってもいいと思います。</p>
<h4>ちょっと困っているところ</h4>
<p>グラフをディスプレイに表示し続けるとテレメトリーのようでかっこいいのですが、無料枠ではこの表示中も編集可能でロックはできません。ライセンス購入になると一気にいい値段になってしまうようで二の足です。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com1tag:blogger.com,1999:blog-2454413944984526463.post-33544048852233941952019-04-15T20:20:00.001+09:002019-04-15T20:20:33.110+09:00技術書典6のふりかえり<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzKNs1Lgyc43y0UmgyIOVnaQn2q7OicUggGKLNYOyNjb3xT-6Wi7VFku-lGswsaaSoR_mo3jItpRTMLsKIVS_vLC4Elr0FU2yXtL3oQHIwuxOeSToj5wnGB7CMFj_0qM4Y_hzOcsMTHX4/s1600/D4HgvhuVUAE2OAK.jpg-large.jpeg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzKNs1Lgyc43y0UmgyIOVnaQn2q7OicUggGKLNYOyNjb3xT-6Wi7VFku-lGswsaaSoR_mo3jItpRTMLsKIVS_vLC4Elr0FU2yXtL3oQHIwuxOeSToj5wnGB7CMFj_0qM4Y_hzOcsMTHX4/s320/D4HgvhuVUAE2OAK.jpg-large.jpeg" width="320" height="240" data-original-width="1600" data-original-height="1200" /></a>
<p>技術書典6で机をいただいたので、展示とPDFの頒布を行ってきました。どちらかと言えば本を売るよりもMaker Faire気分で、作ったものの自慢に出てました。</p>
<h4>被チェック数</h4>
<p>前回の2倍以上の数になっていて驚きました。サークルカットにわかりやすい画像を設定したせいかな、と思っていましたが、いくつかのニュースサイトに掲載されていることに気付きました。</p>
<p><ul>
<li><a href="https://hbol.jp/189718">IT技術書だらけの同人誌即売会が大人気。その理由とは?</a></li>
<li><a href="https://www.asahi.com/articles/ASM2W627PM2WUTNB021.html">技術系同人誌、ファン増加 ニッチな情報をカジュアルに</a></li>
</ul></p>
<p>それぞれあからさまに「自分で作るゲームボーイのカートリッジ」と書いてくれていました。ありがたい限りです。開催中も「お友達から買ってくるように言われた」という方が3人くらいおられまして、興味を持ってもらえるのは嬉しいけど参考になるだろうか?と若干不安です。</p>
<h4>チップチューンのみなさんからの期待</h4>
<p>もともとは「できそうだから」という軽い気持ちで作っていた自作カートリッジなんですが、<a href="https://www.littlesounddj.com/">LSDj</a>を動かすためのカートリッジが年々減っているなかのポッと出てきた新作、かつ日本語で対応できるとのことで湧き上がっているとうかがいました。思わぬ方向からの援軍にモチベーションが高まりますね。</p>
<h4>今後の課題</h4>
<p><ul>
<li>もう少し展示に気を遣う</li>
<li>そろそろ量産できそうかな</li>
<li>M3にも出てみようかな</li>
<li>ゲームボーイカラーの対応</li>
</ul></p>
<p>お持ちいただいたゲームボーイカラーだと、起動ロゴ以降アプリケーションが動作しませんでした。旧ゲームボーイ用カセットということで動いてくれないものか…と期待していたのですが、一筋縄ではいかなさそうです。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-68997947235595406032019-02-24T18:28:00.000+09:002019-02-24T18:30:18.528+09:00ゲームボーイの自作カートリッジでLSDjが動くようになった<p>ゲームボーイのカートリッジを自分で作り、<a href="https://log.niccol.li/2018/10/blog-post.html">技術書典に本を出して</a>から、<a href="https://www.littlesounddj.com/">LSDj</a>が動くといいねという話をよく聞いていました。やっと動くようになったのでつまずいていた点を記載します。</p>
<h4>マイコンの容量を増やす</h4>
<p>今までの基板ではSTM32F407を使っていました。1MBのFlashを持っているのですが、これだと前述の512KBのROMイメージと128KBのRAM領域を確保できなかったので、ROM容量の多いSTM32F427(2MB)/STM32F413(1.5MB)の2種類を試しました。パッケージサイズは同一でピンアサインもほぼ同一です。</p>
<p>STM32F413でもROM/RAMの領域を確保でき、ソフトの起動を確認できました。413は427に比べてQSPIが載っているので、外部Flashを活用するならこちらのほうがいいのかもしれません。でも2MBの427は大して単価もかわらないのに容量がでかいのでもう全部これでいい気がしています。</p>
<h4>MBC5の動きに対応したコードを追加する</h4>
<p><blockquote class="twitter-tweet" data-conversation="none" data-lang="en"><p lang="ja" dir="ltr"><a href="https://t.co/s9bEb12c1Q">https://t.co/s9bEb12c1Q</a> 3000-3FFF - High bit of ROM Bank Number (Write Only)の実装を間違えていたのが原因だった。ここは必ず0か1が入ってくるものだと思ってたけど、実際は0とそれ以外らしい。そういう実装に変えたらちゃんと音が鳴るようになった。</p>— 技術書典6 い05 (@niccolli) <a href="https://twitter.com/niccolli/status/1099451277887467520?ref_src=twsrc%5Etfw">February 23, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</p>
<p>今までも動いてはいたんですが、上記のように実装を間違えていて、音がぶつぶつと途切れるようにしか鳴らないし全くテンポどおりに動かない(超遅い)動作になっていました。リンク先のドキュメントと、<a href="https://github.com/Dhole/stm32f_GBCart/blob/master/stm32f4xx_it.c">もとのコード</a>(コメントアウトになっているところ)を見てて気付きました。</p>
<h4>音が鳴るようになりました</h4>
<p><blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/LSDj?src=hash&ref_src=twsrc%5Etfw">#LSDj</a> で音の長さを設定できるようになった。 <a href="https://t.co/UajdOQMgOw">pic.twitter.com/UajdOQMgOw</a></p>— 技術書典6 い05 (@niccolli) <a href="https://twitter.com/niccolli/status/1099530023629803520?ref_src=twsrc%5Etfw">February 24, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</p>
<h4>お知らせ</h4>
<p><a href="https://techbookfest.org/event/tbf06">技術書典6</a>に出ます。前回出展時の本に加筆修正を加えて、第2版として出します。値上げするけど、今まで買ってくれた人はそのままダウンロードできるようにする予定です。「い06」でデモ機と見本誌を用意して展示します。</p>
<h4>バッテリーバックアップについて</h4>
<p>外部Flashに保存かな〜と考えていたのですが、2MBだと容量の余裕がすごいので内蔵Flashに保存でいいのかもしれません。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-54836831126682130502018-12-25T22:37:00.001+09:002018-12-25T22:37:50.185+09:00enebularはNode-REDの一発デプロイツールとして超便利なのでは<p>先日ウフルの<a href="https://enebular.connpass.com/event/106731/">enebular meetup</a>に参加するので、Node-REDを常時動かすためにherokuにデプロイしてみました。<a href="https://docs.enebular.com/ja/deploy/deployflow/heroku/">公開されている手順</a>でherokuにNode-REDの環境がサクサクと立ち上がりました。このときに「enebular=IoTをよしなにするツールだと思っていたけど、Node-REDを即デプロイできるツールとしても便利なのでは?」と思いました。</p>
<h4>Webhookを受け取る環境をサクッと立ち上げられる</h4>
<p>過去にWebhookを受け取りたい場面があり、その都度サーバーの設定をするのは面倒だなと思っていました。その当時は<a href="https://ngrok.com">ngrok</a>を使いましたが、enebularでWebhookを受け取るフローをつくりそれをherokuにデプロイしておけば、ngrokのようにローカルでプロセスを動かしている必要はないなと。ちょっと試してみました。</p>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdLza0WvKvdtsMjPM63sqmFLZoZkF5sWuSIWTsK8dDYeBs5ahZ7UOPox7LbHXOcP1K2lIdqLmoHxfOKFd4xg2YJs6KG1NIu5XafAxjpiNDUux0eSkmpfme8f76B5tkFIXgEGAy1lLMjls/s1600/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2018-12-25+22.27.26.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdLza0WvKvdtsMjPM63sqmFLZoZkF5sWuSIWTsK8dDYeBs5ahZ7UOPox7LbHXOcP1K2lIdqLmoHxfOKFd4xg2YJs6KG1NIu5XafAxjpiNDUux0eSkmpfme8f76B5tkFIXgEGAy1lLMjls/s320/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2018-12-25+22.27.26.png" width="320" height="211" data-original-width="1600" data-original-height="1057" /></a></p>
<p>入力にHTTP Inputを置き、まずはそのままHTTPの出力につなぎます。<a href="https://qiita.com/joeartsea/items/3bf1fa22e088640c7624">こちら</a>の3項にあった「HTTPの入力は本当に入力しかしないので、HTTPの出力につながないとWebhookの発行側がエラーになる」という内容を参考にしています。入力のHTTPを分岐し、とりあえずデバッグで中身を全部出力するようにします。</p>
<p>Webhook発行側に登録するURLは、herokuデプロイ前なら「デプロイボタンの左にある(i)のボタンで表示されるドメイン+HTTP Inputに設定したパス」が使えます。これで動作確認ができれば、そのまま先ほどの手順に従ってHerokuにデプロイしてWebhookを常時待機できるようになります。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-4048435861793214152018-12-16T16:59:00.005+09:002018-12-16T16:59:55.675+09:00なぜnanoloopのカートリッジは基板だけで差し込めるのか<p>ゲームボーイ用カートリッジの<a href="http://nanoloop.com">nanoloop</a>は、カートリッジ本体が基板のみで、いわゆるカートリッジらしい樹脂筐体を含みません。<a href="http://nanoloop.com/mono/index.html">nanoloop mono</a>はさらに、カートリッジの端子幅だけしか本体サイズがありません。なぜこれで差し込みに問題ないのか、差し込み時の位置合わせは正確に行えるのかが疑問でした。この理由がわかれば、今自分で作っている基板も他のカートリッジから筐体を借りなくて済むので、調べてみました。</p>
<h4>厚みについて</h4>
<p>カートリッジと本体側ソケットそれぞれの端子が接していれば動作します。一般的なカートリッジの端子部の厚みを基板に合わせれば動作すると考えました。</p>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj98Ay1SgO_87ESiFL6rJOkFi1nffLsQxWMTJ7Lydu37Yr7wSWapVEjH3LQmsPhfKOTLUkHxVccy6KHDmifVKBFaUeKDfAsbr1YtACW8abUSg4IvFa2z2qaRBDYDzTiM-uErKHNn3o_tR4/s1600/%25E5%2590%258D%25E7%25A7%25B0%25E6%259C%25AA%25E8%25A8%25AD%25E5%25AE%259A4.heic" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj98Ay1SgO_87ESiFL6rJOkFi1nffLsQxWMTJ7Lydu37Yr7wSWapVEjH3LQmsPhfKOTLUkHxVccy6KHDmifVKBFaUeKDfAsbr1YtACW8abUSg4IvFa2z2qaRBDYDzTiM-uErKHNn3o_tR4/s320/%25E5%2590%258D%25E7%25A7%25B0%25E6%259C%25AA%25E8%25A8%25AD%25E5%25AE%259A4.heic" width="320" height="242" data-original-width="1600" data-original-height="1212" /></a></p>
<p>2.1mmなので、厚みがおおよそ2.0mmあればおそらく大丈夫だろうと思います。</p>
<h4>差し込みについて</h4>
<p>厚みがわかったので、差し込み時の位置合わせやガイドについて調べました。カートリッジのふたを開けた状態で差す様子をみると、この状態では筐体(矢印で示している箇所)が位置を合わせているように見えます。</p>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvjq7aZN77s-rUhAk2SQ8s7d4ILTqeX1oHg_BRuHZOf8Bw71uGTBCqmC7enG3L96CZxlepvZLaZhLZH1USqlcNXJCUd9N5l-EtAxIgJl4voXao-KixeayZj12urL4Hlx3x46ikq78L07Q/s1600/IMG_8062.HEIC" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvjq7aZN77s-rUhAk2SQ8s7d4ILTqeX1oHg_BRuHZOf8Bw71uGTBCqmC7enG3L96CZxlepvZLaZhLZH1USqlcNXJCUd9N5l-EtAxIgJl4voXao-KixeayZj12urL4Hlx3x46ikq78L07Q/s320/IMG_8062.HEIC" width="320" height="240" data-original-width="1600" data-original-height="1200" /></a></p>
<p>ここで、厚みをおおよそ2.0mmに調整したカートリッジ基板を差し込んでみます。</p>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiouf-hYN9I41efP7s9k96Ib_SxDuzOSyvhgePl1rs5ns2FfsIbwA3M9t00ibymTlD0TW6-yL92fKgYSIW_6SFdeJGsFW06C1bUglVw1kcpKGLFlzdfuqs0bnLQhfwRojVyvpCX7sts4JE/s1600/IMG_7981.HEIC" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiouf-hYN9I41efP7s9k96Ib_SxDuzOSyvhgePl1rs5ns2FfsIbwA3M9t00ibymTlD0TW6-yL92fKgYSIW_6SFdeJGsFW06C1bUglVw1kcpKGLFlzdfuqs0bnLQhfwRojVyvpCX7sts4JE/s320/IMG_7981.HEIC" width="320" height="320" data-original-width="1600" data-original-height="1600" /></a></p>
<p>正しい位置に収まり、カートリッジも正常に動作しました。このときにわかったのですが、位置合わせのガイドとなっているのはカートリッジ筐体ではなく、本体ソケットの突起でした。次の写真は差し込み口を上から見た図です。</p>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7yfvvKNjiIjUw34IegYH4GXiRGFMKe6VSWpxyLCBTyXSONz4XVQhHvz78yRyTHZj39n7fIzq6AgCEukJyFU-efeDKcNm5uUPK4VsWHVVjK388UGOLjsfaJ2cKeUBRk0Vw8iAaOJpSvrc/s1600/IMG_8063.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7yfvvKNjiIjUw34IegYH4GXiRGFMKe6VSWpxyLCBTyXSONz4XVQhHvz78yRyTHZj39n7fIzq6AgCEukJyFU-efeDKcNm5uUPK4VsWHVVjK388UGOLjsfaJ2cKeUBRk0Vw8iAaOJpSvrc/s320/IMG_8063.jpg" width="320" height="240" data-original-width="1600" data-original-height="1200" /></a></p>
<p>正しい厚み・正しい幅の板が上から降りてくるとき、ソケットのガイドに従って差し込まれるので、端子同士がまっすぐ接触するようになっています。</p>
<h4>結論</h4>
<p>基板厚み2.0mmでカートリッジ基板を製造すれば、筐体なしでもカートリッジは機能する。</p>
<p>機能検証(とカートリッジをもとのゲームに戻す)のために、上で差した基板の厚みを2.0mmにしたものを製造中です。届き次第試します。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com1tag:blogger.com,1999:blog-2454413944984526463.post-24530433353452974902018-12-14T05:55:00.001+09:002018-12-14T05:55:20.464+09:00AE-TYBLE16にBLE-MIDIを実装するための途中経過<p>秋月電子通商のBLEモジュール <a href="http://akizukidenshi.com/catalog/g/gK-12339/">AE-TYBLE16</a> は、<a href="https://log.niccol.li/2018/11/blehid.html">SWDの書き込み端子が出ているのでファームウェアを書き換えられます</a>。NordicのnRF5 SDKのサンプルコードをいろいろ使うだけでも十分できるのですが、興味のあった MIDI over BLE はサンプルがなかったので実装に挑戦しました。<a href="https://qiita.com/advent-calendar/2018/iotlt">アドベントカレンダー</a>に投稿するのに間に合わなかったので、今回は途中経過を記載します。</p>
<h4>Nordic nRF5 SDKでサービスの実装が大変</h4>
<p><a href="https://www.midi.org/specifications-old/item/bluetooth-le-midi">仕様</a>をみると、次のように実装することとあります。</p>
<p>The following service and characteristic are defined:
<ul>
<li>MIDI Service (UUID: 03B80E5A-EDE8-4B33-A751-6CE34EC4C700)</li>
<li>MIDI Data I/O Characteristic (UUID: 7772E5DB-3868-4112-A1A9-F2669D106BF3)
<ul><li>write (encryption recommended, write without response is required)</li>
<li>read (encryption recommended, respond with no payload)</li>
<li>notify (encryption recommended)</li></ul>
</li></ul>
</p>
<p>「このUUIDのサービスとキャラクタリスティックを実装すればいいんだろ」と思っていましたが、この時点でまず大変でした。</p>
<p>今回のようにサービスとキャラクタリスティックでUUIDが異なっていると、「フルサイズのUUIDをいくつも使うぞ」という設定が必要でした。フォーラムのやり方で<a href="https://devzone.nordicsemi.com/f/nordic-q-a/28258/how-do-i-add-2nd-base-uuid-for-service-and-characteristic">それっぽい</a>のを見つけて実装しデバッグすると、ログにメッセージが出ます。「ユーザーが使うメモリの割当を次のように変えろ」というメッセージが出るので、それに従ってリンカスクリプトを修正します。これでやっと電波が飛ぶようになります。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">シャオラー! <a href="https://t.co/RzooFVXzCC">pic.twitter.com/RzooFVXzCC</a></p>— Yusuke ******** (@niccolli) <a href="https://twitter.com/niccolli/status/1064111579824762880?ref_src=twsrc%5Etfw">November 18, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<h4>仕様の「encryption recommended」にひっかかる</h4>
<p>電波が飛ぶようになったのですが、MacはMIDIポートとして設定してくれません。おそらく仕様の「encryption recommended」が欠けているのが原因のようで、Mac側としてはマウスやキーボードのようにペアリング動作を完了できないとMIDIポートとして設定されないようです。もともとベースにしていたサンプルコードがペアリング処理のないものだったので、ペアリング処理のあるサンプルに移植するのもめんどうだなとなって放置気味になってきたところで今日に至っています。</p>
<h4>まとめ</h4>
<p>すごく手間なので、Arduino環境でつくるほうに乗り換えようかちょっと考えています。でもペアリングの動きとか後ろ側の動きについてかなり勉強になった感じはするので、なしではないです。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-58500215763655770582018-11-12T20:12:00.002+09:002018-11-12T22:23:10.726+09:00秋月のBLEモジュールでHIDを扱えるようにする<p>秋月に太陽誘電のBLEモジュール AE-TYBLE16 が<a href="http://akizukidenshi.com/catalog/g/gK-12339/">販売されています</a>。このモジュールは端子が底面からのみ出ているので、基板実装をしないと扱いづらいのですが、秋月がその基板実装を行った状態で販売しているので非常に扱いやすくなっています。</p>
<p>このモジュールは中のnRF51822に対してあらかじめファームウェアが書き込まれており、電源が入ると独自のサービスを飛ばします。UARTで適切なコマンドを入力すると、その中のキャラクタリスティックにデータが送りこまれると聞いています。</p>
<p>この秋月モジュールは電源・GPIOに加えてSWDIO・SWDCLKが出ているので、JLink等のライターを使用すると自分で作ったファームウェアに置き換えられます。</p>
<h3 id="ファームウェアの書き込み">ファームウェアの書き込み</h3>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6FFzIkWMx10Vf0KCQTDOdddZgO0QIBwLXm4G5mDpN3HM9BOPti7y9HgUxyqOs_daN4aznDbALgI9d36a7fOP3Rs_yTCUnECXF8jBLD5PpO2dKYwYVLkfoSMvzCPHuqBmSUY918G9csO8/s1600/IMG_7793.HEIC" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6FFzIkWMx10Vf0KCQTDOdddZgO0QIBwLXm4G5mDpN3HM9BOPti7y9HgUxyqOs_daN4aznDbALgI9d36a7fOP3Rs_yTCUnECXF8jBLD5PpO2dKYwYVLkfoSMvzCPHuqBmSUY918G9csO8/s320/IMG_7793.HEIC" width="320" height="240" data-original-width="1600" data-original-height="1200" /></a></p>
<p>Before</p>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSLNGZiqnopUdU95VOv8PG8eARKiCCbV7o8oygHGD_63gXGRauLiUNbelX1oDq_p2uUNgzA4iya72wE2VRzYXS21LkqiyBTYGi_ZiWnCaX0kzlSWb6muJMuMKGD2bVgmjcyCh4lHgiumM/s1600/%25E5%2590%258D%25E7%25A7%25B0%25E6%259C%25AA%25E8%25A8%25AD%25E5%25AE%259A.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSLNGZiqnopUdU95VOv8PG8eARKiCCbV7o8oygHGD_63gXGRauLiUNbelX1oDq_p2uUNgzA4iya72wE2VRzYXS21LkqiyBTYGi_ZiWnCaX0kzlSWb6muJMuMKGD2bVgmjcyCh4lHgiumM/s320/%25E5%2590%258D%25E7%25A7%25B0%25E6%259C%25AA%25E8%25A8%25AD%25E5%25AE%259A.jpg" width="320" height="233" data-original-width="1600" data-original-height="1166" /></a></p>
<p>After</p>
<p>J-LINKから書き込むにあたって、最低限次の配線接続があれば動作します。</p>
<p><ul>
<li>SWDIO</li>
<li>SWDCLK</li>
<li>リセット</li>
<li>Vref</li>
<li>GND</li>
</ul></p>
<p>20ピンJ-LINKだと、これに加えて5V供給とUSB-UART変換が使えるのでそれもつないでいます。5V供給をLDOで3.3Vに落とすとモジュール電源とVrefに使えるので、外部電源を容易せずともデバッグができるようになります。当初はブレッドボードにワイヤーを刺していましたが、持ち運びがめんどうなのでユニバーサル基板に実装しました。配線がつながった状態でnrfjprogをつかうと書き込みができるようになります。</p>
<h3>nRF5 SDKのサンプルコードを動かす</h3>
<p>今回は<a href="https://log.niccol.li/2018/09/blog-post.html">ゲームボーイのカセットに組み込みたい</a>ので、nRF5 SDK 12.3.0のうちHID over GATTのマウスサンプルを使いました。</p>
<p>ble_app_hids_mouse/pca10028/s130/armgcc でmakeを実行するとビルドはできますが、サンプルの前提となっている環境と AE-TYBLE16 で異なる箇所があるのでそのままでは動きません。下記を修正しました。</p>
<h4>sdk_config.h</h4>
<p><ul>
<li><pre>CLOCK_CONFIG_XTAL_FREQ 255→0</pre></li>
<li><pre>CLOCK_CONFIG_LF_SRC 1→0</pre></li>
</ul></p>
<h4>components/boards/pca10028.h</h4>
<p>#define NRF_CLOCK_LFCLKSRCの中身を直す</p>
<p>RTCはモジュールに載っていないので、nRF51822内蔵を使うようにします。</p>
<p><ul>
<li><pre>.source = NRF_CLOCK_LF_SRC_XTAL→NRF_CLOCK_LF_SRC_RC</pre></li>
<li><pre>.xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM→NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM</pre></li>
</ul></p>
<h4>components/toolchain/system_nrf51.cとsystem_nrf51422.c</h4>
<p>16MHzを32MHzに変更します。</p>
<pre>#define __SYSTEM_CLOCK (16000000UL)→(32000000UL)</pre>
<p>ここまで直してNRF_LOGの中身がJLinkRTTのなかに表示されるようになります。APP_ERROR:ERROR:Fatalとだけ表示されるので、マイコンは動いていますがアプリは止まっています。</p>
<h4>main.c</h4>
<p>ble_stack_initのクロック設定を直します</p>
<p>nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;の行は削除。かわりに<pre> nrf_clock_lf_cfg_t clock_lf_cfg;
clock_lf_cfg.rc_ctiv = 16;
clock_lf_cfg.rc_temp_ctiv = 2;
clock_lf_cfg.source = NRF_CLOCK_LF_SRC_RC;
clock_lf_cfg.xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM;
</pre>を追加。</p>
<p>ここを直すとJLinkRTTにAPP:INFO:HID Mouse Start!というメッセージが表示されて、BLEの電波も飛ぶようになります。</p>
<h4>直したけど関係なさそうな箇所</h4>
<p>接続はするがペアリングはされない、という状況が起きていて、<a href="https://devzone.nordicsemi.com/f/nordic-q-a/34943/deleting-device-bonds-pm_evt_conn_sec_config_req---apple-hosts">こういう投稿</a>があったので試してみたら動いたんですが、このブログを書くにあたって再度いちばん最初の段階からやり直してみたら、この変更なしでもペアリングが済んでいて頭を抱えています。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-6385105403144753872018-10-13T18:02:00.002+09:002018-10-13T18:02:54.194+09:00ESP32をBluetoothマウスにする<p><a href="https://log.niccol.li/2018/09/blog-post.html">ゲームボーイを無線マウスにした</a>際に、Bluetooth側はESP32を使って実装しました。キーボードのサンプルコードに記載の関数群でマウスまでまかなえたので、使い方を記載しておきます。</p>
<h3 id="esp-idfを使う">ESP-IDFを使う</h3>
<p><a href="https://github.com/espressif/esp-idf">ESP-IDF</a>のBluetooth Low Energyサンプルのうち、HID over GATTを使います。</p>
<p><a href="https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/ble_hid_device_demo">ESP-IDF BLE HID device demo</a></p>
<p>ble_hidd_demo_main.cではほとんどConsumer Keyの送信しかしていないのですが、esp_hidd_prf_api.hにはきちんと関数が実装されています。</p>
<ul>
<li>void esp_hidd_send_consumer_value(uint16_t conn_id, uint8_t key_cmd, bool key_pressed);</li>
<li>void esp_hidd_send_keyboard_value(uint16_t conn_id, key_mask_t special_key_mask, uint8_t *keyboard_cmd, uint8_t num_key);</li>
<li>void esp_hidd_send_mouse_value(uint16_t conn_id, uint8_t mouse_button, int8_t mickeys_x, int8_t mickeys_y);</li>
</ul>
<p>いずれも、キー操作情報等の最低限のデータを入れればよしなに成形して無線で飛ばしてくれます。</p>
<p>マウス利用時のmouse_buttonは、<a href="http://wiki.onakasuita.org/pukiwiki/?%E3%83%AC%E3%83%9D%E3%83%BC%E3%83%88%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%BF" title="レポートディスクリプタ (410d)">レポートディスクリプタ</a>の0バイト目にああたります。下位3ビットに3ボタンマウスのそれぞれが割り当てられています。下から右・左・中ボタンになります。</p>
niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-18233572820378345092018-10-09T16:37:00.002+09:002018-10-09T16:39:57.196+09:00技術書典ふりかえり<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/%E6%8A%80%E8%A1%93%E6%9B%B8%E5%85%B8?src=hash&ref_src=twsrc%5Etfw">#技術書典</a> 机を整えたが半分Maker Faireになっている <a href="https://t.co/XrLaPDTILT">pic.twitter.com/XrLaPDTILT</a></p>— Yusuke ******** (@niccolli) <a href="https://twitter.com/niccolli/status/1049112261627760640?ref_src=twsrc%5Etfw">October 8, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>技術書典に本を出す側で参加したのでその記録です。</p>
<h3 id="出した内容">出した内容</h3>
<ul>
<li>ゲームボーイのカートリッジ基板の作り方をまとめたPDF</li>
<li>実際に作ったカセットのデモ</li>
</ul>
<p>本はPDF版のみにし、購入もすべてBoothで行ってもらう方法にしました。なので、現場での授受はそのBoothのURLとQRコードを印刷したカードのみです。ひとりチームなので金銭のやりとりとか決裁のトラブルとか抱えたくないのと、今後更新を行うときに購入してくれた人に損がないようにと考えてPDF版のみかつBoothのプラットフォームで更新通知を容易にしたいなと思ってこういう形にしました。もともと自分が調べたことを忘れないように書いた本の内容に、今後調べたり試したりして新しいことがわかったらとか改良の余地がありまくるので、そういうのが増えたら追記・更新したいんですよね。</p>
<p>カードの裏面は著者(というかおれ)の名刺代わりにしたので、余ってもあとで名刺として配ってアピールできるなと。</p>
<h3 id="当日の様子">当日の様子</h3>
<p>机の上は見本として印刷したPDFの中身と、実際に動作するゲームボーイのデモを置いておきました。他の振り返りの記事にあった「見本誌は2冊あったほうがいい」という内容を、本とデモ機でうっかり満たした感じがしました。</p>
<p>個人的には本を買ってもらうよりも「俺が作ったものが超おもしろいからおまえらも見ろ」という感じでデモ推しの気持ちだったので、Bluetoothマウスにしたゲームボーイを触ってもらって、おもしろかったらカードを持ち帰ってもらう、みたいな流れに落ち着きました。特定の年齢層だけは、説明する前から操作方法がバッチリはまる様子に最高に笑いました。</p>
<h3 id="その他電気の気付き">その他電気の気付き</h3>
<ul>
<li>マウスのデモに使ったMacBook Proは終了の17時ちょうどに電池が切れたのでギリギリもった</li>
<li>Bluetoothに使ったESP32がおもいのほか大健闘
<ul>
<li>モバイルバッテリーから電源を取ったが、容量ゲージが減る気配がない。</li>
<li>会場の電波が落ち着いていて混信がなく、常時問題なく動作。</li>
</ul>
</li>
</ul>
<p>ESP32はデータシート上だと電流がそんなに消費しないと書いてあって本当かよって思っていましたが、Bluetoothだけだと本当にそんなに消費しないっぽいです。今度測ってみます。</p>
<p><a href="https://niccolli.booth.pm/items/1026724">https://niccolli.booth.pm/items/1026724</a></p>
<p>もし当日の本に興味があれば、上記リンク先から購入ください。デモがないとおもしろいところがわかりにくいと思いますが、何らか参考になれば幸いです。カードを持ち帰りいただいた方から、結構な数の購入をいただいた通知が来まして、ありがたい限りです。</p>
niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-47226120261736482712018-09-29T22:32:00.002+09:002018-09-29T22:32:37.956+09:00ゲームボーイを無線マウスにする<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">やったー ゲームボーイが無線マウスになったよ <a href="https://t.co/pHgN4dKXtr">pic.twitter.com/pHgN4dKXtr</a></p>— Yusuke ******** (@niccolli) <a href="https://twitter.com/niccolli/status/1043386427730325504?ref_src=twsrc%5Etfw">September 22, 2018</a></blockquote>
<p>ひとつ前の投稿でゲームボーイのカセットを作って遊んでいましたが、カセット側のRAMに値を保存すれば周辺部品と通信できるという仕組みは正式な製品でもたくさんつかわれている手法らしい。なので実装に挑戦しました。</p>
<p>とりあえずやりやすそうだった無線マウスをやってみたところ、期待どおり動いて安心。カセット側RAMはマイコンの中にいるので、保存された値はマイコンからいじり放題です。そのカセット側RAMにキー操作情報を入れて、マイコンからESP32に飛ばしています。</p>
<p>というような話をPDFにまとめて、<a href="https://techbookfest.org/event/tbf05/circle/49250003">技術書典5</a>で紹介します。なんらか操作できるものを置いておく予定なので、試して笑う程度でも歓迎です。</p>
niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-1855039775396459632018-06-23T13:35:00.002+09:002018-06-23T13:39:45.086+09:00ゲームボーイのカセットをつくった<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">やったぜ <a href="https://t.co/OxO9vWi2e9">pic.twitter.com/OxO9vWi2e9</a></p>— Yusuke ******** (@niccolli) <a href="https://twitter.com/niccolli/status/1009025885746286592?ref_src=twsrc%5Etfw">June 19, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>よくよく考えてみたら、ゲームのカセットは中身が基板なので、このご時世ならつくるのはたやすいのではないかと思ってやってみたら、遠回りをしつつもうまく動いた。</p>
<h3 id="なぜゲームボーイにしたのか">なぜゲームボーイにしたのか</h3>
<h4 id="手元にあったから">手元にあったから</h4>
<p>実家に置きっぱなしだったのを回収してきて以来、<a href="https://log.niccol.li/2014/01/usb.html">電源の確保が容易</a>なのでずっと遊んでいる。最近はSwitchを買ってしまいスプラトゥーンとプリパラが楽しいのでほったらかしになってきた。</p>
<h4 id="どうかしてる機能を積んだカセットが多かったから">どうかしてる機能を積んだカセットが多かったから</h4>
<p>ファミコンやスーパーファミコンは、拡張機能は本体のポートに専用コントローラーやサテラビューみたいなのをつないで実現していたけれど、ゲームボーイはその辺をカセットの延長でつくっていた印象があって。ポケットカメラやカービィの傾きセンサーなんかがその例(個人の感想です)。今やるならBluetoothとか各種無線通信を載せていきたい。</p>
<h3 id="作り方">作り方</h3>
<p>海外は作っている人が少なからずいるので、そのへんの人の作例を参考に。</p>
<p><a href="http://www.happydaze.se/wolf/">http://www.happydaze.se/wolf/</a><br>
<a href="https://github.com/dwaq/Homebrew-Gameboy-Cartridge">https://github.com/dwaq/Homebrew-Gameboy-Cartridge</a></p>
<p>カセット側の動作は基本的に</p>
<ul>
<li>16ビットのアドレスを受けて対応する8ビットの値を
<ul>
<li>返す (ROM/RAM)</li>
<li>保存する (RAM)</li>
</ul>
</li>
<li>バンクを切り替える</li>
</ul>
<p>なので、このあたりの配線がつながっていればOK。速度が速度なので、等長配線を気にする必要もない。</p>
<p><a href="https://dhole.github.io/post/gameboy_cartridge_emu_1/">https://dhole.github.io/post/gameboy_cartridge_emu_1/</a></p>
<p>dholeさんがSTM32F4Discoveryをつかって、バンク切り替えの任天堂ASICの擬態を行いつつROM/RAMまでSTM32マイコンでまかなう方法を書いてくれているので、この通りに信号線をつなぐとこうなります。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">やっとできた。疲れた。 <a href="https://t.co/RcP5kg0Jl8">pic.twitter.com/RcP5kg0Jl8</a></p>— Yusuke ******** (@niccolli) <a href="https://twitter.com/niccolli/status/997796564792852480?ref_src=twsrc%5Etfw">May 19, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">届きました!(穴位置をまた間違えた) <a href="https://t.co/ef97kh7Cfx">pic.twitter.com/ef97kh7Cfx</a></p>— Yusuke ******** (@niccolli) <a href="https://twitter.com/niccolli/status/1007205497181593600?ref_src=twsrc%5Etfw">June 14, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">とりあえず予備含めて3枚つくった <a href="https://t.co/OORULXNqYZ">pic.twitter.com/OORULXNqYZ</a></p>— Yusuke ******** (@niccolli) <a href="https://twitter.com/niccolli/status/1008254324114223104?ref_src=twsrc%5Etfw">June 17, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<h3 id="直したい点">直したい点</h3>
<h4 id="穴位置を間違えた">穴位置を間違えた</h4>
<p><a href="https://github.com/dwaq/Homebrew-Gameboy-Cartridge">基板の端子情報をライブラリにしてる人がいる</a>のでそのデータを使おうとするも、Eagleが慣れないのでCircuitMakerに持ってくる際に、大きいほうの穴位置がずれたらしく、カートリッジの筐体にすんなりはまらない。次つくることがあったら直す。</p>
<h4 id="電源の使い勝手">電源の使い勝手</h4>
<p>ふつうカセットは外から何かするわけじゃないので、ゲーム機から電源をもらって動くのは当たり前の動作だけど、ゲーム機の電源とカセットの電源を別にしておかないと、マイコン側のデバッグで困る。ゲームボーイ本体の電源が入っていないと動作をデバッグできない。ジャンパ等で切り替えられるようにしたい。</p>
niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-60389474748124923392017-12-09T22:12:00.000+09:002017-12-09T22:12:13.915+09:00100円SIMのいいところと面倒なところ<p>2017年7月、NTTコミュニケーションズが<a href="http://www.ntt.com/about-us/press-releases/news/article/2017/0703.html">100円SIMのサービスを発表しました</a>。価格から惹かれるところがあり内容を伺ったところ、周囲の人からも「あれどう?」ときかれたことがあったのでメモを残しておきます。</p>
<h3>Arcstar Universal Oneのオプションのような位置づけ</h3>
<p>NTTコミュニケーションズのVPNサービスArcstar Universal Oneの契約が必須(VPNに接続する回線の設置工事等も必要)であり、100円SIM単独での利用はできません。さくらやSORACOMのようにSIMを購入して使うのではなく、VPNサービスへの入り口としてSIMが100円で提供されるというものです。</p>
<p>Arcstar Universal Oneは仮想とはいえ閉じているので、デバイスからのセンシティブなデータでも比較的安全に送信ができます。保存するデータベースは、NTTコミュニケーションズが提供するVPN内のサーバを使うパターンと、VPNからAWSやMicrosoft Azureなどの各種クラウドサービスに接続するパターンが用意されています。</p>
<h3>大規模な業務用途向け</h3>
<p>最低発注数量は100枚という記載もどこかにあったので、外部に絶対に流出させたくないセンサーデータを安全かつ大規模に収集するような用途等、業務用として使うものということでした。また、記載のような業務用なので、NTTコミュニケーションズの営業さんへの見積もりが必須です。個人もしくは小規模での3G/LTE回線がほしいという話ならば、sakura.ioやSORACOMの利用を検討したほうがよいと思います。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com1tag:blogger.com,1999:blog-2454413944984526463.post-66170779829119165522017-02-13T10:08:00.000+09:002017-02-13T10:08:12.097+09:00Web Bluetooth APIをつかうにあたって気になったこと<p>Chrome最新版でWeb Bluetooth APIが使えるようになり、<a href="http://qiita.com/niccolli/items/0cda7990201b13bfd95f">実際に動かしてみました</a>。コードを書いたり関連したドキュメントを読むにあたって、気になった箇所をまとめておきます。</p>
<h4>なぜWeb Bluetooth APIを作ったのか</h4>
<p><blockquote>Until now, the ability to interact with bluetooth devices has been possible only for native apps. The Web Bluetooth API aims to change this and brings it to web browsers as well.<br /><a href="https://developers.google.com/web/updates/2015/07/interact-with-ble-devices-on-the-web">Interact with Bluetooth devices on the Web By François Beaufort</a></blockquote></p>
<p>BLEに限らず、端末の各種ハードウェアを動かすにはネイティブアプリからでないと無理だった。Webアプリでもネイティブアプリがやっていることを実現できるようにしようとするのがこのAPIの目的です。WebGLやWeb Audioの流れと、これから<a href="https://wicg.github.io/webusb/">USB</a>や<a href="http://whatwg.github.io/serial/">シリアル通信</a>を実装しようとしている未来を考えれば、まあ実装するよねという感じがします。ブラウザがOSになろうとしていた時期の計画と野望を、着々と進めているんだなという印象です。</p>
<h4>なぜ動作に制限が多いのか</h4>
<p>コードを動作させるにあたって、(いま私が認識しているだけで)下記の制限があります。</p>
<p><ul>
<li>HTTPでは動作しない(localhostを除く)。HTTPSやfile://では動作する。</li>
<li>クリック等のユーザーからのアクションがないと開始できない。onloadなどで自動的に開始するのは不可。</li>
<li>一部接続しないサービスが定義されている</li></ul></p>
<h5>HTTPでは動作しない</h5>
<p>localhostを除き、HTTP接続ではnavigator.bluetooth.requestDevice()を実行してもerrorとなります。HTTPでも許可されるのはlocalhostのみで、プライベートIPアドレスでもHTTPならerrorです。</p>
<p>これは、Web Bluetoothに限った話ではありません。ブラウザの強力な機能を使う際には、少なくともそのサーバの出処がはっきりしているものだけに制限しておきましょうというもので、<a href="https://www.chromium.org/Home/chromium-security/prefer-secure-origins-for-powerful-new-features">"Secure Origins"</a>と呼ばれています。</p>
<h5>ユーザーからのアクションがないと開始できない</h5>
<p>確実にユーザーの意思によって動作させる必要があります。ページ読み込みと同時にバックグラウンドで勝手に動かすのは不可です。たとえば、もしユーザーがBLEで座標を飛ばせるGPS受信機(こういうものはLocation and Navigation Serviceを使って飛ばしていると考えられます)を使っていたら、バックグラウンドでユーザーがどこにいるのかが結構な精度で取得されることも考えられます。</p>
<h5>一部接続しないサービスが定義されている</h5>
<p>キーボードやDFU等の特に扱いが敏感なサービスについては、そもそもAPIからブロックされています。ブロックリストは<a href="https://github.com/WebBluetoothCG/registries/blob/master/gatt_blocklist.txt">こちら</a>。ちょっとした理由も含めて記載されています。</p>
<h4>どのような場面で使うのがよいのか</h4>
<p>スマホアプリの代用とした使い方がいいのかなと思います。ちょっとした機能としてのみ使うときに、わざわざ専用アプリをストアからインストールしてもらう必要がなくなります。特定の施設内に対応したビーコンを使うためとか、Amazon Dash Buttonのようなデバイスの接続設定を書き込むためとか、そのくらいの用途のためにわざわざアプリをインストールするとなると、面倒くさいからいいわとなるのを防げそうとは考えられます。</p>
<p>一方で、この「専用アプリをストアからインストールしない」が、そのまま脆弱性につながるように思います。どのサービス・キャラクタリスティックに接続しているかは、Webページが何もしなければ特に明示されません。ユーザーにきちんと明示しておくようと<a href="https://webbluetoothcg.github.io/web-bluetooth/#device-access-is-powerful">記載されています</a>。</p>
<h4>参考文献</h4>
<p><ul>
<li><a href="https://webbluetoothcg.github.io/web-bluetooth/">Web Bluetooth Draft Community Group Report, 10 February 2017</a></li>
<li><a href="https://developers.google.com/web/updates/2015/07/interact-with-ble-devices-on-the-web">Interact with Bluetooth devices on the Web</a></li>
</ul></p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-54321067702033792362017-01-20T23:55:00.000+09:002017-01-20T23:55:09.371+09:00Intel Edisonのカーネルを自前でビルドして入れ替える方法<p><a href="http://hobby.farit.ru/linux-framebuffer-fbtft-with-dma-for-intel-edison/">IntelのEdisonでfbtftを実行する方法</a>が公開されていたので試してみようとしたら、カーネルビルドにすごい手間取ったので詰まった箇所をまとめておきます。</p>
<h4>Intel配布の最新版は初回ビルドが通らない</h4>
<p>これを書いているときの最新版はiot-devkit-yp-poky-edison-20160606.zipですが、bitbake edison-imageのコマンドでビルドを始めても、OpenJDKまで来るとビルドが止まります。<a href="https://communities.intel.com/thread/107840">フォーラムでキレている人</a>は<a href="https://github.com/hultqvist/edison-yocto-docker/releases/tag/reduced1611">自分でJavaを筆頭に最低限まで削ったソースを配布</a>していますが、これは本当に最低限なのでNode.jsやconfigure_edison等は含まれません。とりあえずJavaだけなくなれば初回のビルドは通るので、ソースコード内の設定ファイルからOpenJDKとicedtea関係の箇所をどんどん削る必要がありました。どこをどう削ったかは忘れた。</p>
<p>それに加えて、iotkit-comm-jsとiotkit-comm-c-devも削る必要があります。これはIntelの<a href="https://dashboard.us.enableiot.com">IoT Analytics dashboardの運営が終了</a>となったため、それにともなって対応するライブラリ群がIntelのGiuHubから削除されたことが原因になっています。修正箇所は<a href="https://communities.intel.com/thread/108000">フォーラムの記載を参照</a>してください。</p>
<h4>カーネルモジュールをビルドする</h4>
<p>基本的に<a href="https://software.intel.com/en-us/node/593593">Intelが公開しているページ</a>の内容どおりです。が、上記最新版では.configの位置が build_edison/tmp/work/edison-poky-linux/linux-externalsrc/1.0-r2/linux-externalsrc-1.0/.config に、置き換えるdefconfigの位置が poky/linux-kernel/arch/x86/configs/i386_edison_defconfig にそれぞれ変わっています。</p>
<h4>動きました</h4>
<p><a data-flickr-embed="true" href="https://www.flickr.com/photos/36571434@N03/32381930886/in/dateposted-public/" title="Intel Edison with TFT Display"><img src="https://c1.staticflickr.com/1/683/32381930886_e777ae893e.jpg" width="375" height="500" alt="Intel Edison with TFT Display"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script></p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-89978877570980681602015-12-27T19:30:00.003+09:002015-12-27T19:30:59.661+09:00J-LINK EDUが安くて便利<p>ARMマイコンをいじるのにちゃんとしたエミュレータがあるといいなと思っていましたが、どれもかなり高く二の足を踏んでいたところ、J-LINKシリーズの廉価版でJ-LINK EDUというものがあるのを知りました。教育用としか読めないのにふつうに買えるので、ひとつ買ってみました。</p>
<h4>教育以外の人が買ってもいいらしい</h4>
<p>教育・学習が主で、Freescaleのサイトには趣味やNGOでもどうぞといった記述もあったと記憶しています。もともとの目的から、開発業務での使用は認められていないということなので、個人的に使うぶんにはいいらしい。</p>
<h4>1万円以下で買える</h4>
<p><a href="http://www.digikey.com/product-detail/en/8.08.90%20J-LINK%20EDU/899-1008-ND/2263130">DigiKey</a>や<a href="https://www.adafruit.com/products/1369">Adafruit</a>にも取り扱いがあり、だいたい$70以下です。日本円だと<a href="http://www.mouser.jp/ProductDetail/Segger-Microcontroller/J-Link-EDU/">Mouser</a>が安かったので、Mouserで買いました。1台で送料無料枠に入るので助かります。</p>
<p>確認するのに英語版やUSDも見ましたが、通貨レートを見てもUSDのほうがなお安いですね。結局クレジットカード払いだからそっちにすればよかった…。</p>
<h4><a href="https://www.segger.com/jlink_base.html">J-LINK BASE</a>と同等品</h4>
<p>なので、思いのほか機能を積んでいてくれて助かります。20ピンのうちひとつに、ターゲットに供給する5Vを出力する機能がついています。オンオフはコマンドラインからですが、別途電源を用意する必要もなくありがたい。レギュレータで適宜下げた電圧に信号線を合わせてくれるので、定格を超えてしまう心配もなし。</p>
<p>マイコンの評価ボードに付属のデバッガは、そのボードに積んでいるもの以外には対応しなかったりすることがあるので、ちゃんとしたものがあるといいなと思っていたところでした。コマンドラインではありますが、Macでもちゃんと動いてくれるのもありがたいところ。まだ複雑なことに手をつけていませんが、これはいいですね。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-48417811537957082282014-11-09T10:44:00.001+09:002014-11-15T09:25:57.105+09:00Ringの回路雑感<p><a href="https://www.kickstarter.com/projects/1761670738/ring-shortcut-everything">Kickstarter</a>で出資した<strike>変身できないほうの</strike>魔法の指輪が届きました。ソフトや使用感の話はいろいろ出ているので、製品そのものの雑感を書きます。</p>
<h4>電源端子について</h4>
<p>指輪の内側に充電用端子が出ています。満充電後にテスターをあてると、ほぼほぼリチウムイオン電池と同じだけの電圧が出ます。ダイオードでも入れて表に出ないようにしとけよ…なんて思いましたが、充電スタンド側を分解すると<a href="http://www.ti.com/product/BQ24090">TIのBQ24090</a>を積んでいました。充電ICは指輪の中に入っていると予想していたのですが。BQ24090のデータシートの参考回路を見るとICから直接電池につないでいるので、ここを指輪と充電器とで分離すると、指輪の端子で遮断するのはいろいろ調整とか大変なのかなと思いました。</p>
<h4>工事設計認証について</h4>
<p>外箱の底面に技適マークと番号がついていましたが、これはNGです。電波を出すものに記載するので、Ringの場合は指輪に記載します。電波を出すものに書いてある前提で、購入の目安とするために外箱等にも記載するのはOKです。高くなるかもしれないけど、指輪の内側に彫ってあったりしたらちょっとかっこいいのでこれからに期待したいところ。</p>
<p><b>11/15 訂正</b> この工事設計認証の話はBluetooth部分を自前で設計した場合の話で書きました。内部に認証取得済みモジュールを内蔵している場合は、Logbarのやり方が正しくなります。申し訳。</p>
<p>RingのiPhoneアプリにHardware Versionの項目があるので、これからまだ改良が入るかもしれません。Kickstarterの1stロットだから、多少ひっかかる点もあるけれどまあよしと言ったところ。もの自体はちゃんと動くし動いたときは楽しいので、SDKも楽しみに待っています。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com0tag:blogger.com,1999:blog-2454413944984526463.post-15947616412042417042014-06-22T20:00:00.001+09:002014-06-22T20:00:53.464+09:00ArduinoからEthernetで直接fluentdにPOSTする<a href="https://www.flickr.com/photos/36571434@N03/14292816547" title="IMG_0993 by Yusuke Umahashi, on Flickr"><img src="https://farm6.staticflickr.com/5513/14292816547_a6a5deb741.jpg" width="500" height="375" alt="IMG_0993"></a>
<p>ArduinoにEthernet Shieldを載せることで、Arduinoから直接各種サーバにデータを送ることができるようになります。ArduinoでA/D変換した電圧値をfluentdに送付することで、簡易ロガーとして活用することもできます。</p>
<h4>fluentd側</h4>
<p>Ethernet経由で受信するだけなので <a href="http://docs.fluentd.org/ja/articles/in_http">in_http</a> が動くようにします。サンプルどおりで大丈夫です。</p>
<h4>Arduino側</h4>
<p>fluentd の in_http はPOSTで受け取るので、<a href="http://playground.arduino.cc/Code/WebClient">サイトのWebClient</a>を参考にしてPOSTを送信するスケッチを作成します。</p>
<p><ul>
<li>servername:fluentdサーバのドメイン名 or IPアドレス</li>
<li>serverPort:fluentdサーバのポート</li>
<li>pageName:fluentdに送信する際のタグ(スラッシュ含む)</li>
<li>params:fluentdに送信するJSON(json=で始まる)</li>
</ul></p>
<p>コード中のこれらの変数を適宜書き換え、POSTメソッドの生データを組み立てて送信する形になります。</p>
<h4>目的</h4>
<p>回路の性能測定の際、電圧・電流を長時間モニタすることがあります。専用機器を使うものなのですが、機器自体が高価で、なかなか手が出ないものです。A/D変換し値を保存できればよいので、Arduino + fluentdの組み合わせで簡易ロガーとして使用します。fluentd側がが受信した時刻を記録できるので、ネットワークの遅延を気にしない程度の間隔ならば、複数のArduinoで計測記録の同期をとるのも容易です。</p>
<p>また、センサネットワークのセンサそのものに組み込むには高機能高コストですが、別途なんらかの無線とかで受信したセンサの値をネットワークに送信する母艦としても使えると思います。</p>niccollihttp://www.blogger.com/profile/05081830682707964896noreply@blogger.com1