LoginSignup
4
1

More than 5 years have passed since last update.

arduino microで頭部装着するHIDデバイス(マウス)を作ったので備忘録

Last updated at Posted at 2019-04-07

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出力につないでも問題ない模様.

どうすればHIDデバイスとして使える?

スクリーンショット (53).png

↑のスクショにあるライブラリをArduino IDEにイントールする.その後,基本的には以下のコードでArduinoがHIDマウスになります.

mouse.c
#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を参照されたし.

最終的なコード

HIDmouse.c
#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互換ボードだと超小型のものもあるので,後々小型化していく予定.

4
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1