2018年12月14日金曜日

AE-TYBLE16にBLE-MIDIを実装するための途中経過

秋月電子通商のBLEモジュール AE-TYBLE16 は、SWDの書き込み端子が出ているのでファームウェアを書き換えられます。NordicのnRF5 SDKのサンプルコードをいろいろ使うだけでも十分できるのですが、興味のあった MIDI over BLE はサンプルがなかったので実装に挑戦しました。アドベントカレンダーに投稿するのに間に合わなかったので、今回は途中経過を記載します。

Nordic nRF5 SDKでサービスの実装が大変

仕様をみると、次のように実装することとあります。

The following service and characteristic are defined:

  • MIDI Service (UUID: 03B80E5A-EDE8-4B33-A751-6CE34EC4C700)
  • MIDI Data I/O Characteristic (UUID: 7772E5DB-3868-4112-A1A9-F2669D106BF3)
    • write (encryption recommended, write without response is required)
    • read (encryption recommended, respond with no payload)
    • notify (encryption recommended)

「このUUIDのサービスとキャラクタリスティックを実装すればいいんだろ」と思っていましたが、この時点でまず大変でした。

今回のようにサービスとキャラクタリスティックでUUIDが異なっていると、「フルサイズのUUIDをいくつも使うぞ」という設定が必要でした。フォーラムのやり方でそれっぽいのを見つけて実装しデバッグすると、ログにメッセージが出ます。「ユーザーが使うメモリの割当を次のように変えろ」というメッセージが出るので、それに従ってリンカスクリプトを修正します。これでやっと電波が飛ぶようになります。

仕様の「encryption recommended」にひっかかる

電波が飛ぶようになったのですが、MacはMIDIポートとして設定してくれません。おそらく仕様の「encryption recommended」が欠けているのが原因のようで、Mac側としてはマウスやキーボードのようにペアリング動作を完了できないとMIDIポートとして設定されないようです。もともとベースにしていたサンプルコードがペアリング処理のないものだったので、ペアリング処理のあるサンプルに移植するのもめんどうだなとなって放置気味になってきたところで今日に至っています。

まとめ

すごく手間なので、Arduino環境でつくるほうに乗り換えようかちょっと考えています。でもペアリングの動きとか後ろ側の動きについてかなり勉強になった感じはするので、なしではないです。

2018年11月12日月曜日

秋月のBLEモジュールでHIDを扱えるようにする

秋月に太陽誘電のBLEモジュール AE-TYBLE16 が販売されています。このモジュールは端子が底面からのみ出ているので、基板実装をしないと扱いづらいのですが、秋月がその基板実装を行った状態で販売しているので非常に扱いやすくなっています。

このモジュールは中のnRF51822に対してあらかじめファームウェアが書き込まれており、電源が入ると独自のサービスを飛ばします。UARTで適切なコマンドを入力すると、その中のキャラクタリスティックにデータが送りこまれると聞いています。

この秋月モジュールは電源・GPIOに加えてSWDIO・SWDCLKが出ているので、JLink等のライターを使用すると自分で作ったファームウェアに置き換えられます。

ファームウェアの書き込み

Before

After

J-LINKから書き込むにあたって、最低限次の配線接続があれば動作します。

  • SWDIO
  • SWDCLK
  • リセット
  • Vref
  • GND

20ピンJ-LINKだと、これに加えて5V供給とUSB-UART変換が使えるのでそれもつないでいます。5V供給をLDOで3.3Vに落とすとモジュール電源とVrefに使えるので、外部電源を容易せずともデバッグができるようになります。当初はブレッドボードにワイヤーを刺していましたが、持ち運びがめんどうなのでユニバーサル基板に実装しました。配線がつながった状態でnrfjprogをつかうと書き込みができるようになります。

nRF5 SDKのサンプルコードを動かす

今回はゲームボーイのカセットに組み込みたいので、nRF5 SDK 12.3.0のうちHID over GATTのマウスサンプルを使いました。

ble_app_hids_mouse/pca10028/s130/armgcc でmakeを実行するとビルドはできますが、サンプルの前提となっている環境と AE-TYBLE16 で異なる箇所があるのでそのままでは動きません。下記を修正しました。

sdk_config.h

  • CLOCK_CONFIG_XTAL_FREQ 255→0
  • CLOCK_CONFIG_LF_SRC 1→0

components/boards/pca10028.h

#define NRF_CLOCK_LFCLKSRCの中身を直す

RTCはモジュールに載っていないので、nRF51822内蔵を使うようにします。

  • .source        = NRF_CLOCK_LF_SRC_XTAL→NRF_CLOCK_LF_SRC_RC
  • .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM→NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM

components/toolchain/system_nrf51.cとsystem_nrf51422.c

