#Arduino Microで頭部装着するHIDデバイス(マウス)を作ったので備忘録
###なんでそんなもん作ったか
とある事情で頭部装着ポインティングデバイスを作ってます.これまた諸事情あって,加速度センサから割り出した頭部傾きを使ってカーソルを動かしています.
###Arduino Microについて
サクッと使えて便利なArduinoですが,その中でもArduino Micro, Arduino Leonardo等(ATmega32U4搭載)のものはHIDデバイスとしてそのまま使えちゃう便利な機能がついています.
なので,自作キーボードや自作マウスが作れたりしちゃいます.
###今回使ったセンサ・マイコン
MPU-6050 (6軸ジャイロ加速度センサ)
Arduino Micro
を今回は使用しています.
つなぎ方は(センサ)-(マイコン)間で
(VCC)-(3.3V)
(GND)-(GND)
(SCL)-(SCL)
(SDA)-(SDA)
でつなぐだけです.どうやら僕が使ったMPU-6050にはレギュレータなるものが入っているらしく,直接5V出力につないでも問題ない模様.
↑のスクショにあるライブラリをArduino IDEにイントールする.その後,基本的には以下のコードでArduinoがHIDマウスになります.
#include <Mouse.h>
int xval; //x軸方向の相対移動量
int yval; //y軸方向の相対移動量
const int wheelVal = 0; //スクロールホイールの移動量
void setup(){
Mouse.begin();
}
void loop(){
//xval = hoge1 センサから上がってきた何らかの値を代入
//yval = hoge2 センサから上がってきた何らかの値を代入
Mouse.move(xval, yval, wheelVal);
}
他にもクリックなども実装できます.詳しくはArduino公式referenceを参照されたし.
###最終的なコード
#include <Mouse.h>
#include <Wire.h>
int16_t axRaw, ayRaw, azRaw, gxRaw, gyRaw, gzRaw;
const float kx=0.2; //gain for x
const float ky=0.2; //gain for y
int move_x; //relative distance to move along X-axis
int move_y; //relative distance to move along Y-axis
float acc_x, acc_y, acc_z
float acc_angX, acc_angY;
void setup(){
Wire.begin();
Wire.beginTransmission(0x68);
Wire.write(0x6B);
Wire.write(0X00);
Wire.endTransmission();
Wire.beginTransmission(0x68);
Wire.write(0x1C);
Wire.write(0x10);
Wire.endTransmission();
Wire.beginTransmission(0x68);
Wire.write(0x1B);
Wire.write(0x08);
Wire.endTransmission();
Wire.beginTransmission(0x68);
Wire.write(0x1A);
Wire.write(0x05);
Wire.endTransmission();
Mouse.begin();
}
void loop(){
Wire.beginTransmission(0x68);
Wire.write(0x3B);
Wire.endTransmission();
Wire.requestFrom(0x68, 14);
while (Wire.available() < 14);
axRaw = Wire.read() << 8 | Wire.read();
ayRaw = Wire.read() << 8 | Wire.read();
azRaw = Wire.read() << 8 | Wire.read();
acc_x = axRaw / 16384.0;
acc_y = ayRaw / 16384.0;
acc_z = azRaw / 16384.0;
acc_angX = atan2(acc_y, -acc_x) * 360 / 2.0 / PI;
acc_angY = atan2(acc_z, -acc_x) * 360 / 2.0 / PI;
//ここはセンサを縦置きにしているので引数の順序が変わってます.
//以下センサを水平において使う場合
//acc_angX = atan2(acc_x, acc_z) * 360 / 2.0 / PI;
//acc_angY = atan2(acc_y, acc_z) * 360 / 2.0 / PI;
move_x = (int) (kx*acc_angX);
move_y = (int) (ky*acc_angY);
Mouse.move(move_x, move_y, wheelVal);
//move()にはint型にキャストした座標を渡します
}
これでセンサから上がってきた値から角度を割り出し,それをカーソル速度に反映できます.
###補足(というか教えてえらい人)
1.ジャイロセンサから上がってきた角速度を積分してz軸回転(ヨー軸回転)を出したいんですが無理なんですかね.カルマンフィルタのライブラリ等もあるっぽいですが,ヨー軸回転は出せなさそうだったので...
2.arduino leonardo互換ボードだと超小型のものもあるので,後々小型化していく予定.