Bimeji Client for Arduino
2010年1月24日
Tweet
前回紹介したWimeji Client for Arduinoの最後で予告していた、Wimeji clientのBluetooth版が完成したのでご報告。
概要
- これはArduinoを使ったAndroid向けの自作ハードウェアキーボードです
- 自身で、Arduinoの配線をする必要があります。
- Bluetoothなのでバッテリー駆動させれば、どんな場所でも利用可能です
- PS/2接続タイプのキーボードなら、自分好みのキーボードが利用可能です
これらの機能を実現する為に、アンドロイドアプリ adamrocker氏作のSimeji と esmasui氏作のBimejiSPP版を利用しています。
必要な部品
今回使った主な部品は以下の通り。
部品だけで、13,000円以上(目安)もかかってしまって随分高いBTキーボードです><
|
品名 |
個数 | 価格 |
| Arduino Duemilanove | 1 | 3,200 円 |
| BT-MOD100R(Bluetoothモジュール) | 1 | 7,500 円 |
| 80FG970(BT-MOD100R用アダプタ) | 1 | 1,300 円 |
| PS/2(mini-DIN6) コネクター | 1 | 120円 |
| PS/2 キーボード | 1 | 1,000円程 |
PS/2コネクターは、僕は不要マザーボードからもぎ取りましたが、千石電商では6P ミニDINソケット(基板用) 120円で売られているようです。
配線(回路図)
BTモジュールは、こちら(Android+Bluetooth+Arduino)で紹介したBT-MOD100Rを利用しています。
他のモジュールを使う場合も、TXを6PINにRXを5PINに接続して、ソースのスピード設定部分を変更すれば利用できると思います。