16MHzを32MHzに変更します。

#define __SYSTEM_CLOCK      (16000000UL)→(32000000UL)

ここまで直してNRF_LOGの中身がJLinkRTTのなかに表示されるようになります。APP_ERROR:ERROR:Fatalとだけ表示されるので、マイコンは動いていますがアプリは止まっています。

main.c

ble_stack_initのクロック設定を直します

nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;の行は削除。かわりに

    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;
を追加。

ここを直すとJLinkRTTにAPP:INFO:HID Mouse Start!というメッセージが表示されて、BLEの電波も飛ぶようになります。

直したけど関係なさそうな箇所

接続はするがペアリングはされない、という状況が起きていて、こういう投稿があったので試してみたら動いたんですが、このブログを書くにあたって再度いちばん最初の段階からやり直してみたら、この変更なしでもペアリングが済んでいて頭を抱えています。

2018年10月13日土曜日

ESP32をBluetoothマウスにする

ゲームボーイを無線マウスにした際に、Bluetooth側はESP32を使って実装しました。キーボードのサンプルコードに記載の関数群でマウスまでまかなえたので、使い方を記載しておきます。

ESP-IDFを使う

ESP-IDFのBluetooth Low Energyサンプルのうち、HID over GATTを使います。

ESP-IDF BLE HID device demo

ble_hidd_demo_main.cではほとんどConsumer Keyの送信しかしていないのですが、esp_hidd_prf_api.hにはきちんと関数が実装されています。

  • void esp_hidd_send_consumer_value(uint16_t conn_id, uint8_t key_cmd, bool key_pressed);
  • void esp_hidd_send_keyboard_value(uint16_t conn_id, key_mask_t special_key_mask, uint8_t *keyboard_cmd, uint8_t num_key);
  • void esp_hidd_send_mouse_value(uint16_t conn_id, uint8_t mouse_button, int8_t mickeys_x, int8_t mickeys_y);

いずれも、キー操作情報等の最低限のデータを入れればよしなに成形して無線で飛ばしてくれます。

マウス利用時のmouse_buttonは、レポートディスクリプタの0バイト目にああたります。下位3ビットに3ボタンマウスのそれぞれが割り当てられています。下から右・左・中ボタンになります。

2018年10月9日火曜日

技術書典ふりかえり

技術書典に本を出す側で参加したのでその記録です。

出した内容

  • ゲームボーイのカートリッジ基板の作り方をまとめたPDF
  • 実際に作ったカセットのデモ

本はPDF版のみにし、購入もすべてBoothで行ってもらう方法にしました。なので、現場での授受はそのBoothのURLとQRコードを印刷したカードのみです。ひとりチームなので金銭のやりとりとか決裁のトラブルとか抱えたくないのと、今後更新を行うときに購入してくれた人に損がないようにと考えてPDF版のみかつBoothのプラットフォームで更新通知を容易にしたいなと思ってこういう形にしました。もともと自分が調べたことを忘れないように書いた本の内容に、今後調べたり試したりして新しいことがわかったらとか改良の余地がありまくるので、そういうのが増えたら追記・更新したいんですよね。

カードの裏面は著者(というかおれ)の名刺代わりにしたので、余ってもあとで名刺として配ってアピールできるなと。

当日の様子

机の上は見本として印刷したPDFの中身と、実際に動作するゲームボーイのデモを置いておきました。他の振り返りの記事にあった「見本誌は2冊あったほうがいい」という内容を、本とデモ機でうっかり満たした感じがしました。

個人的には本を買ってもらうよりも「俺が作ったものが超おもしろいからおまえらも見ろ」という感じでデモ推しの気持ちだったので、Bluetoothマウスにしたゲームボーイを触ってもらって、おもしろかったらカードを持ち帰ってもらう、みたいな流れに落ち着きました。特定の年齢層だけは、説明する前から操作方法がバッチリはまる様子に最高に笑いました。

その他電気の気付き

  • マウスのデモに使ったMacBook Proは終了の17時ちょうどに電池が切れたのでギリギリもった
  • Bluetoothに使ったESP32がおもいのほか大健闘
    • モバイルバッテリーから電源を取ったが、容量ゲージが減る気配がない。
    • 会場の電波が落ち着いていて混信がなく、常時問題なく動作。

ESP32はデータシート上だと電流がそんなに消費しないと書いてあって本当かよって思っていましたが、Bluetoothだけだと本当にそんなに消費しないっぽいです。今度測ってみます。

https://niccolli.booth.pm/items/1026724

もし当日の本に興味があれば、上記リンク先から購入ください。デモがないとおもしろいところがわかりにくいと思いますが、何らか参考になれば幸いです。カードを持ち帰りいただいた方から、結構な数の購入をいただいた通知が来まして、ありがたい限りです。

