Arduino 入門
番外編 09
【スケッチ(コード、プログラム)の関数化】
こんにちは管理人のomoroyaです。
今回は、「Arduino 入門 番外編 09 スケッチ(コード、プログラム)の関数化」です。
arduino 入門 番外編はarduinoの基本的なことを書いていく方向性にしたいと考えています。
本日は、スケッチ(コード、プログラム)の関数化についてです。
Arduinoに複雑なことをさせようとすると、スケッチ(コード、プログラム)がどんどん複雑になっていきますよね。
そんなときは、スケッチ(コード、プログラム)の関数化で解決です。
ぜひ、スケッチ(コード、プログラム)を関数化することで分かりやすいコードを書いてみてください。
arduino自身のこと、スケッチ(コード、プログラム)を少しづつ理解して行きましょう。
いやいや、arduinoを早速始めたいんだ!というかたは下記の入門編からお読みください。
Arduino入門編の解説にて使用しているArduinoは互換品です。
互換品とは言え、Arduinoはオープンソースであり複製して販売するのもライセンス的に問題なし。
そのため互換品の品質も悪くなく、それでいて値段は安いです。
正規品本体の値段程度で豊富な部品が多数ついています。
正規品(Arduino UNO R3)の本体単品がほしい方はこちらとなります。
Arduino入門編2では「Arduino UNO R4 Minima」「Arduino UNO R4 WIFI」にて遊ぶため今のところは正規品を使用。(まだ互換品が・・・ほぼない)
スケッチ(コード、プログラム)の関数化について
ArduinoはC/C++をベースにしています。
そのため、
スケッチ(コード、プログラム)を機能ごとに分割して特定の仕事をこなすモジュールを作成するといったことが簡単にできます。
このモジュールの単位のことを関数(function)と呼びます。
スケッチ(コード、プログラム)のなか、頻繁に行われる処理をモジュール化することで1つの関数としてまとめます。
関数を呼び出す(コール)すると処理が実行され、処理が終了したらコールした位置へ戻ってきます。
Arduinoに慣れてきて、スケッチ(コード、プログラム)が複雑に長くなってしまわないように関数化は必須な作業です。
ぜひ、使えるようになりましょう。
スケッチ(コード、プログラム)を関数化することのメリット
メリットはいくつかありますが
私が考える一番のメリットは、「デバックが容易」といったところでしょうか。
一度、関数化してクローズさせてしまえば問題があったときにクローズしている中だけでデバックができるなどが可能です。
その他にも
- 関数化することでスケッチ(コード、プログラム)が見やすくなる。(※重要!)
- 同じ処理を何度も書かずに済む。
- スケッチ(コード、プログラム)のサイズを小さくする。
- スケッチが小さくなるのでメモリの使用量が減る。
- 関数の再利用が可能。
などなどメリットがたくさんあります。
ぜひ、同じ作業の繰り返しに関しては関数化することをお勧めします。
公式ホームページでは以下にて説明がなされています。
では、さっそく関数化について解説していきます。
関数化するには2つの手段があります。
1.戻り値を返す関数
2.戻り値を返さない関数
戻り値を返す関数
戻り値を返す関数というのは、関数が何かの作業をし、その作業結果を返すという処理のことです。
関数に対して、作業をさせるために情報を渡す(引数と言う)場合もあります。
{
処理に必要なコードを記述;
return 戻り値;
}
戻り値の型名:int , double などのデータ型を定義
関数名:お好きにどうぞ(reserve名は使わないでね)
引数の型:int , double などのデータ型を定義
引数名:お好きにどうぞ
※引数がない場合は ( ) 内は何もか書かない。
実際の例で説明していきます。
例1.2つの数字の足し算をする関数。(引数あり)
int func_add(int x, int y) { int result; result = x + y; return result; }
func_addが関数名、int x, int yは関数に渡される引数となります。
ここでは、int型の整数を2つ引数としています。
{ } 内で囲まれた箇所が、func_add関数が処理する作業となります。
x、yの値をもらって、x + yを実行してresultに格納。
resultの結果を戻り値として返すということになります。
実際のスケッチに組み込んだサンプルコードがこちら。
シリアルモニタに計算結果を表示するサンプルスケッチです。
void setup() { Serial.begin(9600); } void loop() { int a = 7; int b = 5; int c; c = func_add(a, b); Serial.println(c); delay(500); } int func_add(int x, int y) { int result; result = x + y; return result; }
例2.2つの数字の足し算をする関数。(引数なし)
int func_add() { int x = 8; int x = 5; int result; result = x + y; return result; }
func_addが関数名、関数に渡す引数がない場合は()内になにも記載しなくてOK。
{ } 内で囲まれた箇所が、func_add関数が処理する作業となります。
x、yに定義された値で、x + yを実行してresultに格納。
resultの結果を戻り値として返すということになります。
実際のスケッチに組み込んだサンプルコードがこちら。
シリアルモニタに計算結果を表示するサンプルスケッチです。
void setup() { Serial.begin(9600); } void loop() { int c; c = func_add(); Serial.println(c); delay(500); } int func_add() { int x = 8; int y = 5; int result; result = x + y; return result; }
戻り値を返さない関数
戻り値を返さない関数というのは、関数に何かの作業だけをさせ、その作業結果をスケッチ内で特に利用しない場合に利用します。
関数に対して、作業をさせるために情報を渡す(引数と言う)場合もあります。
{
処理に必要なコードを記述;
}
void:戻り値がない場合はvoidとなります。
関数名:お好きにどうぞ(reserve名は使わないでね)
引数の型:int , double などのデータ型を定義
引数名:お好きにどうぞ
※引数がない場合は ( ) 内は何もか書かない。
実際の例で説明していきます。
例1.LEDをON OFF する関数。(引数あり)
こんなんでも、関数にできちゃいますよという例です。
void func_led(int x) { pinMode(x, OUTPUT); digitalWrite(x , HIGH); delay(500); digitalWrite(x , LOW); delay(500); }
func_ledが関数名、int xは関数に渡される引数となります。
ここでは、int型の整数を1つ引数としています。
{ } 内で囲まれた箇所が、func_led関数が処理する作業となります。
xに定義されたデジタル入出力ピンをHIGH、LOWにすることでLEDをON、OFFしています。
実際のスケッチに組み込んだサンプルコードがこちら。
デジタル入出力、8、9番ピンに接続されたLEDをON、OFFするサンプルスケッチです。
同じことを2回、記述しなくても良いことをわかりやすくしたサンプルです。
void setup() { } void loop() { func_led(8); func_led(9); } void func_led(int x) { pinMode(x, OUTPUT); digitalWrite(x , HIGH); delay(500); digitalWrite(x , LOW); delay(500); }
例2.LEDをON OFF する関数。(引数なし)
例1を引数なしで記述してみました。
void func_led() { pinMode(8, OUTPUT); digitalWrite(8 , HIGH); delay(500); digitalWrite(8 , LOW); delay(500); }
func_ledが関数名、引数なしとなります。
{ } 内で囲まれた箇所が、func_led関数が処理する作業となります。
デジタル入出力の8番ピンをHIGH、LOWにすることでLEDをON、OFFしています。
実際のスケッチに組み込んだサンプルコードがこちら。
デジタル入出力の8番ピン接続されたLEDをON、OFFするサンプルスケッチです。
同じLEDを3秒、5秒のインターバルを設けてON、OFFさせています。
こちらも同じことを2回、記述しなくても良いことをわかりやすくしたサンプルです。
void setup() { } void loop() { func_led(); delay(3000); func_led(); delay(5000); } void func_led() { pinMode(8, OUTPUT); digitalWrite(8 , HIGH); delay(500); digitalWrite(8 , LOW); delay(500); }
まとめ
「Arduino 入門 番外編 09 スケッチ(コード、プログラム)の関数化」
いかがだったでしょうか?
Arduinoに色んなことをさせようと考えると、スケッチ(コード、プログラム)がどんどん複雑になっていきます。
そんなときは、ぜひ関数化してわかりやすいスケッチを書くようにすると良いと思います。
デバックが容易ですし、後で見てもわかりやすいです。
次回の番外編は、スケッチで重要な【変数のスコープ】について情報を発信したいと考えています。
最後に
疑問点、質問などありましたら気軽にコメントください。
この電子部品の解説をしてほしい!などなどなんでもOKです。
リンク切れ、間違いなどあればコメントいただけると助かります。
Arduino入門編、番外編、お役立ち情報などなどサイトマップで記事一覧をぜひご確認ください。
Arduino入門編、Arduino入門編2で使用しているUNOはAmazonにて購入可能です。
Arduino入門編では互換品を使用。
Arduinoはオープンソース。
複製して販売するのもライセンス的に問題なし。
そのため互換品の品質も悪くなく、それでいて値段は安いです。
正規品本体の値段程度で豊富な部品が多数ついています。
学習用、遊び用、お試し用には安価な互換品がおすすめです。
ELEGOO UNO キット レベルアップ チュートリアル付 uno mega2560 r3 nanoと互換 Arduino用
上記のものでも十分に多数の部品が入っていますが、最初からもっと多数の部品が入っているこちらもお勧めです。
Arduino入門編2では「Arduino UNO R4 Minima」「Arduino UNO R4 WIFI」にて遊ぶため今のところは正規品を使用。(まだ互換品が・・・ほぼない)
Amazonでお得に買う方法
Amazonでお得に購入するならAmazon Mastercard、Amazonギフト券がおすすめです。
時期により異なりますが、様々なキャンペーンを実施しています。
\Amazonギフト券/
Amazonギフトカード キャンペーン
\Amazon Mastercard お申込み/
Amazon Mastercard 申し込み
いずれの場合もプライム会員である方がお得!!
\Amazon Prime 30日間の無料会員を試す/
無料会員登録
コメント
メインルーチンでIfで分岐した先で、例えばスイッチのinputがLOWの間はサブルーチンをぐるぐる繰り返し続けて、スイッチのinputがHIGHになったらメインルーチンに戻って続きの処理に行く、みたいな挙動はどういう風に書いたらいいでしょうか?調べても関連した情報があまり出てこなかったのですが。
コメントありがとうございます。
メインルーチンでLの間は、そのサブルーチンを繰り返すようにするのが良いかと思います。
メインルーチンもループしているわけですから。
どうしてもサブルーチンでということであれば、
サブルーチン内でwhileあたりを使ってLの間は
whileから抜けださいない様にするなどするのが良いのではないでしょうか。
電気が苦手なのに趣味で真似してやってますが、独学だと分からないことだらけでしたが、個々のサイトは他では説明してない、ホントに素人が直面するところを説明していただいているのでホント助かります。ありがとうございます。
で、ここでの質問ですが、よくvoid 関数名(void)と書いてあるプログラムが多いですが、これは void 関数名()と同じですか。voidの意味が良く分かりません。
よろしくお願いします。
コメントありがとうございます。
voidは何もないってことを意味しています。
C言語の意味合い的には下記と管理人は理解しています。
例)
1.引数あり、戻り値あり -> int xxx(int 引数)
2.引数あり、戻り値なし -> void xxx(int 引数)
3.引数なし、戻り値あり -> int xxx(void)
4.引数なし、戻り値なし -> void xxx(void)
ここで、3番目、4番目の引数なしの場合
( )の中にvoidを描いた方が良いか?ということですが・・・
Arduinoのスケッチとしては、なくてもOKでして・・・
描いておいた方が、わかりやすい。
C言語的には、あった方がよい。
という感じかなと管理人は考えています。
引数の考え方が今ひとつ理解できなかったのですが、記事を拝読してようやく理解出来ました!
そう言っていただくと、記事を書く励みになります!