今回はロボットでは基本中の基本、モーター関連のことを教えていきます。
ただ、僕も使っていないAPIがあるので、それについては紹介できません。
でも安心してください。基本動作はできるようになります!!
以下はモーター関連のAPIです。これも参考にしながら見てください。
EV3RT C API Reference サーボモータ
#①使うモーターをコンフィグする#
前回もお伝えしましたが、モーターを使うには宣言をして置かなければなりません。
ここではモーターAとDにLモーターを繋ぐことにします。
#include "ev3api.h" //絶対必要
#include "app.h"//絶対必要
#include <stdio.h>
#include <stdbool.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
void main_task(intptr_t unused)
{
/* コンフィグゾーン */
ev3_motor_config (EV3_PORT_A, LARGE_MOTOR);
ev3_motor_config (EV3_PORT_D, LARGE_MOTOR);
これでモーターが使えるようになります。
ポートとの接続は
もしくは
つまり
ポート | 列挙型① | 列挙型② |
---|---|---|
A | EV3_PORT_A | 0 |
B | EV3_PORT_B | 1 |
C | EV3_PORT_C | 2 |
D | EV3_PORT_D | 3 |
という風にプログラムします。 |
#②モーターを動かしてみる#
さて、いよいよ動かしていきます。
といっても、EV3には様々な命令方法がありますので、教育用ソフトウェアと比較して見ていきたいと思います。
##モーターON##
教育用ソフトウェアだと↓のコマンド
EV3rtだと…
void main_task(intptr_t unused)
{
/* コンフィグゾーン */
ev3_motor_config (EV3_PORT_A, LARGE_MOTOR);
ev3_motor_config (EV3_PORT_D, LARGE_MOTOR);
ev3_motor_set_power(EV3_PORT_A,50);
ev3_motor_set_power(EV3_PORT_D,50);
}
ただし、この命令はストップ命令を掛けない限り永遠に動き続けます。
ということで次は、
##モーターOFF##
教育用ソフトウェアだと↓のコマンド
EV3rtだと…
void main_task(intptr_t unused)
{
/* コンフィグゾーン */
ev3_motor_config (EV3_PORT_A, LARGE_MOTOR);
ev3_motor_config (EV3_PORT_D, LARGE_MOTOR);
ev3_motor_stop(EV3_PORT_A, true);//Aで即時停止
ev3_motor_stop(EV3_PORT_D, true);//Dで即時停止
ev3_motor_stop(EV3_PORT_A, false);//Aで惰性減速
ev3_motor_stop(EV3_PORT_D, false);//Dで惰性減速
}
こんな感じです。
さて、基本的にはこれだけで作業できますが、他にもいくつかあるので紹介しておきましょう。
#③回転角を取得する#
void main_task(intptr_t unused)
{
/* コンフィグゾーン */
ev3_motor_config (EV3_PORT_A, LARGE_MOTOR);
ev3_motor_config (EV3_PORT_D, LARGE_MOTOR);
int MotorAcount=ev3_motor_get_count(EV3_PORT_A);
int MotorDcount=ev3_motor_get_count(EV3_PORT_D);
}
この例では変数MotorAcountとMotorDcountにAとDの回転角を代入します。
これを使うと何ができるか?
教育用ソフトウェアでいう↓のようなことができるようになります。
角度を指定して動く事ができるのです。下に例を提示しておきます。
void main_task(intptr_t unused)
{
/* コンフィグゾーン */
ev3_motor_config (EV3_PORT_A, LARGE_MOTOR);
ev3_motor_config (EV3_PORT_D, LARGE_MOTOR);
ev3_motor_reset_counts(L_motorA);//回転角のリセット
while (360>ev3_motor_get_counts(EV3_PORT_A)) {
ev3_motor_set_power(EV3_PORT_A,50);
ev3_motor_set_power(EV3_PORT_D,50);
}
ev3_motor_stop(EV3_PORT_A, true);//Aで即時停止
ev3_motor_stop(EV3_PORT_D, true);//Dで即時停止
}
こんな風にすることで簡単に指定角文動かすことができます!!
さらに!!「C言語コンパイルが可能なんただったら、関数化してしまえばいいじゃないか」ということで、私は下の関数をめちゃくちゃ使ってプログラミングしました。よかったら参考にしてみてください。
#④関数化してプログラムを効率化#
void main_task(intptr_t unused)
{
/* コンフィグゾーン */
ev3_motor_config (EV3_PORT_A, LARGE_MOTOR);
ev3_motor_config (EV3_PORT_D, LARGE_MOTOR);
func_motor(50,50,360);
func_motor_stop();
}
void func_motor(double a,double d,double dis);//aとdはパワーレベル・disは角度の指定
void func_motor(double a,double d,double dis)
{
ev3_motor_reset_counts(EV3_PORT_A);
if (a>0) {//パワーが正か負かで場合分け
while (dis>ev3_motor_get_counts(EV3_PORT_A)) {
ev3_motor_set_power(EV3_PORT_A,a);
ev3_motor_set_power(EV3_PORT_D,d);
}
}
else if(a<0){
while (dis>-(ev3_motor_get_counts(EV3_PORT_A))) {
ev3_motor_set_power(EV3_PORT_A,a);
ev3_motor_set_power(EV3_PORT_D,d);
}
}
}
void func_motor_A(double a,double dis);
void func_motor_A(double a,double dis)
{
ev3_motor_reset_counts(EV3_PORT_A);
if (a>0) {
while (dis>ev3_motor_get_counts(EV3_PORT_A)) {
ev3_motor_set_power(EV3_PORT_A,a);
}
}
else if(a<0)
{
while (dis>-(ev3_motor_get_counts(EV3_PORT_A))) {
ev3_motor_set_power(EV3_PORT_A,a);
}
}
}
void func_motor_B(double a,double dis);
void func_motor_B(double a,double dis)
{
ev3_motor_reset_counts(EV3_PORT_B);
if (a>0) {
while (dis>ev3_motor_get_counts(EV3_PORT_B)) {
ev3_motor_set_power(EV3_PORT_B,a);
}
}
else if(a<0)
{
while (dis>-(ev3_motor_get_counts(EV3_PORT_B))) {
ev3_motor_set_power(EV3_PORT_B,a);
}
}
}
void func_motor_C(double a,double dis);
void func_motor_C(double a,double dis)
{
ev3_motor_reset_counts(EV3_PORT_C);
if (a>0) {
while (dis>ev3_motor_get_counts(EV3_PORT_C)) {
ev3_motor_set_power(EV3_PORT_C,a);
}
}
else if(a<0)
{
while (dis>-(ev3_motor_get_counts(EV3_PORT_C))) {
ev3_motor_set_power(EV3_PORT_C,a);
}
}
}
void func_motor_D(double a,double dis);
void func_motor_D(double a,double dis)
{
ev3_motor_reset_counts(EV3_PORT_D);
if (a>0) {
while (dis>ev3_motor_get_counts(EV3_PORT_D)) {
ev3_motor_set_power(EV3_PORT_D,a);
}
}
else if(a<0)
{
while (dis>-(ev3_motor_get_counts(EV3_PORT_D))) {
ev3_motor_set_power(EV3_PORT_D,a);
}
}
}
void func_motor_stop();
void func_motor_stop()
{
ev3_motor_stop(EV3_PORT_A, true);
ev3_motor_stop(EV3_PORT_B, true);
ev3_motor_stop(EV3_PORT_C, true);
ev3_motor_stop(EV3_PORT_D, true);
}
void func_motor_sleep();
void func_motor_sleep()
{
ev3_motor_stop(EV3_PORT_A, false);
ev3_motor_stop(EV3_PORT_B, false);
ev3_motor_stop(EV3_PORT_C, false);
ev3_motor_stop(EV3_PORT_D, false);
}
#まとめ#
今回はモーター関連のAPIを紹介しました。
また、今回以下の4つは紹介していません。
ev3_motor_get_type (motor_port_t port)
ev3_motor_get_power (motor_port_t port)
ev3_motor_rotate (motor_port_t port, int degrees, uint32_t speed_abs, bool_t blocking)
ev3_motor_steer (motor_port_t left_motor, motor_port_t right_motor, int power, int turn_ratio)
紹介しなかった理由としては大きく2つあります。
1つは使う機会がかなり限られているということ(特に上2つ)
もう1つは私自身使い方がイマイチわからないということ(特に下2つ)
ということで、これら4つを使いたい方は自分で使い方を調べてください。今回紹介した他のAPIとノリは同じなので、リファレンスを見ればだいたいわかります。また機会があれば紹介したいと思います。