2014年5月10日土曜日

自作Arduinoライブラリ

今回は、Arduinoのライブラリを書いてみました回です。
ステッピングモータの回で作ったスケッチを簡単に使えたらよいなあという感じでやってみました。ユニポーラ駆動用です。



必要なファイル

ライブラリのフォルダには以下の3つのファイルが必要です。
ソースファイル
ヘッダーファイル
キーワードファイル

フォルダー名とソースファイル名は一致してなくても動くことは確認したのですが、ややこしくなってしまいそうなので同じにしました。ちなみに既に「Stepper」というライブラリがあるので、名前は「MyStepper」にしました。


ソースファイル

Arduino の標準関数を使うためのarduino.hですが、これはArduinoIDEバージョン1.0.1あたり以降からWProgram.hじゃできない的なお馴染みのアレですね。

まず最初にコンストラクタ、というクラスをインスタンス化したときに呼び出される関数を定義します。クラス内の関数や変数を使うためにはインスタンスというものを作らないといけないのですが、その時に呼び出されるのでpinModeとかを設定しておきます。コンストラクタの名前はクラス名と同じにしないといけないことに注意です。

クラスではメンバと呼ばれる変数や関数をもつことができて、後はそれを書いていきます。
MyStepper.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "arduino.h"
#include "MyStepper.h"
 
Motor::Motor(int X1,int Y1,int X2,int Y2)
{
    pinMode(X1,OUTPUT);
    pinMode(Y1,OUTPUT);
    pinMode(X2,OUTPUT);
    pinMode(Y2,OUTPUT);
    pin[0] = X1;
    pin[1] = Y1;
    pin[2] = X2;
    pin[3] = Y2;
}
 
void Motor::cw1(int rotation,int interval)//1相励磁 時計回り
{
    for(int c=0; c<rotation; c++)
    {
        for(int i=0; i<4; i++)
        {
            int prev = i-1;
            if(prev == -1) prev = 3;
            digitalWrite(pin[prev], LOW);
            digitalWrite(pin[i], HIGH);
            delay(interval);
        }
    }
}
void Motor::ccw1(int rotation,int interval)//1相励磁 反時計回り
{
    for(int c=0; c<rotation; c++)
    {
        for(int i=3; i>-1; i--)
        {
            int prev = i+1;
            if(prev == 4) prev = 0;
            digitalWrite(pin[prev], LOW);
            digitalWrite(pin[i], HIGH);
            delay(interval);
        }
    }
}
void Motor::cw2(int rotation,int interval)//2相励磁 時計回り
{
    for(int c=0; c<rotation; c++)
    {
        for(int i=0; i<4; i++)
        {
            int prev = i-1;
            int next = i+1;
            if(prev == -1) prev = 3;
            if(next == 4) next = 0;
            digitalWrite(pin[prev], LOW);
            digitalWrite(pin[i], HIGH);
            digitalWrite(pin[next], HIGH);
            delay(interval);
        }
    }
}
void Motor::ccw2(int rotation,int interval)//2相励磁 反時計回り
{
    for(int c=0; c<rotation; c++)
    {
        for(int i=3; i>-1; i--)
        {
            int prev = i+1;
            int next = i-1;
            if(prev == 4) prev = 0;
            if(next == -1) next = 3;
            digitalWrite(pin[prev], LOW);
            digitalWrite(pin[i], HIGH);
            digitalWrite(pin[next], HIGH);
            delay(interval);
        }
    }
}
void Motor::cw1_2(int rotation,int interval)//1-2相励磁 時計回り
{
    for(int c=0; c<rotation; c++)
    {
        for(int i=0; i<4; i++)
        {
            int prev = i-1;
            int next = i+1;
            if(prev == -1) prev = 3;
            if(next == 4) next = 0;
            digitalWrite(pin[prev], LOW);
            digitalWrite(pin[i], HIGH);
            digitalWrite(pin[next], LOW);
            delay(interval);
            digitalWrite(pin[next], HIGH);
            delay(interval);
        }
    }
}
void Motor::ccw1_2(int rotation,int interval)//1-2相励磁 反時計回り
{
    for(int c=0; c<rotation; c++)
    {
        for(int i=3; i>-1; i--)
        {
            int prev = i+1;
            int next = i-1;
            if(prev == 4) prev = 0;
            if(next == -1) next = 3;
            digitalWrite(pin[prev], LOW);
            digitalWrite(pin[i], HIGH);
            digitalWrite(pin[next], LOW);
            delay(interval);
            digitalWrite(pin[next], HIGH);
            delay(interval);
        }
    }
}


ヘッダーファイル

クラスのメンバには"public"と"private"の二つの属性があって、"public"は公開されたメンバで、外部からアクセスする必要があるもの、"private"は非公開でクラス内だけで参照可能で、外部からはアクセスする必要がないメソッドや変数を定義しています。

#ifndef ~ #endifはこのヘッダーが何度インクルードされても定義が重複しないようにしているらしいのですが、詳しくはこちらで(よくわかってない顔)。セミコロンを忘れずに。
MyStepper.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef MyStepper_H_
#define MyStepper_H_
#include "arduino.h"
 
class Motor
{
public:
    Motor(int X1,int Y1,int X2,int Y2);
    void cw1(int rotation,int interval);
    void ccw1(int rotation,int interval);
    void cw2(int rotation,int interval);
    void ccw2(int rotation,int interval);
    void cw1_2(int rotation,int interval);
    void ccw1_2(int rotation,int interval);
private:
    int pin[4];
};
#endif


キーワードファイル

これは必須ではないのですが、IDE上でKEYWORD1がオレンジでKEYWORD2が茶色で指定した文字に色が付きます。間はTabで空けるようです。
keywords.txt
1
2
3
4
5
6
7
8
MyStepper KEYWORD1
Motor KEYWORD2
cw1 KEYWORD2
ccw1 KEYWORD2
cw2 KEYWORD2
ccw2 KEYWORD2
cw1_2 KEYWORD2
ccw1_2 KEYWORD2


実際に使う

完成したフォルダは、\Arduino\arduino-1.5.4\librariesにコピーします。これは自分の例ですがとにかく「libraries」の中に入れます。

その後は他のライブラリを使うのと同様にしてインクルードすればおkです。

以下のスケッチは10~13pinを使って(パルスを送る順番通りに繋ぐ)1相励磁で180度回転、1秒置いて今度は1-2相励磁で180度逆回転するものとなっています。各関数で渡す数字は、一つ目がステップ数で1ごとに4ステップします。(ステップ角が1.8度のものは1.8×4×25=180度回転)ただし1-2相励磁の関数は1ごとに8ステップするので、この場合結果的に同じく180度になります。二つ目の数字はパルスを送る間隔で単位は[ms]です。

 



かなりスケッチがすっきりしていい感じですね!
角度を渡すとその角度分回るとかいろいろ改良していきます。

参考にしたサイト
自作ライブラリの作り方
74HC595 シフトレジスタの操作をライブラリに

0 件のコメント:

コメントを投稿