それでは、Arduinoの統合開発環境「Arduino IDE」でスケッチを作成します。Arduinoでは、プログラムのことを「スケッチ」と呼びます。開発環境のPCでArduino IDEを起動すると、新規画面が開きます。試しに、メニューから[ファイル]-[スケッチの例]-[Basic]-[BareMinimum]を開いてみましょう。これは、Arduinoのスケッチを作る際に最低限必要な2つの関数が記述された“スケルトンスケッチ”です(画像13)。
画像13を見ながら、Arduinoのスケッチ作成の基本を理解していきましょう。
まず、setup()内には、Arduinoが起動されたときやリセットボタンを押されたときに「最初に1回だけ実行する処理(セットアップ処理)」を記述します。例えば、LEDやスイッチが接続されているピンの設定や、PCのディスプレイに情報を表示するためのシリアルモニターのスタートなどです。
そして、loop()内にはメイン処理を記述します。記述されている命令が何度も繰り返されることに留意してください。
試しに、C言語のプログラムとArduinoのスケッチを比較してみましょう(画像14)。Arduinoのスケッチは、C言語のメイン関数内の初期設定をsetup()、ループ内に記述する命令をloop()として記述します。
スケッチは、大文字・小文字を区別するので、注意してください。命令の終わりには「; (セミコロン)」が必要です。全角文字を入力するとエラーになります。スペースの全角半角は気付きにくいので注意が必要です。
スケッチを書き終えたら、コンパイルエラーをチェックして(画像13-①のアイコンをクリック)、問題がなければ、ArduinoとPCをUSBケーブルで接続し、マイコンボードに書き込み(画像13-②のアイコンをクリック)を行います。
上記を念頭において、2コマアニメのスケッチを見ていきましょう(スケッチ1)
- //-----------------------
- // 定数の定義
- //-----------------------
- const int SW = 2; // スイッチの入力ピン
- const int B_LED = 3; // 青色LEDの出力ピン
- const int O_LED = 4; // 橙色LEDの出力ピン
- //スイッチの回路は負論理なので、ONがLOWになる
- const int SW_ON = LOW;
- const int SW_OFF = HIGH;
- //-----------------------
- // フラグの定義
- //-----------------------
- const int FLG_ON = 1;
- const int FLG_OFF = 0;
- //-----------------------
- // グローバル変数の定義
- //-----------------------
- int G_oldval = SW_OFF; // スイッチの状態 (初期設定はOFF)
- int G_state = FLG_OFF; // LED点滅の状態 (初期設定はOFF)
- //-----------------------
- //最初に1回だけ実行する処理
- //-----------------------
- void setup() {
- pinMode(SW, INPUT); // SWを入力モードに設定
- pinMode(B_LED, OUTPUT); // 青色LEDを出力モードに設定
- pinMode(O_LED, OUTPUT); // 橙色LEDを出力モードに設定
- }
- //-----------------------
- //繰り返し実行する処理
- //-----------------------
- void loop() {
- int val = digitalRead(SW); // スイッチの状態を読み取る
- //スイッチがON、前回がOFFだったとき
- if( val == SW_ON && G_oldval == SW_OFF ){
- //LED点滅の状態を切り替える
- if(G_state == FLG_ON){ // フラグがONのとき
- G_state = FLG_OFF; // OFF
- } else { // フラグがOFFのとき
- G_state = FLG_ON; // ON
- }
- delay(10); // チャタリング防止のウエイト
- }
- G_oldval = val; // スイッチの状態をG_oldvalへ保存
- //LEDの点滅状態を開始するとき
- if (G_state == FLG_ON){ // LEDの点滅状態がONのとき
- digitalWrite(O_LED, HIGH); // 橙色LED点灯
- delay(300); // 0.3秒待つ
- digitalWrite(O_LED, LOW); // 橙色LED消灯
- delay(300); // 0.3秒待つ
- digitalWrite(B_LED, HIGH); // 青色LED点灯
- delay(300); // 0.3秒待つ
- digitalWrite(B_LED, LOW); // 青色LED消灯
- delay(300); // 0.3秒待つ
- } else { // OFFのとき
- digitalWrite(B_LED,LOW); // 青色LED消灯
- digitalWrite(O_LED,LOW); // 橙色LED消灯
- }
- }
それでは、今回のスケッチの中身について説明していきます。
4~6行目は、Arduinoのピンがどの電子部品と接続しているかを定義しています。
9~10行目で、スイッチを押したときと押されていないときの状態を定義しています。今回の回路では、通常時に2番ピンにHIGHの信号が送られており、ボタンを押したときにLOWになります(こういう回路を「負論理」または「ロウアクティブ」といいます)。
ONがLOWで、OFFがHIGHというのは、電子工作に慣れていないと少し不自然に感じます。そこで、スケッチを読みやすくするために定数でONとOFFを定義しています。
21~22行目は、スイッチを押下した後もLED点滅の状態を保つために「LED点滅の状況」と「スイッチの状態」を記憶するための変数です。判断はloop()内で行いますが、グローバル変数にしておかないと毎回初期化されてしまうので、最初に定義しておきます。
続いて、27~31行目のsetup()内では、事前に定義しておいた3つのピンに対し、スイッチを入力に、2つのLEDを出力に指定しています。
そして、36行目以降のloop()内の記述をArduinoが繰り返し実行します。37行目のdigitalRead()は、ピンから得られたデジタル値を読み込む関数です。ここでは、スイッチが押されているか、押されていないかを読み取ります。
スイッチが押されたからといって、すぐにLEDの点滅を開始するわけにはいきません。なぜなら今回は、2コマアニメを実現するために、
という仕様にしているからです。
そこで、スイッチが押されたときに、前回のスイッチの状態が「OFF」だった場合に限定して、LEDの状態を変更するように指示しています(40~48行目)。
ちなみに、この場合の「前回のスイッチの状態」は、「前回、自分がスイッチを押下したとき」ではありません。Arduinoのマイコンは、電源が入ったらすぐに起動し、setup()内の処理をした後は、loop()内を何度も繰り返し実行します。つまり、ここでは、「スイッチが押されていない状態から押した瞬間」を見つけ出しているわけです。
47行目で、10ms待っているのは、スイッチの押下が完全にできてから処理を実行するために「チャタリング防止」を入れているからです。
このあたりの考え方は、「電子工作のプログラム」らしいなと筆者は感じました。
Copyright © ITmedia, Inc. All Rights Reserved.