Lazy Diary @ Hatena Blog

PowerShell / Java / miscellaneous things about software development, Tips & Gochas. CC BY-SA 4.0/Apache License 2.0

無線キーボード自作に関して調べたこと

HHKBを無線化したい!そしてArduino×2とXBee×2を用意すれば無線化できるかも!と思ったのが最初の構想。
しかし情報漏洩対策が叫ばれる昨今、仕事場でUSBハブに怪しげなデバイスが刺さってたら疑われるだろうと、Bluetoothによる無線キーボードの実装方法について調査したのですが、大変ハードルが高くてグワーッ!

調べたこと

  1. 無免許でBluetoothZigBee等の無線モジュールを使うなら、技適(技術適合証明)*1取得済モジュールが必須。技適マークのないモジュールを使うと電波法違反になるなる可能性がある *2
  2. 技適マークなしのモジュールの輸入や販売はOKで使用はNGという扱い*3なので、国内のお店で売ってるモジュールでも油断できない。
  3. 無免許&技適マークなしだと相当小さな電力でしか通信できない*4BluetoothZigBeeも無理っぽいけど詳しい調査はしてない。
  4. 技適のないモジュールも、免許を持っている人なら無線局の開設手続きをすれば使えるけど、その場合も機器の設計を添えて申請が必要*5。電波強度の測定なんかも必要みたい。事実上、個人レベルでは技適取得済モジュールを使う他ない。
  5. Bluetoothの通信速度は方向対称・非対称の場合で異なり、対称の場合は最大1.3Mbps程度*6。USBの信号を載せるならバッファリングとか要りそう。
  6. Bluetoothにはプロファイルというのがあって、送信側・受信側が同じプロファイルで話さないといけない。対応してるプロファイルはモジュール毎・受信機毎に違う。
  7. Bluetoothモジュール自体に信号を与えるインタフェースもモジュール毎に違う。UARTだったり、USBだったり。
  8. Bluetoothバイスは使う前にペアリングが必要。OS上で動作するドライバソフトウェがペアリングを行う受信機と、ハードウェア単体でペアリングできる受信機とがある。
  9. BIOS操作や、シンクライアントで使うとかなら、ハードウェア単体でペアリングできる受信機が必要。ロジクール RCBT-MX*7やBelkin F8T016*8がある。ただし前者はBIOS画面でFnキーが動作しない模様で、シンクライアントでも怪しいかもと思っている*9
  10. ロジクール RCBT-MXは、ハードウェアペアリングの場合HIDプロファイルにのみ対応の模様。F8T016が対応しているプロファイルの情報は見つからなかった……
  11. Arduino等でBluetooth通信を容易に行えるようにしたモジュールもある*10。それを使わないならBluetoothプロトコルスタック*11を実装する必要がある。
  12. USBなど、1.5Mbps程度の通信を行うならクロックジェネレータは水晶を使ったほうがよい。AVR内蔵のクロックでは精度不足。セラロックの場合は選別が必要*12。通信速度を抑えれば大丈夫?
  13. 技適取得済みBluetoothモジュールとしてはBT-MOD100R*13があるが、対応しているプロファイルはSPPのみなのでRCBT-MXでは使用できない。F8T016がSPPに対応しているかは謎。
  14. 技適取得済みBluetoothモジュールとして他にもSurfGridのBlack Shield*14があるが、これもAndroid向けのモジュールなのでプロファイルはSPP(とGAP)にしか対応していない。
  15. 技適を通っており、かつHIDプロファイルに対応しているBluetoothモジュールとしてはBroadcom BC2045*15を搭載したJ27H002*16が手に入れやすいが、これはデータシートがネット上で見つからない*17。また、インタフェースがUSBなので、このモジュールとは別にArduinoからUSBを喋る用のモジュールなりが要る。Teensy*18Arduino化したりすれば良いのかな?
  16. Blugiga WT-12はデータシートが簡単に手に入るらしく*19、海外ではその点が好評みたい。
  17. Arduinoで使えそうなBluetoothモジュールがまとめられているページを見つけた*20