完成写真です。今回はユニバーサル基板を割って、自作シールド化してみました。
PS2コネクタは、前回利用した物で、不要マザーボードから無理矢理剥がし取った物。1段高くなっていて不細工です。
ソース
Arduinoのソースです。WimejiとBimeji両対応のソースとなっています。
このままでも動作しますが、Bimejiで利用する場合は冒頭の #include <Ethernet.h> を削除すると、コンパイル後のコードが多少小さくなります。
逆にWimejiで利用する場合は冒頭の #include <NewSoftSerial.h> を削除すれば、こちらも多少コードが小さくなります。
#include <NewSoftSerial.h>
#include <Ethernet.h>
#include <ps2.h>
//#define DEBUG
#define USB_BAUD 9600UL // USB Serial Baudrate
#define BT_BAUD 9600UL // Bluetooth Connection Baudrate
#define PS2_CLK_PIN 3
#define PS2_DAT_PIN 4
#define BT_TX_PIN 5
#define BT_RX_PIN 6
PS2 kbd(PS2_CLK_PIN, PS2_DAT_PIN);
#ifdef Ethernet_h
// 各自の環境に合わせて編集してください。
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 25 };
byte server[] = { 192, 168, 1, 12 };
Client client(server, 10000);
#endif
#ifdef NewSoftSerial_h
NewSoftSerial BTSerial(BT_RX_PIN,BT_TX_PIN);
#endif
int kcLength,kcExLength;
// http://www.simandl.cz/stranky/elektro/keyboard/keyboard_a.htm
byte ps2_kc[] =
{
0x16, 0x1e, 0x26, 0x25, 0x2e, 0x36, 0x3d, 0x3e, 0x46, 0x45, 0x4e, 0x55, 0x6A, 0x66,
0x0D, 0x15, 0x1D, 0x24, 0x2D, 0x2C, 0x35, 0x3C, 0x43, 0x44, 0x4D, 0x54, 0x5B, 0x5D,
0x58, 0x1C, 0x1B, 0x23, 0x2B, 0x34, 0x33, 0x3B, 0x42, 0x4B, 0x4C, 0x52, 0x5A,
0x12, 0x1A, 0x22, 0x21, 0x2A, 0x32, 0x31, 0x3A, 0x41, 0x49, 0x4A, 0x51, 0x59,
0x14, 0x11, 0x29, 0x76,
0x05, 0x06, 0x04, 0x0C, 0x03, 0x0B, 0x83, 0x0A, 0x01, 0x09, 0x78, 0x07,
0x77, 0x7B, 0x71, 0x7C, 0x79,
0x70, 0x69, 0x72, 0x7A, 0x6B, 0x73, 0x74, 0x6C, 0x75, 0x7D,
0x84, 0x7E,
0x0E, 0x67, 0x64, 0x13,
};
byte send_kch[] =
{
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^','\', 8 ,
9 , 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '@', '[', ']',
0 , 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', ':', 10 ,
0 , 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '\', 0 ,
0 , 0 , ' ', 27 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , '-', '.', '*', '+',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
0 , 0 ,
0 , 0 , 0 , 0 ,
};
byte send_kch_s[] =
{
'!', '"', '#', '$', '%', '&',''', '(', ')', 0 , '=', '~', '|', 0 ,
0 , 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', ']',
0 , 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0 ,
0 , 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', '_', 0 ,
0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , '-', '.', '*', '+',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
0 , 0 ,
0 , 0 , 0 , 0 ,
};
word send_kc[] =
{
0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0007, 0x0045, 0x390D, 0x0049, 0x0043,
0x0000, 0x002D, 0x0033, 0x0021, 0x002E, 0x0030, 0x0035, 0x0031, 0x0025, 0x002B, 0x002C, 0x004D, 0x0047, 0x0048,
0x0000, 0x001D, 0x002F, 0x0020, 0x0022, 0x0023, 0x0024, 0x0026, 0x0027, 0x0028, 0x004A, 0x3928, 0x0042,
0x0000, 0x0036, 0x0034, 0x001F, 0x0032, 0x001E, 0x002A, 0x0029, 0x0037, 0x0038, 0x004C, 0x0049, 0x0000,
0x0000, 0x0000, 0x003E, 0x0004,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0045, 0x0038, 0x0011, 0x0051,
0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010,
0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
};
word send_kc_s[] =
{
0x3908, 0x3921, 0x390A, 0x390B, 0x390C, 0x390E, 0x394b, 0x3910, 0x3907, 0x3933, 0x0046, 0x390D, 0x392D, 0x0000,
0x0000, 0x3B2D, 0x3B33, 0x3B21, 0x3B2E, 0x3B30, 0x3B35, 0x3B31, 0x3B25, 0x3B2B, 0x3B2C, 0x392E, 0x3930, 0x3935,
0x0000, 0x3B1D, 0x3B2F, 0x3B20, 0x3B22, 0x3B23, 0x3B24, 0x3B26, 0x3B27, 0x3B28, 0x0051, 0x0011, 0x0000,
0x0000, 0x3B36, 0x3B34, 0x3B1F, 0x3B32, 0x3B1E, 0x3B2A, 0x3B29, 0x3924, 0x3926, 0x394C, 0x3931, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
};
byte ps2_kc_ex[] =
{
0x4A,
0x70, 0x6c, 0x7d, 0x71, 0x69, 0x7a,
0x75, 0x6b, 0x74, 0x72,
0x1F, 0x27,
};
byte send_kch_ex[] =
{
'/',
155, 36 , 19 , 127, 35 , 34 ,
82 , 80 , 79 , 81 ,
0 , 0 ,
};
word send_kc_ex[] =
{
0x004C,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0013, 0x0015, 0x0016, 0x001C,
0x0000, 0x0000,
};
void kbd_init()
{
char ack;
kbd.write(0xff); // send reset code
ack = kbd.read(); // byte, kbd does self test
ack = kbd.read(); // another ack when self test is done
kcLength=sizeof(ps2_kc);
kcExLength=sizeof(ps2_kc_ex);
}
void setup()
{
// Serial setup
#ifdef DEBUG
Serial.begin(USB_BAUD);
Serial.flush();
Serial.println("Bimeji Client");
#endif
// Bluetooth側 Serial setup
#ifdef NewSoftSerial_h
BTSerial.begin(BT_BAUD);
BTSerial.flush();
#endif
#ifdef Ethernet_h
Ethernet.begin(mac, ip);
client.connect();
#endif
kbd_init();
#ifdef DEBUG
Serial.println("---Table Size---");
Serial.print("KeyCode=");
Serial.println(sizeof(ps2_kc), DEC);
Serial.print("KeyCodeEx=");
Serial.println(sizeof(ps2_kc_ex), DEC);
Serial.println("---Start---");
#endif
}
void loop()
{
unsigned char code;
boolean release;
boolean ext;
boolean shift;
shift=false;
for (;;)
{
ext=false;
release=false;
code = kbd.read();
if(code==0xE0)
{
ext=true;
code = kbd.read();
}
if(code==0xF0)
{
release=true;
code = kbd.read();
}
if(ext)
{
if(code==0x11 || code==0x14 || code==0x4A || code==0x5A) ext=false;
}
// Shift
if(code==0x12 || code==0x59)
{
shift=(release)?false:true;
continue;
}
#ifdef DEBUG
if(release) Serial.print("OnKeyUp ");
else Serial.print("OnKeyDown ");
Serial.print("0x");
Serial.print(code, HEX);
if(ext) Serial.print("(ex)");
if(shift) Serial.print("+shift");
#endif
int i=0;
if(!ext && !release)
{
for(i=0;i<kcLength;i++)
{
if(code==ps2_kc[i]) break;
}
if(i<kcLength)
{
if(!shift)
{
SendKeyCodeET(send_kc[i]);
SendKeyCodeBT(send_kch[i]);
}
else
{
SendKeyCodeET(send_kc_s[i]);
SendKeyCodeBT(send_kch_s[i]);
}
}
}
else if(ext && !release)
{
for(i=0;i<kcExLength;i++)
{
if(code==ps2_kc_ex[i]) break;
}
if(i<kcExLength)
{
if(!shift)
{
SendKeyCodeET(send_kc_ex[i]);
SendKeyCodeBT(send_kch_ex[i]);
}
}
}
#ifdef DEBUG
Serial.println("");
#endif
}
}
void SendKeyCodeET(word code)
{
#ifdef Ethernet_h
byte c;
c=(code>>8)&0xFF;
if(c)
{
client.write((byte)0x00);
client.write((byte)0x00);
client.write((byte)0x00);
client.write(c);
}
c=code&0xFF;
if(c)
{
client.write((byte)0x00);
client.write((byte)0x00);
client.write((byte)0x00);
client.write(c);
}
#endif
}
void SendKeyCodeBT(byte ch)
{
#ifdef NewSoftSerial_h
if(ch)
{
BTSerial.print(ch);
}
#endif
}
このソースでは、PS2ライブラリとNewSoftSerialライブラリを利用しています。
コンパイルするには、これらのライブラリを有効にしておく必要があります。
使い方
Simeji
今まで別プロジェクト扱いだったbimeji/wimejiが、最新版のsimejiからはintentで文字コードを受け付けるBroadcastReceiverが正式採用されたようです。 今まで野良アプリをインストールする必要がありましたが、アンドロイドマーケットにアップされているsimejiで対応されたので便利です。
simejiの設定画面で【外部接続】にチェックを入れておきます。
Bimeji SPP版
今回の自作ハードウェアキーボードとsimejiを繋いでくれるアプリが、bimeji SPP版です。
bluetoothから受け取った文字コードを、intentとしてsimejiに投げてくれるアプリです。
esmasuiさんのページ(BT接続できるSimeji)で公開されています。
apkファイルをダウンロード・インストールします。
起動してconnectで、接続します。
bimejiでconnectが出来れば、入力可能な状態になっています。
最後に
誰が使うでも無いニッチで馬鹿高いデバイスが出来上がりました。
しかし、「アンドロイドでこんなことが出来る」と言う実験が出来たことは、無駄では無かったと思っています。
実際にこのデバイスを使ってキーボード入力するには、もう少し作り込みが必要な感じです。
必要な人がいれば、ここで公開しているソースは自由にして頂いて結構です。
Category: Androidと電子工作
TrackBack URL :






こんにちは。
製品にしていただければ、非常にありがたいです。
゜(-m-)パンパン
コメントありがとうございます
製品化は難しいですねぇ・・・色々と・・・
Android 2.x の端末なら、HIDプロファイルのBluetoothキーボードが使えるそうなので、そちらを検討されては如何でしょうか?
こんばんは。
やはり無理ですか(8_8) 。
Android 2.x の端末で使えるようになるのは確かな情報でしょうか?
今、私が持っているHT-03Aでは、この先使えるようにならないと言うことですかね(T△T) そんなぁ…
androidの開発ができればFutabaさんのように試してみるのですが。。。
羨ましい限りです。
こんばんは
このBimeji client for arduinoで利用している esmasuiさんのBimeji SPP版は、他にBimeji HID版も公開されています。
BimejiHID版は、Android 2.x以降対応だそうです。
僕自身で試してはいませんが、確かな情報です。
詳しくは氏のブログをご覧下さい。
http://d.hatena.ne.jp/esmasui/20100112/1263247514
後、こちらも試した訳ではありませんが、海外製アプリでSPPキーボードに対応したKeyProと言うアプリもあるようです。
こちらはAndroid 1.5以降対応だったと思います。
キーボードとアプリで値が張りますが、自作するよりは安いです・・・
http://jp.androlib.com/android.application.com-mymobilegear-pjqz.aspx
( ^ ^ )/ こんにちは
情報ありがとうございます。
申告で忙しくて見ることが出来ませんでした。
日頃サボっているのでだめですね~!
教えてもらったサイトを確認してみます。
ありがとうございましたm(__)m 。