Arduino
PR

【Arduino初級】機能をまとめてloopをスッキリ!関数の使い方を解説!

blog_admin
記事内に商品プロモーションを含む場合があります

ロボットに色んな動きをさせたい!
そう思ってloopの中にたくさんプログラムを書くと、ごちゃごちゃしますよね。
プログラムがごちゃついてきた…と思ったら、関数の出番です。

CHA
CHA

関数を使うと、すっきりしたプログラムが書けます。
機能をひとまとめにして1行で書くことが出来るんです!

関数はArduinoだけでなく、いろんな言語に使われている仕組みです。
なのでプログラミングをする上では必須の知識です。

ぜひ、関数を使ってプログラムをスッキリ書けるようになりましょう!\(^o^)/

この記事で解説すること
  • 関数とは?
  • 関数の作り方と使い方3パターン
    1. 引数なしの場合
    2. 引数1個の場合
    3. 引数2個の場合

この記事を読むことで関数の使い方が理解できますよ。

スポンサーリンク

解説動画

今回の記事の解説動画はこちらです。

関数とは?

関数とは機能をまとめて1行で使えるようにしたものです。

digitalWriteやdelayも関数なんです!
digitalWriteは、指定したピンからHIGHまたはLOWを出力する機能をまとめて1行で使えるようにした関数。
delayは、指定した時間待つという機能をまとめて1行で使えるようにした関数。

さらに見た目は全然違いますが、setupやloopも関数だったんです!!

みなさん無意識のうちにすでに関数を使っちゃってたので、怖がらなくて大丈夫そうですね^^

関数の作り方と使い方を3パターン解説!

関数の作り方にはいろいろあります。
今回は下記の3パターンを解説したいと思います!

  1. 引数なし→単純に指示をまとめて実行できるようにしたもの
  2. 引数1個→delayのように実行するときに数値を指定できるもの
  3. 引数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のように実行するときに数値を指定できるもの

上で解説したプログラムのデメリットは、モータのパワーを変化させたいときにパワー別に関数を作成しなければならないことです。

CHA
CHA

値が違うだけの関数を複数作るのは面倒です。
そこで引数を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も関数の中に入れて、一気にスッキリさせちゃいましょう!

関数を使うときに指定できる数値は1個だけとは限らない!
(例)analogWriteはピン番号とパワーの2個の数値を指定している

オリジナルの関数で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. 引数1個の場合
    3. 引数2個の場合

最終的には、ごちゃごちゃしていたloopの中が、たった8行になっちゃいましたね^^

関数はArduinoだけでなくいろんな言語に使われている仕組みなので、プログラミングをする上では必須の知識です。
ぜひこの知識を活用して、効率よく読みやすいプログラムを書けるようになりましょう\(^o^)/

プログラミングを勉強するならArduinoがおすすめです。
ロボット作りに必要なパーツはこちらの記事にまとめています。

あわせて読みたい
プログラミングを始めたいロボット好き→Arduinoがおすすめ!
プログラミングを始めたいロボット好き→Arduinoがおすすめ!

最後まで読んでいただき、ありがとうございました!
以上、CHAでした!

スポンサーリンク
ABOUT ME
CHA
「勉強に自由を!」をスローガンに、学校に限らず、好きな時に、好きな場所で、好きなことをYouTubeで勉強できるようになればいいなと思って授業動画を作っています!
記事URLをコピーしました