作例など

  1. ArduinoBluetoothモジュールを載っけたArduino BT*21というものもあるが、これは技適を通っていない。BluetoothモジュールはBluegiga WT-11を積んでいる。
  2. Android向けにHHKBをBluetooth化している例*22もあるが、これはBT-MOD100Rを使ってSPPプロファイルで実現している。
  3. HHKBをHIDプロファイルでBluetooth化している例*23もあるが、ここで使用しているBluetoothモジュール(Bluegiga WT-12)は技適を通っていない。
  4. Arduinoを使ってBluetooth HIDデバイスを作成するためのHOW TO*24もあるが、ここで使用しているBluetoothモジュール(BlueSMiRF HID*25)も技適を通っていない。
  5. Bluetoothキーボードを実現するためのチップとしてはBroadcom BC2042*26がある。
    • 利点としては、Wiiのコントローラなどに使用されているため入手性がいいことと、キーボードマトリクスをそのまま入力できること。
    • このチップを搭載しているモジュールとしてはBlue Packet BP20422*27くらいしかなく、当然技適も通っていない。
    • 作例としてはWayne and Layneのもの*28やkeygrobeのもの*29が見つかった。

調査の際の注意事項

  • "Arduino Bluetooth"などでググると、Bluetoothレシーバ(ホスト側のこと。ドングルなど)を使ったBluetoothホストコントローラの使い方がよく引っかかる。作りたいのはBluetoothトランスミッタ(クライアント側のこと。Bluetoothバイス)なので、作例調査の際は何を作っているのか要注意。
  • 例えば、Broadcom BCM2045はWiiマザーボード側に搭載されている*30チップで、これはレシーバ用チップ。トランスミッタ用のチップは前述したBCM2042で、これはWiiのコントローラ側に搭載されている*31。「すzのAVR研究」で安価なWiiBluetoothモジュールとして紹介されている*32のはレシーバの方。
  • 船田戦闘機氏のブログでも*33Bluetoothクライアント用モジュールに関しては苦戦しているみたい。
  • これは勘違いっぽい。Bluetoothは双方向通信可能な規格なので、どちらからもデータを送信できる*34

。また、ハンドシェイクの際にどちらがマスタ(PC側)でどちらがスレーブ(周辺機器側)か決めるらしい*35

  • USB BluetoothドングルをPCまたはPICマイコンに繋げて、マウスの真似事をさせる作例が見つかった*36。チップとしてはCSRのBlueCoreを搭載したドングルを使用している模様。
    • CSR BlueTooth シリアルモジュールの解析*37というページを発見した。ここで使用しているのはCSR BlueCoreのBC417(BC417143B?)というチップ*38みたい。

プロトコルスタックについて

  • Bluetoothにはプロトコルスタックというのがある。一番下がHCIという規格で、これはBluetoothのチップとやりとりする手順の規格。HCI-USBやHCI-UARTなどがある。
  • HCIの上には、ハンドシェイクをしたり、プロファイル情報を提供したり、プロファイル通りのデバイスとして振舞ったりといったプロトコルが載っかってくる。
  • 高価なモジュールには「プロファイル通りのデバイスとして振る舞う」あたりのプロトコルスタックが実装されているけれど、安いUSBのBluetoothドングルにはそれがない(HCIくらいしか実装されていない)ため、OS上でデバイスドライバがそれより上のプロトコルを喋る役割をしている。
  • 当初はBluetoothスタックを搭載したモジュールばかりを探してたから気づかなかったが、HCI以下のレイヤだけを実装したドングルを使って、上位レイヤをソフトウェアで実装すれば、理論上は何でもできるのでは?と考えている(上のBluetooth+PICマイコンの例みたいに)。