2018年9月29日土曜日

ゲームボーイを無線マウスにする

ひとつ前の投稿でゲームボーイのカセットを作って遊んでいましたが、カセット側のRAMに値を保存すれば周辺部品と通信できるという仕組みは正式な製品でもたくさんつかわれている手法らしい。なので実装に挑戦しました。

とりあえずやりやすそうだった無線マウスをやってみたところ、期待どおり動いて安心。カセット側RAMはマイコンの中にいるので、保存された値はマイコンからいじり放題です。そのカセット側RAMにキー操作情報を入れて、マイコンからESP32に飛ばしています。

というような話をPDFにまとめて、技術書典5で紹介します。なんらか操作できるものを置いておく予定なので、試して笑う程度でも歓迎です。

2018年6月23日土曜日

ゲームボーイのカセットをつくった

よくよく考えてみたら、ゲームのカセットは中身が基板なので、このご時世ならつくるのはたやすいのではないかと思ってやってみたら、遠回りをしつつもうまく動いた。

なぜゲームボーイにしたのか

手元にあったから

実家に置きっぱなしだったのを回収してきて以来、電源の確保が容易なのでずっと遊んでいる。最近はSwitchを買ってしまいスプラトゥーンとプリパラが楽しいのでほったらかしになってきた。

どうかしてる機能を積んだカセットが多かったから

ファミコンやスーパーファミコンは、拡張機能は本体のポートに専用コントローラーやサテラビューみたいなのをつないで実現していたけれど、ゲームボーイはその辺をカセットの延長でつくっていた印象があって。ポケットカメラやカービィの傾きセンサーなんかがその例(個人の感想です)。今やるならBluetoothとか各種無線通信を載せていきたい。

作り方

海外は作っている人が少なからずいるので、そのへんの人の作例を参考に。

http://www.happydaze.se/wolf/
https://github.com/dwaq/Homebrew-Gameboy-Cartridge

カセット側の動作は基本的に

  • 16ビットのアドレスを受けて対応する8ビットの値を
    • 返す (ROM/RAM)
    • 保存する (RAM)
  • バンクを切り替える

なので、このあたりの配線がつながっていればOK。速度が速度なので、等長配線を気にする必要もない。

https://dhole.github.io/post/gameboy_cartridge_emu_1/

dholeさんがSTM32F4Discoveryをつかって、バンク切り替えの任天堂ASICの擬態を行いつつROM/RAMまでSTM32マイコンでまかなう方法を書いてくれているので、この通りに信号線をつなぐとこうなります。

直したい点

穴位置を間違えた

基板の端子情報をライブラリにしてる人がいるのでそのデータを使おうとするも、Eagleが慣れないのでCircuitMakerに持ってくる際に、大きいほうの穴位置がずれたらしく、カートリッジの筐体にすんなりはまらない。次つくることがあったら直す。

電源の使い勝手

ふつうカセットは外から何かするわけじゃないので、ゲーム機から電源をもらって動くのは当たり前の動作だけど、ゲーム機の電源とカセットの電源を別にしておかないと、マイコン側のデバッグで困る。ゲームボーイ本体の電源が入っていないと動作をデバッグできない。ジャンパ等で切り替えられるようにしたい。

2017年12月9日土曜日

100円SIMのいいところと面倒なところ

2017年7月、NTTコミュニケーションズが100円SIMのサービスを発表しました。価格から惹かれるところがあり内容を伺ったところ、周囲の人からも「あれどう?」ときかれたことがあったのでメモを残しておきます。

Arcstar Universal Oneのオプションのような位置づけ

NTTコミュニケーションズのVPNサービスArcstar Universal Oneの契約が必須(VPNに接続する回線の設置工事等も必要)であり、100円SIM単独での利用はできません。さくらやSORACOMのようにSIMを購入して使うのではなく、VPNサービスへの入り口としてSIMが100円で提供されるというものです。

Arcstar Universal Oneは仮想とはいえ閉じているので、デバイスからのセンシティブなデータでも比較的安全に送信ができます。保存するデータベースは、NTTコミュニケーションズが提供するVPN内のサーバを使うパターンと、VPNからAWSやMicrosoft Azureなどの各種クラウドサービスに接続するパターンが用意されています。

大規模な業務用途向け

最低発注数量は100枚という記載もどこかにあったので、外部に絶対に流出させたくないセンサーデータを安全かつ大規模に収集するような用途等、業務用として使うものということでした。また、記載のような業務用なので、NTTコミュニケーションズの営業さんへの見積もりが必須です。個人もしくは小規模での3G/LTE回線がほしいという話ならば、sakura.ioやSORACOMの利用を検討したほうがよいと思います。