Help us understand the problem. What is going on with this article?

mbedを用いたUSBエアマウスの作成

More than 3 years have passed since last update.

はじめに

この記事では、mbedを使ってUSBエアマウスの簡単なプロトタイプを作成する方法を説明します。

mbedとは

mbedとは、mbed対応ボード(ARM Cortex-Mベース)のための開発フレームワークのことです。オンラインIDE、OS、mbed対応ボードなどを含めたエコシステム全体のことをmbedと呼びます。mbedを使うことで、プロトタイプ開発を迅速に進めることができます。詳細については、公式ページなどを参照してください。

作成したUSBエアマウスの使い方

以下に、作成したUSBエアマウスの使い方を説明します。

マウスカーソルの水平移動

ボードを横方向に傾けると水平方向にマウスカーソルが移動します。また、傾きを検出している間は、LEDが青色に点灯します。

mouse_move_horizontal.gif

マウスカーソルの垂直移動

ボードを縦方向に傾けると垂直方向にマウスカーソルが移動します。傾きを検出している間は、LEDが青色に点灯します。

mouse_move_vertical.gif

マウスの右クリック

タッチセンサの右半分をタッチすることで、マウスの右クリックができます。同時にLEDが緑色に点灯します。

mouse_right_click.gif

マウスの左クリック

タッチセンサの左半分をタッチすることで、マウスの左クリックができます。同時にLEDが赤色に点灯します。

mouse_left_click.gif

USBエアマウスの作成方法

USBエアマウスは、以下の流れで作成しました。

  1. FRDM-KL25Zのファームウェアの更新
  2. 必要なライブラリのインポート
  3. コーディング
  4. コンパイル

FRDM-KL25Z

今回は、mbed対応ボードとして、FRDM-KL25Zを採用しました。FRDM-KL25Zは、以下のような機能を備えています。

  • ARM Cortex-M0+
  • 3軸加速度センサ
  • 静電容量タッチセンサ

mbed FRDM KL25Z 諸元
https://os.mbed.com/users/okini3939/notebook/mbed_frdm_kl25z_jp/

ファームウェアの更新

FRDM-KL25Z上でmbedを使うために、ファームウェアを更新する必要があります。更新方法については、以下のWebページなど参照してください。

mbed FRDM KL25Z ゲッティングスターテッド
https://os.mbed.com/users/Norisuke/notebook/mbed-frdm-kl25z-Getting-started-jp/

コーディング

続いて、mbedのオンラインIDE上でC/C++を使って実装を行っていきます。

mbedのオンラインIDEの使い方

mbedのオンラインIDEの使い方については、以下のWebページなどを参照してください。

mbed入門
https://os.mbed.com/users/RyoheiHagimoto/notebook/mbed_introduction/

ライブラリのインポート

今回は以下の3つのライブラリを使いました。

  1. USBMouse
  2. タッチセンサ(Touch Sensor)
  3. 加速度センサ(Accelerometer)

それぞれのWebページで「Import program」のボタンをクリックします。

import_program.png

インポートする際は、Libraryとしてインポートしてください。

import_library.png

ライブラリとしてインポートした場合、ライブラリ内のmain.cppは不要ですので削除してください。

コード

今回実装したコードは以下のとおりです。main.cppに以下のコードを記述してください。

main.cpp
#include "mbed.h"
#include "MMA8451Q.h"
#include "TSISensor.h"
#include "USBMouse.h"

class LED {
public:
    LED() : _rled(LED_RED), 
            _gled(LED_GREEN), 
            _bled(LED_BLUE) {}

    void turnOn(PinName pin) {
        turnOffAll();
        if (pin == LED_RED) {
            _rled = 0;
            _timeout_rled.attach(this, &LED::turnOffAll, 0.01);
        } else if (pin == LED_GREEN) {
            _gled = 0;
            _timeout_gled.attach(this, &LED::turnOffAll, 0.01);
        } else {
            _bled = 0;
            _timeout_bled.attach(this, &LED::turnOffAll, 0.01);
        }
    }

private:
    DigitalOut _rled;
    DigitalOut _gled;
    DigitalOut _bled;

    Timeout _timeout_rled;
    Timeout _timeout_gled;
    Timeout _timeout_bled;

    void turnOffAll(void) {
        _rled = 1;
        _gled = 1;
        _bled = 1;
    }
};

class TouchSensor {
public:
    TouchSensor() {}

    bool isLeftClick(void) {
        float tsi_val = _tsi.readPercentage();
        return tsi_val > 0.0 && tsi_val < 0.5;
    }

    bool isRightClick(void) {
        float tsi_val = _tsi.readPercentage();
        return tsi_val >= 0.5 && tsi_val < 1.0;
    }

private:
    TSISensor _tsi;
};

class Accelerometer {
public:
    Accelerometer() : _acc(PTE25, PTE24, MMA8451_I2C_ADDRESS) {}

    int getMouseCursorXDist(void) {
        return (int)(10.0 * _acc.getAccY());
    }

    int getMouseCursorYDist(void) {
        return (int)(10.0 * _acc.getAccX());
    }

    bool isMouseCursorMoved(void) {
        return getMouseCursorXDist() != 0 || getMouseCursorYDist() != 0;
    }            

private:
    static const int MMA8451_I2C_ADDRESS = 0x1d << 1;
    MMA8451Q _acc;
};

class Mouse {
public:              
    Mouse() {}

    void handle(void) {
        while (true) {
            handleClick();
            handleMove();
            wait(0.01);
        }
    }

private:
    LED _led;
    USBMouse _mouse;
    TouchSensor _ts;
    Accelerometer _acc;

    void handleClick(void) {        
        if (_ts.isLeftClick()) {
            _mouse.click(MOUSE_LEFT);
            _led.turnOn(LED_RED);
        } else if (_ts.isRightClick()) {
            _mouse.click(MOUSE_RIGHT);
            _led.turnOn(LED_GREEN);
        }
    }

    void handleMove(void) {
        if (_acc.isMouseCursorMoved()) {
            _mouse.move(_acc.getMouseCursorXDist(), _acc.getMouseCursorYDist());
            _led.turnOn(LED_BLUE);
        }
    }
};

int main(void) {
    Mouse mouse;
    mouse.handle();    
}

コンパイル

以下の画像のとおり、FRDM-KL25Zにある2つのUSBのうち、「OpenSDA」の方にUSBケーブルを接続すると、「MBED」という名前のUSBメモリとして認識されます。

openSDA.png

続いて、オンラインIDE上で「コンパイル」ボタンをクリックすると、.binファイルが作成されるので、それを先ほどの「MBED」にコピーしてください。自動的に.binファイルがインストールされます。

USBエアマウスとして使用する

USBエアマウスとして使用する場合は、以下の画像のとおり、2つのUSBのうち、「KL25Z USB」の方にUSBケーブルを接続します。

KL25Z_USB.png

補足)
Windows、Macの双方でUSBエアマウスとして使用することができます。

参考文献

ほとんどコピペで作るコピペ専用USBデバイス
http://www.dm9records.com/index.php/tips/elec/mbedadvent2014/

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした