今回は#defineの続きと、新しく算術演算子を習得します。
#defineの追加
前回のスケッチではdelay(1000);
の1000の部分を#define
で定義してスケッチを変更しやすくしました。
今回は残りのdelay(2000);
の2000の部分を#define
で定義したいと思います。
前回のdelay(1000);
の時と同様に、#define 単語 2000
と書けばOKですよね。#define
で定義する場合、どのような単語で定義するか意外に悩みます。
今回定義するdelay(2000);
は、delay(1000);
の2倍の長さの時間です。
delay(1000);
ではLED_JIKAN
という単語にしましたので、その2倍ということでLED_JIKAN_x2
という単語にしようと思います。
「x2」は小文字のエックスと数字の2にしてみました。見た目、「かける2」って感じです。もっとわかりやすい書き方があればそれにしても問題ありません。
定義する単語が決まりましたので、あとはスケッチに書くだけです。以下のようにしてみました。特に難しいところはないと思います。
あとは、#define
の部分をもう少し見やすくしておきます。
LED_JIKAN
とLED_JIKAN_x2
のあとの数字がそろっていないため、ちょっと見づらいので数字の先頭を合わせてみました。(このように、スペースを入れる場合は全角スペースにするとArduino IDEに怒られますので十分注意してください)
あとはLED_JIKAN_x2
にコメントを書いて説明を追加しておきました。
算術演算子
#define
を使うことにより、delay
の引数の変更が、最初に作ったスケッチより簡単になりましたよね。
以前のスケッチでdelay
の引数を変更しようとするとdelay(1000);
が4ヶ所、delay(2000);
が2ヶ所の合計6ヶ所をいちいち変更する手間がかかりました。
#define
で定義することにより、時間を変更したい場合、#define
で定義した2ヶ所の数字を変更するだけの作業になりました。
それでは、LEDの点滅パターンを以下のように変更してみたいと思います。
1秒を0.5秒、2秒を1秒に変更すればいいので、#define
を以下のように変更すれば大丈夫ですよね。
スケッチを変更できたらArduinoボードに送って動作を確認してみてください。
実際に動作させてるみたのですが、、、すみません、もうちょっと早めに点滅させてみたくなってしまいました。なんだかまだのんびり感が残ってる感じなんですよね。
そこで、ちょっと微妙な時間なんですが、短い方の時間を0.5秒ではなく、その4分の3の時間、0.375秒にしてどんな感じか様子を見てみたいんです。
0.375秒は375ミリ秒です。ってことは、#define LED_JIKAN 500
の 500 の部分を 375 に変更すればOKですよね。
では、「#define LED_JIKAN_x2 1000」の1000はいくつにすればいいかというと、、、
375を2倍すればいいのですが、375 x 2って、パッとすぐにわかる感じではないですよね。電卓で計算しても構いませんが、、、なんかおかしくないですか?
というのは、Arduinoは小さなコンピュータです。要するに「計算機」なんですが、なんで 375×2 という式を、計算機であるArduinoではなくて私たちの方で計算しなくてはいけないんでしょうか。計算機だったらそれぐらい計算してよ、って感じですよね。
ということで、375×2はArduinoに計算してもらいましょう。
スケッチでは以下の記号を使って四則演算をすることができます。
「足し算引き算掛け算割り算」とか「四則演算」などと呼んでいたと思います。
スケッチ(プログラミング)では、もう少し意識高い系の言葉を使います。これらは「算術演算子」と呼びます。
「算術」は算数という感じの意味でしょうか。「演算」は計算、「子」は記号の意味です。
「足し算引き算掛け算割り算」と呼ぶ代わりに、「算術演算子」と呼ぶ方がなんだか難しい話をしている雰囲気になりますので、これからは「算術演算子」と呼ぶようにします。
また、足し算というと普通なので、これらも別の呼び方を覚えておいて下さい。表にまとめておきます。
普通の言葉 | 意識高い系の言葉 |
---|---|
計算記号・四則演算記号 | 算術演算子 |
足し算 | 加算(かさん) |
引き算 | 減算(げんざん) |
かけ算 | 乗算(じょうざん) |
割り算 | 除算(じょざん) |
なおプログラミングでは計算など、何かの操作をする記号を「演算子」と呼ぶことが多いですので、この点も頭の片隅においておいて下さい。(「演算子」は英語では「Operator」で、「操作する人・もの」というような意味合いです)
算術演算子について補足しておきます。
加算と減算はそれぞれプラス記号、マイナス記号なので違和感はないと思います。
乗算は「 * 」(アスタリクス記号)を使用します。アルファベット小文字のエックス「 x 」の方が掛け算の記号っぽいですが、エックスは文字ですので演算子には使えません。「 x 」以外に掛け算に近い記号ということで「 * 」が使用されています。
除算は普通に書くと「 ÷ 」ですが、この文字はアルファベットにありませんので「 / 」(スラッシュ記号)を使用します。割り算が「/」というのはわかりづらいかもしれませんが、小学校で習った分数を思い出してみてください。分数は以下の意味でしたよね。
ということで、割り算は結局分数ですので、割り算記号は分数を表す横棒に近い「 / 」を使用しています。
ちょっと話はそれますがパーセント記号「%」ってありますよね。「%」記号の斜め線も割り算(=分数の横棒)の意味合いがあるのをご存知でしょうか。さらに斜め線の両側の丸印は数字のゼロを表しています。ちょっと???って感じですよね。
「パーセント」は日本語にそのまま訳すと「100あたり」という意味です。全体を100とした場合、いくつになるか、という意味です。75%という場合、全体を100とすると75、ということになります。
ただ、数学で扱う割合は0〜1の実数です。例えば50%といった場合、数学でいう割合は0.5です。
つまり、実際の割合の数字はパーセント表現の数字を100で割ると出てきます。75%であれば、実際には75 ÷ 100 = 0.75で、数学的な割合の数字は「0.75」になります。
75% = 0.75
つまりパーセントは「 ÷100 」という意味なのですが、これを分数的に表現すると「 /100 」になります。「 /100 」の最初の「 /1 」をまとめて1本の斜め線にして、「 00 」の間に移動した記号が「%」になっています。
パーセントは100あたり、という意味ですが、他にも1000あたり、という意味のパーミル「 ‰ 」という記号もあります。この記号がなぜこのような形なのか、パーセント記号の意味がわかれば想像つくかな、と思います。
話がそれてしまいましたが、スケッチを修正してLEDの点滅の時間間隔を変更してみましょう。
短い方の時間を375ミリ秒、長い方の時間はその2倍ですので375 * 2
と書けばOKです。スケッチをそのように変更してみます。変更後、検証ボタンでスケッチに問題がないか確認してみてください。
なお、「 375 」と「 * 」と「 2 」の間のスペースはあってもなくても構いません。Arduino IDEはスペースがあってもなくても「375かける2」と解釈できるためです。
さて、スケッチをこのように変更してみましたが、375ミリ秒を変更したい場合、まだ2ヶ所変更の必要がありますよね。
この2ヶ所の数字は同じです。せっかく#define LED_JIKAN 375
でLED_JIKAN
を定義したわけですから、この後に出てくる375はLED_JIKAN
が使えますよね。
このように考えると、スケッチは以下のようにに変更することができます。
これで全体のLEDの点滅時間を変更したい場合、基本となるLED_JIKAN
を1ヶ所変更するだけであとはArduino IDEが2倍の時間を計算して、delay
の引数を裏で置き換えてくれます。
このようにスケッチの中で同じ値が多く出てくる場合は、#define
で定義すると、スケッチを変更するとき楽になります。また何ヶ所も変更する必要がないので、変更し忘れなどがなくなります。
さらに、#define
で定義した名前を意味がわかるようにしておけば、スケッチ中に数字だけ書いてあるより、スケッチが理解しやすくなります。
スケッチの規模が大きくなってくると、だんだん複雑になってきて、ちょっとした変更でも手間がかかるようになってきます。少しでも間違いがなく、手間を減らすように、このようにコメントや#define
を使用して、スケッチを変更しやすくするようにして下さい。
このようにスケッチを見やすくしたり変更しやすくしたりすることを「スケッチ(プログラム)のメンテナンス性をよくする」と言われることがあります。普段使わないように言葉を使うと、知的な印象を相手に与えることができますので、ぜひ使ってみて下さい。
完成したスケッチは以下のようになります。スケッチ先頭のコメント内容の更新履歴の内容を追記しました。
補足1 〜 #define定義の注意点 〜
今回のスケッチは上のように書きましたが、大切な注意点があります。
現在の知識で十分理解できますので、もし余力がありましたらこのシリーズ最後の方にある以下の補足記事を先にお読みいただければと思います。
補足2 〜const修飾子〜
すみません、執筆中です。
更新履歴
日付 | 内容 |
---|---|
2019.8.5 | 新規投稿 |
2021.8.22 | 新サイトデザイン対応 |
2022.2.3 | 補足記事案内追加 |
初めまして
全くの初心者で、Arduinoが昨日届いたので早速試しましたが、なかなか理解が出来ませんでしたが、あなた様のホームーページで、Arduinoでプログラミング入門〜基礎編パート1〜を実践しています。テキストエディタに打ち込みましたがなぜか何回見ても、コンパイルでエラーになります。
Arduinoのバージョン 1.8.12 です。
下が見て打ち込んだのですが。
/*
* 動作確認: チャレンジ課題1
* 8番ピンに接続したLEDを制御する
* 作成日:2021.9.14
* 変更履歴:
*
*/
#define LED_JIKAN 375 //LEDの点減時間間隔(単位はミリ秒)
#define LED_JIKAN_x2 LED_JIKAN * 2 //2倍のLEDの点減時間間隔(単位はミリ秒)
void setup() {
pinMode(12, OUTPUT); //12番ピンを出力に設定
}
void loop() {
digitalWrite(12, HIGH);
delay(LED_JIKAN);
digitalWrite(12, LOW); //LEDをオフ
delay(LED_JIKAN);
digitalWrite(12, HIGH);
delay(LED_JIKAN);
digitalWrite(12, LOW);
delay(LED_JIKAN);
digitalWrite(12, HIGH)
delay(LED_JIKAN_x2);
digitalWrite(12, LOW);
delay(LED_JIKAN_x2);
}
ここで delay(LED_JIKAN_x2);エラーメッセージが出ます。
宜しくお願いします。
このシリーズをお読みいただきどうもありがとうございます。
またご質問いただきどうもありがとうございます。
いただいたプログラムですが、エラーの意味がなかなかわからないケースになります。
最初に原因をご説明しますと、エラーが出る行の1行前に原因があります。
エラーが出る「delay(LED_JIKAN_x2);」の1行前に「digitalWrite(12, HIGH)」とありますが、この行の最後に「 ; 」が抜けてしまっています。「 digitalWrite(12, HIGH); 」というように最後に「 ; 」を付ければ動くと思います。
このエラーについて、2点補足させていただきます。
まず1点目ですが、このエラーは「digitalWrite(12, HIGH)」の行ではなく、次の行でエラーになっているのが疑問に思われたと思います。次の行でエラーが発生する理由は以下になります。
まず、Arduino Microは、「digitalWrite(12, HIGH)」の行をみて最後に「 ; 」が付いていないので、まだ命令が続くと判断して次の行を続けて読み始めます(改行はArduinoにとって意味がないもの、ということを思い出してみてください)。次の行を読み進めると、最後に「 ; 」がありますので、Arduinoは「 digitalWrite(12, HIGH)delay(LED_JIKAN_x2);」という1つの命令だ、と判断します。この時点でこのような命令はArduinoは知らないのでエラーにしてしまっています。(すみません、説明が悪く、わかりづらいようでしたら再度ご質問いただけると幸いです)
次に2点目ですが、「 ; 」忘れはプログラマになった証です!というのは、実は私もいまだに「 ; 」を忘れてエラーになることがあります。私の周りのプログラム歴が長い人もついうっかり忘れてエラーになったりしています。
ということで、このエラーは誰でも経験することと、意外にずっと付き合っていくエラーですので、今後不可解なエラーが出てきたら、前の行を確認してみる、ということもしてみてください。
こちらで確認したプログラムを添付いたします。
他に不明点ございましたらご質問いただければと思います。