ArduinoにおけるUSB

  • ArduinoをUSBホスト*39として動かすには、通常USB Host Shield*40というものを使う。でっかいArduino用。
    • ちっちゃいArduino用のUSB Host Shield for Arduino Pro Mini*41というものもあるが、国内では扱っている店がないらしい*42のでこれを使うなら輸入となる。
  • USB Host Shieldを使えば、Arduinoを簡単にUSBホストにできるみたい。でも結構お値段が張る……
  • Arduino Leonard*43に載る石(ATMega32U4)には、USB端子を操作するための機能も付いているらしい。ならUSB-HCIもイケるかな?と調べたところ、V-USB*44やLUFA*45などを使えばArduinoにUSBを喋らせることができそう。
    • つまり、USB Host Shieldがやってくれる処理をソフトウェアで代替するということだろうね(処理は重くなるだろうけど)
  • V-USBは基本的にUSBデバイスとして動くためのプロトコルスタックで、つまりATMega32U4にハードウェア的に載っているのと同じ機能なんではないかと理解している。
  • LUFAはUSBのデバイスにもホストにもなれるみたい。LUFAの作者がAVRマイコンBluetoothドングルを挿して動作させているのを発見*46
    • ボードは小さくてTeensy++かと思ったけど違った。MicropendousA*47というボードらしい。
    • Bluetoothスタックは自作とのこと。論文があるようなので後で見る。
  • 結局LUFAがやってくれる処理と、ATMega32U4が提供するUSB制御機能の関係はどうなるんだろう?

LUFA, V-USB, USB Host Shield, ADKの関係

  • LUFAはAVRに内蔵されたUSB制御機能を使用してUSBデバイスを実現する。
    • LUFAをダウンロードして解凍すると、サポートしているデバイスの情報がLUFA/DoxygenPages/DeviceSupport.txtに書かれている。
    • AVRでも石によってLUFAの対応・非対応が異なる。また、USBデバイスにしかなれないのか、それともUSBホストにもなれるかも異なる。
      • 例えば、Arduino Leonardに載っているATMega32U4では、デバイスにはなれるがホストにはなれない。
      • AT90USB1286ではデバイスにもホストにもなれる。
    • Bluetoothドングルへは対応途中みたい。LUFAのアーカイブを展開すると/Demos/Host/Incomplete/BluetoothHost以下にBluetoothバイス用のコードらしきものがある。
  • V-USBはAVRにUSB制御機能が内蔵されていなくても、割り込み用の信号線を利用してUSBプロトコルを喋らせる(つまり、USB制御機能をソフトウェアで実装する)プロジェクト。
    • LUFAが対応していない石でもUSBを喋らせられると解釈。
    • 基本的に実装できるのはHIDかUSBシリアル*48程度で、それ以外のデバイスを実装するには自前で実装を書く必要がある。
    • USBホストになれるという情報は見当たらなかった。
  • USB Host Shieldでは、AVRとは別のチップにUSBを喋らせる。使っている石はMAX3421E*49
    • なので、LUFAやV-USBとは全く別モノ。
    • MAX3421Eはデータシートもオフィシャルなものが入手可能みたい*50
    • Bluetoothドングルを制御する作例が、Circuits@Home*51のサイトにあった*52
    • 注意点として、結構電力を食うみたいで、USBバスパワーだけではうまく動作しない可能性があるとのこと*53
  • ADK(Android Open Accessory Development Kit)はArduinoAndroid用のデバイスを開発するための、Arduinoベースのボード。
    • これに準拠しているデバイスには、USB Host Shieldと同じMAX3421Eが載っている*54ので、Arduino+USB Host Shieldの構成と同じように使えるかも。
    • ArduinoとUSB Host Shieldを使ってADKコンパチのデバイスを作る例がside2.jp*55やAndroDocs*56で見つかった。

