さて、今日はprg_process(int num)
の中身を作ります。
それにあたっては、C言語の文法を2つ、switch文と、ビットシフトを学んだほうが楽かと思いますので、ご紹介します。
いきなり完成したソースを紹介
追加分のみ掲載
int BANK_DATA[4] = {0x1, 0x3, 0x7, 0xf}; void setup() { pinMode(LED[0], OUTPUT); pinMode(LED[1], OUTPUT); pinMode(LED[2], OUTPUT); pinMode(LED[3], OUTPUT); pinMode(LED[4], OUTPUT); pinMode(LED[5], OUTPUT); pinMode(LED[6], OUTPUT); pinMode(LED[7], OUTPUT); pinMode(SW[0], INPUT_PULLUP); pinMode(SW[1], INPUT_PULLUP); pinMode(SW[2], INPUT_PULLUP); pinMode(SW[3], INPUT_PULLUP); } void prg_process(int num)// PGMモード時動作 { switch (num) { case 0: digitalWrite(LED[4], LOW); digitalWrite(LED[5], HIGH); digitalWrite(LED[6], HIGH); digitalWrite(LED[7], HIGH); break; case 1: digitalWrite(LED[4], HIGH); digitalWrite(LED[5], LOW); digitalWrite(LED[6], HIGH); digitalWrite(LED[7], HIGH); break; case 2: digitalWrite(LED[4], HIGH); digitalWrite(LED[5], HIGH); digitalWrite(LED[6], LOW); digitalWrite(LED[7], HIGH); break; case 3: digitalWrite(LED[4], HIGH); digitalWrite(LED[5], HIGH); digitalWrite(LED[6], HIGH); digitalWrite(LED[7], LOW); break; } if (BANK_DATA[num] & 1) { digitalWrite(LED[0], LOW); // LEDへの信号をLOW(点灯) } else { digitalWrite(LED[0], HIGH); // LEDへの信号をHIGH(消灯) } if (BANK_DATA[num] >> 1 & 1) { digitalWrite(LED[1], LOW); // LEDへの信号をLOW(点灯) } else { digitalWrite(LED[1], HIGH); // LEDへの信号をHIGH(消灯) } if (BANK_DATA[num] >> 2 & 1) { digitalWrite(LED[2], LOW); // LEDへの信号をLOW(点灯) } else { digitalWrite(LED[2], HIGH); // LEDへの信号をHIGH(消灯) } if (BANK_DATA[num] >> 3 & 1) { digitalWrite(LED[3], LOW); // LEDへの信号をLOW(点灯) } else { digitalWrite(LED[3], HIGH); // LEDへの信号をHIGH(消灯) } }
構造としては、
switch文にて、新たに追加したLED4,5,6,7を点灯する。(点灯しているLED以外は消灯する。)
↓
BANK_DATA[num]に格納しているプログラムデータを分解してそれぞれに対応しているLED及びリレーをONにする。
↓
prg_process関数を抜けて呼び出された位置に戻る。
これでプログラム動作をします。
switch文の使い方
switch文はifなどと同じ条件分岐の命令ですが、非常に明快です。
switch (変数) { case 0: //←変数がゼロならbreak;まで実行して抜けろ digitalWrite(LED[4], LOW); //LED[4]を点灯しろ break; //抜けろ }
これだけの構造です。
0-20までnumが動くときはcase 20:
まで書けば良いのです。
今回のように、numという変数を渡し続けて全体をコントロールするやり方もありますし、可変抵抗やセンサーを読んだ値をswitchで振り分けることも出来ます。
ビットシフト
ビットシフトとは、ビットの桁をずらすことです。
int BANK_DATA[4] = {0x1, 0x3, 0x7, 0xf};
まず最初に定義したBANK_DATA[]という配列は、
[sw0を押したときの(プログラムされている)LED[0,1,2,3]を並べたもの,sw1を押したときの(以下同文)]
です。0x○○と書く場合は、16進数です。つまり、
int BANK_DATA[4] = {0x1, 0x3, 0x7, 0xf};
を2進数で書くと
int BANK_DATA[4] = {0b0001, 0b0011, 0b0111, 0b1111};
という事になります。
(ちなみにこれはテスト用に初期設定しているだけで、最終的には保存→呼び出しという機能をつけます)
ビットシフトはビットずらしとも言います。
0001を右に1つずらすときは、 >> 1
で、左にずらすときは<<
と記述します。
a = 0b0001 >> 1;
とするとa
の中身は0b0000
a = 0b0001 << 1;
とするとa
の中身は0b0010
今回ビットシフトをしているのは、目的の桁の情報(0か1か)を抜き出すためです。
論理積 AND(&)
if (BANK_DATA[num] & 1)
&とは、論理積を表します。
論理積とは、AもBも1なら1、それ以外(1と0,0と1,0と0)のときは0を返す論理演算です。
では、 BANK_DATA[num] & 1
とは何をしているかというと、
BANK_DATA[num](例えば0のときは今回の場合0b0001)と1(0b0001)を論理和しなさい
という事になり、それぞれの桁でANDを計算します。
& 1
とすることで、下一桁が0か1かわかります。