【Arduino初級】機能をまとめてloopをスッキリ!関数の使い方を解説!
ロボットに色んな動きをさせたい!
そう思ってloopの中にたくさんプログラムを書くと、ごちゃごちゃしますよね。
プログラムがごちゃついてきた…と思ったら、関数の出番です。
関数を使うと、すっきりしたプログラムが書けます。
機能をひとまとめにして1行で書くことが出来るんです!
関数はArduinoだけでなく、いろんな言語に使われている仕組みです。
なのでプログラミングをする上では必須の知識です。
ぜひ、関数を使ってプログラムをスッキリ書けるようになりましょう!\(^o^)/
- 関数とは?
- 関数の作り方と使い方3パターン
- 引数なしの場合
- 引数1個の場合
- 引数2個の場合
この記事を読むことで関数の使い方が理解できますよ。
解説動画
今回の記事の解説動画はこちらです。
関数とは?
digitalWriteやdelayも関数なんです!
digitalWriteは、指定したピンからHIGHまたはLOWを出力する機能をまとめて1行で使えるようにした関数。
delayは、指定した時間待つという機能をまとめて1行で使えるようにした関数。
さらに見た目は全然違いますが、setupやloopも関数だったんです!!
みなさん無意識のうちにすでに関数を使っちゃってたので、怖がらなくて大丈夫そうですね^^
関数の作り方と使い方を3パターン解説!
関数の作り方にはいろいろあります。
今回は下記の3パターンを解説したいと思います!
- 引数なし→単純に指示をまとめて実行できるようにしたもの
- 引数1個→delayのように実行するときに数値を指定できるもの
- 引数2個→analogWriteのように指定できる数値が2個あるもの
※引数・・・関数を使うときに入れる数値
引数なし: 単純に指示をまとめて実行できるようにしたもの
まずは、関数の作り方を説明します。
今回作る関数は、これです。
シンプルに、ロボット(NR-02)を前進させる関数を作ります。
中身は、左右の車輪を正転させるだけですね^^
setup関数をマネして作ります。
新規作成で自動的にsetupとloop関数が出てきますよね?
下の図のように、オリジナルの関数は、setup関数の上に改行でスペースを作って書くのがオススメです!
形はsetup関数をマネしちゃいましょう^^
そして、下の図のように、中括弧{ }の間に前進させるためのプログラムを書けば、関数の出来上がりです!
関数を使うときは、関数の名前を書くだけでOK!
プログラムを上から実行しているときに、関数名にたどり着いたときに、その中身が実行されることになります!
下の図のようなイメージです!
それでは、定数や変数を作ったり、後退や右旋回、左旋回、ストップの関数も作った全文をココでお見せしますね!
ぜひ、マネして作ってみてください^^
1const int PIN_MOTOR_L_A = 6; //左モータA
2const int PIN_MOTOR_L_B = 9; //左モータB
3const int PIN_MOTOR_R_A = 5; //右モータA
4const int PIN_MOTOR_R_B = 3; //右モータB
5const int PIN_BUTTON = 8; //押しボタンスイッチ
6
7int Power = 0; //モータのパワー
8
9//前進
10void moveForward() {
11 Power = 160; //パワー設定
12 analogWrite(PIN_MOTOR_L_A, Power); //左A
13 analogWrite(PIN_MOTOR_L_B, 0); //左B
14 analogWrite(PIN_MOTOR_R_A, Power); //右A
15 analogWrite(PIN_MOTOR_R_B, 0); //右B
16}
17
18//後退
19void moveBackward() {
20 Power = 160; //パワー設定
21 analogWrite(PIN_MOTOR_L_A, 0); //左A
22 analogWrite(PIN_MOTOR_L_B, Power); //左B
23 analogWrite(PIN_MOTOR_R_A, 0); //右A
24 analogWrite(PIN_MOTOR_R_B, Power); //右B
25}
26
27//右旋回
28void turnRight() {
29 Power = 160; //パワー設定
30 analogWrite(PIN_MOTOR_L_A, Power); //左A
31 analogWrite(PIN_MOTOR_L_B, 0); //左B
32 analogWrite(PIN_MOTOR_R_A, 0); //右A
33 analogWrite(PIN_MOTOR_R_B, Power); //右B
34}
35
36//左旋回
37void turnLeft() {
38 Power = 160; //パワー設定
39 analogWrite(PIN_MOTOR_L_A, 0); //左A
40 analogWrite(PIN_MOTOR_L_B, Power); //左B
41 analogWrite(PIN_MOTOR_R_A, Power); //右A
42 analogWrite(PIN_MOTOR_R_B, 0); //右B
43}
44
45//ブレーキ
46void stopBreak() {
47 digitalWrite(PIN_MOTOR_L_A, LOW); //左A
48 digitalWrite(PIN_MOTOR_L_B, LOW); //左B
49 digitalWrite(PIN_MOTOR_R_A, LOW); //右A
50 digitalWrite(PIN_MOTOR_R_B, LOW); //右B
51}
52
53//フリー
54void stopFree() {
55 digitalWrite(PIN_MOTOR_L_A, HIGH); //左A
56 digitalWrite(PIN_MOTOR_L_B, HIGH); //左B
57 digitalWrite(PIN_MOTOR_R_A, HIGH); //右A
58 digitalWrite(PIN_MOTOR_R_B, HIGH); //右B
59}
60
61void setup() {
62 //ピンの出力(Output)or入力(Input)設定
63 pinMode(PIN_MOTOR_L_A, OUTPUT); //左モータA
64 pinMode(PIN_MOTOR_L_B, OUTPUT); //左モータB
65 pinMode(PIN_MOTOR_R_A, OUTPUT); //右モータA
66 pinMode(PIN_MOTOR_R_B, OUTPUT); //右モータB
67 pinMode(PIN_BUTTON, INPUT); //スイッチ
68
69 //スタートボタンを押されるのを待つ
70 while(digitalRead(PIN_BUTTON)==0);
71 delay(1000); //1秒待つ
72}
73
74void loop() {
75 moveForward(); //前進
76 delay(1000);
77 stopBreak(); //ブレーキ
78 delay(500);
79 moveBackward(); //後退
80 delay(1000);
81 stopBreak(); //ブレーキ
82 delay(500);
83 turnRight(); //右旋回
84 delay(1000);
85 stopBreak(); //ブレーキ
86 delay(500);
87 turnLeft(); //左旋回
88 delay(1000);
89 stopBreak(); //ブレーキ
90 delay(500);
91}
引数1個: delayのように実行するときに数値を指定できるもの
上で解説したプログラムのデメリットは、モータのパワーを変化させたいときにパワー別に関数を作成しなければならないことです。
値が違うだけの関数を複数作るのは面倒です。
そこで引数を1個使って値を都度指定できる関数を作ります。
作り方は意外と簡単で、関数名のすぐ後ろにある括弧()の中に変数を作るだけ!
そうすると、関数を使うときに、括弧の中に数値を入れられるようになります。
括弧の中に書いた数値は、括弧の中で作った変数に入るんです!!
例えば、下の図の場合。
powerに160が入って、analogWriteで160のパワーが出力されることになります。
関数名の後ろの括弧()の中に作った変数や、関数を使うときに入れた数値160のこと。
これが【引数】(ひきすう)です。
ちなみに、引数powerは、その関数の中(中括弧の外)だけで使うことができます。
それでは、引数を使って関数を作り直したプログラムを全文書いておきます!
これなら、場合によってパワーを変えたいときにも、臨機応変に数値を調整できますね^^
1const int PIN_MOTOR_L_A = 6; //左モータA
2const int PIN_MOTOR_L_B = 9; //左モータB
3const int PIN_MOTOR_R_A = 5; //右モータA
4const int PIN_MOTOR_R_B = 3; //右モータB
5const int PIN_BUTTON = 8; //押しボタンスイッチ
6
7//前進
8void moveForward(int power) {
9 analogWrite(PIN_MOTOR_L_A, power); //左A
10 analogWrite(PIN_MOTOR_L_B, 0); //左B
11 analogWrite(PIN_MOTOR_R_A, power); //右A
12 analogWrite(PIN_MOTOR_R_B, 0); //右B
13}
14
15//後退
16void moveBackward(int power) {
17 analogWrite(PIN_MOTOR_L_A, 0); //左A
18 analogWrite(PIN_MOTOR_L_B, power); //左B
19 analogWrite(PIN_MOTOR_R_A, 0); //右A
20 analogWrite(PIN_MOTOR_R_B, power); //右B
21}
22
23//右旋回
24void turnRight(int power) {
25 analogWrite(PIN_MOTOR_L_A, power); //左A
26 analogWrite(PIN_MOTOR_L_B, 0); //左B
27 analogWrite(PIN_MOTOR_R_A, 0); //右A
28 analogWrite(PIN_MOTOR_R_B, power); //右B
29}
30
31//左旋回
32void turnLeft(int power) {
33 analogWrite(PIN_MOTOR_L_A, 0); //左A
34 analogWrite(PIN_MOTOR_L_B, power); //左B
35 analogWrite(PIN_MOTOR_R_A, power); //右A
36 analogWrite(PIN_MOTOR_R_B, 0); //右B
37}
38
39//ブレーキ
40void stopBreak() {
41 digitalWrite(PIN_MOTOR_L_A, LOW); //左A
42 digitalWrite(PIN_MOTOR_L_B, LOW); //左B
43 digitalWrite(PIN_MOTOR_R_A, LOW); //右A
44 digitalWrite(PIN_MOTOR_R_B, LOW); //右B
45}
46
47//フリー
48void stopFree() {
49 digitalWrite(PIN_MOTOR_L_A, HIGH); //左A
50 digitalWrite(PIN_MOTOR_L_B, HIGH); //左B
51 digitalWrite(PIN_MOTOR_R_A, HIGH); //右A
52 digitalWrite(PIN_MOTOR_R_B, HIGH); //右B
53}
54
55void setup() {
56 //ピンの出力(Output)or入力(Input)設定
57 pinMode(PIN_MOTOR_L_A, OUTPUT); //左モータA
58 pinMode(PIN_MOTOR_L_B, OUTPUT); //左モータB
59 pinMode(PIN_MOTOR_R_A, OUTPUT); //右モータA
60 pinMode(PIN_MOTOR_R_B, OUTPUT); //右モータB
61 pinMode(PIN_BUTTON, INPUT); //スイッチ
62
63 //スタートボタンを押されるのを待つ
64 while(digitalRead(PIN_BUTTON)==0);
65 delay(1000); //1秒待つ
66}
67
68void loop() {
69 moveForward(160); //前進
70 delay(1000);
71 stopBreak(); //ブレーキ
72 delay(500);
73 moveBackward(160); //後退
74 delay(1000);
75 stopBreak(); //ブレーキ
76 delay(500);
77 turnRight(160); //右旋回
78 delay(1000);
79 stopBreak(); //ブレーキ
80 delay(500);
81 turnLeft(160); //左旋回
82 delay(1000);
83 stopBreak(); //ブレーキ
84 delay(500);
85}
引数2個:analogWriteのように指定できる数値が2個あるもの
上のプログラムを見ると、動作の後に必ずその動作の継続時間を設定するためのdelayが入っていますよね。
delayも関数の中に入れて、一気にスッキリさせちゃいましょう!
オリジナルの関数で2個の数値を指定できるようにする(引数を2個にする)には、下の図のように括弧()の中で、コンマ(,)で区切って、変数を2個作ればいいんです!
もしかして、予想通りでした?
下の例ではduration(間隔)という変数(引数)を追加して、動作の継続時間を設定するためのdelayの中に入れていますね。
複数の引数を持つ関数を使うときには、数値を書く順番に気を付けてくださいね!
最後に、動作継続時間も指定することができるように、引数を2個使った関数に書き換えたプログラムを全文載せておきます。
ついに、loopの中がたった8行になっちゃいましたね!!
1const int PIN_MOTOR_L_A = 6; //左モータA
2const int PIN_MOTOR_L_B = 9; //左モータB
3const int PIN_MOTOR_R_A = 5; //右モータA
4const int PIN_MOTOR_R_B = 3; //右モータB
5const int PIN_BUTTON = 8; //押しボタンスイッチ
6
7//前進
8void moveForward(int power, int duration) {
9 analogWrite(PIN_MOTOR_L_A, power); //左A
10 analogWrite(PIN_MOTOR_L_B, 0); //左B
11 analogWrite(PIN_MOTOR_R_A, power); //右A
12 analogWrite(PIN_MOTOR_R_B, 0); //右B
13 delay(duration);
14}
15
16//後退
17void moveBackward(int power, int duration) {
18 analogWrite(PIN_MOTOR_L_A, 0); //左A
19 analogWrite(PIN_MOTOR_L_B, power); //左B
20 analogWrite(PIN_MOTOR_R_A, 0); //右A
21 analogWrite(PIN_MOTOR_R_B, power); //右B
22 delay(duration);
23}
24
25//右旋回
26void turnRight(int power, int duration) {
27 analogWrite(PIN_MOTOR_L_A, power); //左A
28 analogWrite(PIN_MOTOR_L_B, 0); //左B
29 analogWrite(PIN_MOTOR_R_A, 0); //右A
30 analogWrite(PIN_MOTOR_R_B, power); //右B
31 delay(duration);
32}
33
34//左旋回
35void turnLeft(int power, int duration) {
36 analogWrite(PIN_MOTOR_L_A, 0); //左A
37 analogWrite(PIN_MOTOR_L_B, power); //左B
38 analogWrite(PIN_MOTOR_R_A, power); //右A
39 analogWrite(PIN_MOTOR_R_B, 0); //右B
40 delay(duration);
41}
42
43//ブレーキ
44void stopBreak(int duration) {
45 digitalWrite(PIN_MOTOR_L_A, LOW); //左A
46 digitalWrite(PIN_MOTOR_L_B, LOW); //左B
47 digitalWrite(PIN_MOTOR_R_A, LOW); //右A
48 digitalWrite(PIN_MOTOR_R_B, LOW); //右B
49 delay(duration);
50}
51
52//フリー
53void stopFree(int duration) {
54 digitalWrite(PIN_MOTOR_L_A, HIGH); //左A
55 digitalWrite(PIN_MOTOR_L_B, HIGH); //左B
56 digitalWrite(PIN_MOTOR_R_A, HIGH); //右A
57 digitalWrite(PIN_MOTOR_R_B, HIGH); //右B
58 delay(duration);
59}
60
61void setup() {
62 //ピンの出力(Output)or入力(Input)設定
63 pinMode(PIN_MOTOR_L_A, OUTPUT); //左モータA
64 pinMode(PIN_MOTOR_L_B, OUTPUT); //左モータB
65 pinMode(PIN_MOTOR_R_A, OUTPUT); //右モータA
66 pinMode(PIN_MOTOR_R_B, OUTPUT); //右モータB
67 pinMode(PIN_BUTTON, INPUT); //スイッチ
68
69 //スタートボタンを押されるのを待つ
70 while(digitalRead(PIN_BUTTON)==0);
71 delay(1000); //1秒待つ
72}
73
74void loop() {
75 moveForward(160, 1000); //前進
76 stopBreak(500); //ブレーキ
77 moveBackward(160, 1000); //後退
78 stopBreak(500); //ブレーキ
79 turnRight(160, 1000); //右旋回
80 stopBreak(500); //ブレーキ
81 turnLeft(160, 1000); //左旋回
82 stopBreak(500); //ブレーキ
83}
ちなみに、引数は何個でも作ることができます!
必要な時は、3個でも4個でも作っちゃってください!!
まとめ: 【Arduino初級】機能をまとめてloopをスッキリ!関数の使い方を解説!
今回の記事では、動作を追加してごちゃごちゃになってきたloopの中をスッキリさせるために、【関数】の作り方と使い方を解説しました!
- 関数とは?
- 関数の作り方と使い方3パターン
- 引数なしの場合
- 引数1個の場合
- 引数2個の場合
最終的には、ごちゃごちゃしていたloopの中が、たった8行になっちゃいましたね^^
関数はArduinoだけでなくいろんな言語に使われている仕組みなので、プログラミングをする上では必須の知識です。
ぜひこの知識を活用して、効率よく読みやすいプログラムを書けるようになりましょう\(^o^)/
プログラミングを勉強するならArduinoがおすすめです。
ロボット作りに必要なパーツはこちらの記事にまとめています。
最後まで読んでいただき、ありがとうございました!
以上、CHAでした!