TOPPERS/EV3RTでEV3のモーターを回してみる

TOPPERS/EV3RT環境でC言語をを用いてEV3のモーターを回してみます。
[環境開発の記事はこちら](http://qiita.com/tkzw102/items/93dd959cccf2efc8d4a6)
#モーターの接続

![conect-motor.png](https://qiita-image-store.s3.amazonaws.com/0/152243/21f14eaa-aee1-8eef-9ed9-4c78c58bc36e.png)


上の画像のように接続しました。今回はポートAに**Lモーター**、ポートDに**Mモーター**を接続しました。それぞれのモーターの特性は以下の通りになります。

EV3 Lモーター...パワフル。しかし細かい動きは得意ではなく、回転数は低め。画像の赤い部分が回る。

EV3 Mモーター...精度が良く高回転。しかし、Lモーターよりパワーが低いので、あまり負荷はかけられない。画像には映ってないが、ケーブルコネクタの反対側の面に穴があり、そこが回る。

![Mmotor.jpg](https://qiita-image-store.s3.amazonaws.com/0/152243/155d05f3-a22a-39af-79ef-0fe8e13e1385.jpeg)

Mモーターはこんなふうにしてあげると回ったときわかりやすいです。

共通事項...1°単位で角度指定ができる。(サーボモーターってことですね)また、EV3ソフトウェアで利用可能である。


今回はこの二つのモーターを動かすところまでやりたいと思います。

#EV3APIについて
アプリを開発するうえで、モーター、センサー等EV3独自の機能をサポートするC言語のAPIが必須になります。詳しくは[EV3RT C言語APIリファレンス](http://www.toppers.jp/ev3pf/EV3RT_C_API_Reference/index.html)を参照してください。
今回はこのAPIの機能のうち、モーターに関する機能を使用します。

このAPIのおかげで、デバイスを動かすうえで必要なことが関数を呼び出すだけになるのでとっても便利です。

#アプリケーションの新規作成

まずCygwinを起動し、C:/cygwin64/hrp2/sdk/workspaceまで移動します。
移動が完了したら、`$ cp -r (コピー元のアプリケーションのフォルダ名) (新規に作成したいアプリケーションのフォルダ名)`というコマンドを入力します。こうすることで、中身がコピー元と全く同じで別な名前のフォルダが作成されます。
今回は、"test-cyc"をもとに、"motor-test"というアプリケーションを作っていきたいと思います。(フォルダの作成までは以下の画像を参考にしてください)
<img width="455" alt="cpapp.png" src="https://qiita-image-store.s3.amazonaws.com/0/152243/6ee91494-488c-a618-2dcb-45f08b7da007.png">


aliasを使ってcdetというコマンドを作成し、これ一つでC:/cygwin64/hrp2/sdk/workspaceまで移動できるようにしておきました。

#ソースコードの編集

main.cの中身を以下のように書き換えます。

```C:main.c
#include "ev3api.h"
#include "app.h"

#if defined(BUILD_MODULE)
#include "module_cfg.h"
#else
#include "kernel_cfg.h"
#endif

#define DEBUG

#ifdef DEBUG
#define _debug(x) (x)
#else
#define _debug(x)
#endif

static const motor_port_t
    M_motor      = EV3_PORT_D,
    L_motor      = EV3_PORT_A;

void main_task(intptr_t unused)
{
	ev3_motor_config (L_motor, LARGE_MOTOR);
	ev3_motor_config (M_motor, MEDIUM_MOTOR);
    ev3_led_set_color(LED_ORANGE); 
    while(1)
    { 
		ev3_motor_set_power(L_motor,100);
		ev3_motor_set_power(M_motor,-100);
    }
    ev3_motor_stop(L_motor, false);
    ev3_motor_stop(M_motor, false);
    ext_tsk();
}

```

たったこれだけです。

#作成したappをEV3に転送して動かしてみる

<img width="768" alt="makeapp.png" src="https://qiita-image-store.s3.amazonaws.com/0/152243/334da0d6-64a3-a6dc-aed9-9d7143eea38c.png">

`make app=motor-test`でビルド、最後にエラーが出なければ成功です。
workspaceに作成されたappを、SDカードのev3rt/appsディレクトリにコピーします。


で、SDカードをEV3本体に差し込んでアプリを動かせばいいのですが・・・
アプリを起動した瞬間にモーターが勢いよく回り始めたのでびっくりしました・・・(汗)
このままでは危ないですね。

なので、中身を少し変更します。

```C:main.c
#include "ev3api.h"
#include "app.h"

#if defined(BUILD_MODULE)
#include "module_cfg.h"
#else
#include "kernel_cfg.h"
#endif

#define DEBUG

#ifdef DEBUG
#define _debug(x) (x)
#else
#define _debug(x)
#endif

/* モーターポートの設定 */
static const motor_port_t
    M_motor      = EV3_PORT_D,
    L_motor      = EV3_PORT_A;

/* メインタスク */
void main_task(intptr_t unused)
{
	/* ループに入ってしまう前にモーターとモーターポートを接続する */
	ev3_motor_config (L_motor, LARGE_MOTOR);
	ev3_motor_config (M_motor, MEDIUM_MOTOR);
    ev3_led_set_color(LED_ORANGE); 
    /* ループの中に入る */
    while(1)
    {   /* エンターボタンが押されているとき */
    	if(ev3_button_is_pressed(ENTER_BUTTON)){
    		/* Lモーターを最大パワーで回す */
			ev3_motor_set_power(L_motor,100);
			/* Mモーターを最大パワーで回す(こっちは逆方向) */
			ev3_motor_set_power(M_motor,-100);
		}else{ /* 押されていないとき */
            /* 双方のモーターを止める */
			ev3_motor_stop(L_motor, false);
			ev3_motor_stop(M_motor, false);
		}
    }
    /* それぞれのモータの停止 */
    ev3_motor_stop(L_motor, false);
    ev3_motor_stop(M_motor, false);
    /* タスク終了 */
    ext_tsk();
}

```

本体中央にあるエンターボタンを押し続けている間回転、という形に書き換えました。

今回はモーターを回しただけですが、使用しているモーターがサーボモーターということで、指定角度まで回してキープ、なんてこともできるみたいです。