Harpyについて

  • 安価に入手できて小型のADKとして、Harpy*57がある。Engadget Japanで紹介されているのを見つけた。
    • Harpy Nano*58は非常に小さくて、HHKBにも内蔵できるかな?要サイズ調査。
    • ADKなので、当然MAX3421Eも積んでいる。
    • Harpyと、Arduino+USB Host Shieldとの互換性について議論している記事が見つかった*59

キーボード内部の仕組みについて

  • HHKB Professionalの内蔵マイコンをAVRで置き換えた作例*60を発見した。
    • キーボード内蔵のマイコンがキーをスキャンする仕組みも分かってきた。メンブレンのシートにN×Mのマトリクスがある場合、N+Mビットを一度にスキャンするんじゃなくて、NビットをM回スキャンする。これで2キー以上の同時押しも検出できる。
    • 部品的には、マルチプレクサで行を指定して、その行の内容を読む感じになるみたい。
    • スキャンレートはHHKB Proの場合で66Hz。13msくらいで全行の内容を読むことになる。

Bluetoothについて

  • Bluetoothにはクラス(Class 2とか)とバージョン(2.0+EDRとか)がある*61。前者で電波強度や消費電力、後者で通信速度なんかが決まるみたい。
  • 無線キーボードのプロファイルは普通HID(普通のキーボード)かSPP(シリアル接続のキーボードみたいなもの?)。iPhoneはHIDのみ対応で、AndroidはSPPのみ対応みたい。

Arduinoについて

  • まずは素人向けの情報を読んでみる*62

今後の予定?

  • Circuits@Homeの"Bluetooth code for Arduino USB Host"*63を読む。
    • Bluetooth HIDプロファイルの実装方法を調べる。不明であればBluetoothの企画書に当たる。調べる規格のバージョンはUSBドングルに合わせる。
    • CSR BlueTooth シリアルモジュールの解析」*64はSPPプロファイルについて調べているようなので、あまり役に立たないかも?
      • BlueLab(BlueCoreシリーズの開発キット?)にサンプルが同梱されているようなので、そこは調べる価値があるかも。
  • USBドングルを入手する。"Bluetooth code for Arduino USB Host"で使っているものか、「Bluetoothドングルを使った無線通信実験」*65で使っているものがよい。
  • Harpy Nano*66が欲しい。

→ 続きを書きました(id:satob:20120603)

*1:http://ja.wikipedia.org/wiki/%E6%8A%80%E8%A1%93%E5%9F%BA%E6%BA%96%E9%81%A9%E5%90%88%E8%A8%BC%E6%98%8E

*2:http://www.tele.soumu.go.jp/j/adm/monitoring/summary/qa/giteki_mark/

*3:http://blog.livedoor.jp/spiritual_area/archives/51727060.html

*4:http://www.tele.soumu.go.jp/j/ref/material/rule/

*5:http://2chnull.info/r/radio/1273029907/226-226

*6:ZigBee(XBee)だと144kbps程度みたい

*7:http://store.logicool.co.jp/lcs/catalog/product_info.php?cPath=67_221&products_id=2000898

*8:http://www.belkin.com/IWCatProductPage.process?Product_Id=398674

*9:ただしこの件については、(1)Fnキーが効かないとそもそもF2とかでBIOS画面に入れないんじゃ? (2)職場のシンクライアントBluetoothキーボードを使っている先輩がRCBT-MXを使っているっぽい、の2点から心配しなくて良いかもと思っている

*10:http://www.kobakant.at/DIY/?p=3310

*11:http://en.wikipedia.org/wiki/Bluetooth_stack#Embedded_implementations

*12:http://www.geocities.jp/arduino_diecimila/obaka/project-5/

*13:http://park11.wakwak.com/~microtechnica/cgi-bin/goodslist.cgi?mode=view_detail&genre_id=00000028&goods_id=00000001

*14:http://www.junglejapan.com/products/surfgrid/

*15:http://ja.broadcom.com/products/Bluetooth/Bluetooth-RF-Silicon-and-Software-Solutions/BCM2045

*16:http://suz-avr.sblo.jp/article/39493974.html

*17:聞いた所ではBroadcomは製品のデータシートの無料公開はしていないらしい

*18:http://www.pjrc.com/teensy/

*19:http://d.hatena.ne.jp/ramencozo/20110327/1301203353

*20:http://side2.jp/2010/01/bluetooth-module/

*21:http://arduino.cc/en/Main/ArduinoBoardBluetooth

*22:http://blog.livedoor.jp/jun_dime/archives/51548297.html

*23:http://geekhack.org/showwiki.php?title=Island:20851

*24:http://www.kobakant.at/DIY/?p=3310

*25:http://www.sparkfun.com/products/10938

*26:http://ja.broadcom.com/products/Bluetooth/Bluetooth-RF-Silicon-and-Software-Solutions/BCM2042

*27:http://www.bluepacket.net/BluePacket/solutions/solutions.aspx

*28:http://www.wayneandlayne.com/blog/2010/05/28/bluetooth-keyboard-module-part-1/

*29:http://www.keyglove.net/2011/03/15/interfacing-with-a-bcm2042-bp20422-bluetooth-hid-module/

*30:http://wiire.org/Wii/console/bluetooth_card

*31:http://wiire.org/Wii/wiimote

*32:http://suz-avr.sblo.jp/article/39493974.html

*33:http://www.nnar.org/archives/1800

*34:http://mobiquitous.com/device/bluetooth-serial.html

*35:http://www.musenka.com/bluetooth/zeal_manual.html

*36:http://homebrew.jp/show?page=1203

*37:https://sites.google.com/site/csrbluetooth/home

*38:データシートは http://www.datasheetarchive.com/BC417*%20CSR-datasheet.html で見つかる

*39:BluetoothドングルはUSBの周辺機器(スレーブ)だから、Arduinoはマスタとして働く必要がある

*40:http://www.switch-science.com/products/detail.php?product_id=438

*41:http://www.circuitsathome.com/products-page/arduino-shields/usb-host-shield-for-arduino-pro-mini

*42:http://iwatanlab.blogspot.jp/2011/07/arduino-pro-miniadk.html

*43:実際にはダ・ヴィンチ32Uの使用を想定。 http://strawberry-linux.com/support/25005/1187959

*44:http://www.obdev.at/products/vusb/index.html

*45:http://www.fourwalledcubicle.com/LUFA.php

*46:http://fourwalledcubicle.com/blog/2011/09/oh-and-that-robot-thing/

*47:https://code.google.com/p/micropendous/wiki/MicropendousA

*48:http://d.hatena.ne.jp/deb/20110103/1294060194

*49:http://www.sparkfun.com/products/9628

*50:http://japan.maxim-ic.com/datasheet/index.mvp/id/3639

*51:USB Host Shieldの開発元?

*52:http://www.circuitsathome.com/mcu/bluetooth-code-for-arduino-usb-host

*53:http://www.ytsuboi.org/wp/archives/1989

*54:http://www.ytsuboi.org/wp/archives/1989

*55:http://side2.jp/2011/05/try-adk-part1/

*56:https://sites.google.com/a/gclue.jp/android-docs-2009/arduino-unodeadkwo-zi-zuo

*57:http://www.harpyhack.com/

*58:http://www.harpyhack.com/#cc-m-product-5644560415

*59:https://groups.google.com/group/harpyhack/browse_thread/thread/3f7484e81712ec3?hl=ja

*60:http://geekhack.org/showwiki.php?title=Island:12047

*61:http://fnya.cocolog-nifty.com/blog/2009/05/bluetooth-d6e8.html

*62:http://robo.mydns.jp/Lecture/index.php?Arduino

*63:http://www.circuitsathome.com/mcu/bluetooth-code-for-arduino-usb-host

*64:https://sites.google.com/site/csrbluetooth/home

*65:http://homebrew.jp/show?page=1203

*66:http://www.harpyhack.com/#cc-m-product-5644560415