俺はプログラミングもほとんど初心者に等しいので、そっちの方をもう少し勉強しようと思ってます。
Arduino スケッチは C 言語をベースにしているということなので、C 言語も合わせてやっていきましょう。てなことを考えながら、とりあえず何か書いてみるなら FizzBuzz かなとか (^_^;)
FizzBuzz とは、まぁ誰でも知っていると思いますけど、50 まで数えて 3 の倍数のときアホになるというやつです。… じゃぁなくて、100 までカウントして 3 の倍数のとき Fizz 、5 の倍数のとき Buzz、さらに 3 と 5 の倍数のときは FizzBuzz と表示させるといったプログラムのことです。こいつを Arduino でやってみます。
ちょうど 7セグメント LED を使ってみていたので、スタートボタンを押したら 0 から 99 までカウント表示させることにしましょう。3 の倍数のときは FZ 、5 の倍数では BZ 、3 と 5 の倍数のときは FB と表示させることにします。
回路図は以下です。特段変わったところはありません。
Arduino の D9 にタクトスイッチをつなぎ、これを ON するとカウントをスタートさせます。
アノードコモンの 7 セグメント LED 表示器が 2個手元にありますので、これをシフトレジスタ SN74LS164 で表示させます。デジットドライブはこれも手持ちの 2N3906 を使用しています。2SA1015 とかでもいいですね。FET でもかまいません。持っているものを適当に使いましょう。でも Arduino で直接駆動するのはちょっと無理があります。
シフトレジスタと LED の接続は、7ビットのデータを LSBFIRST (最下位ビットから送出) させるつもりなので、Qa の出力を未接続にしています。このあたりはプログラムと整合させないとうまく表示できませんので注意します。
スケッチのフローチャートです。
スイッチの ON を検出して 0 から 99 までカウントします。それを 7 セグメント LED で 2 桁表示させます。十の位が 0 のときは表示しないようにしています。2 桁を 1 ミリ秒ずつ表示して 300 回繰り返すので、約 600 ミリ秒ごとにカウントしていくことになります。
その値の倍数かどうかは剰余が 0 かどうかを判断します。3 と 5 の倍数ということは 15 の倍数ということです。ここが FizzBuzz の肝ですね。それぞれの判定結果に従って、表示する値を変えています。
ん〜、なんかもっとすっきりできそうな気がするけど、いまの俺のレベルではこんなもんでしょ (^_^;)
スケッチです。
じつは、関数の引数とか戻り値とか初めて使ってみたんですよ (^_^;)
// Fizz Buzz on Arduino 2019.06.16 meyon
/* スイッチを押下すると 0 から 99 までカウントする。
3 の倍数のとき FZ 、5 の倍数のとき BZ 、
15 の倍数のとき FB と表示させる。
*/const byte segmentData[14] = {
B1111110, // 0
B0110000, // 1
B1101101, // 2
B1111001, // 3
B0110011, // 4
B1011011, // 5
B1011111, // 6
B1110000, // 7
B1111111, // 8
B1111011, // 9
B1000111, // F
B0011111, // B
B1101100, // Z
B0000000 // blank
};const int startPin = 9;
const int driverPin[2] = {10, 11};
const int clockPin = 12;
const int dataPin = 13;
int judgeNumber(int value) {
int result;
if(value == 0) {
result = 0;
} else if(value % 15 == 0) {
result = 15;
} else if(value % 5 == 0) {
result = 5;
} else if(value % 3 == 0) {
result = 3;
} else {
result = value;
}
return result;
}
void displayNumber(int value) {
int digit[2];
if(value == 15) {
digit[0] = 11; // B
digit[1] = 10; // F
} else if(value == 5) {
digit[0] = 12; // Z
digit[1] = 11; // B
} else if(value == 3) {
digit[0] = 12; // Z
digit[1] = 10; // F
} else {
digit[0] = value % 10;
if(value / 10 == 0) {
digit[1] = 13; // 10 digit is blank
} else {
digit[1] = value / 10;
}
}int j=0;
while(++j < 300) { // Display cycle
for(int i=0; i<2; i++) {
shiftOut(dataPin, clockPin, LSBFIRST, ~segmentData[digit[i]]);
digitalWrite(driverPin[i], LOW);
delay(1);
digitalWrite(driverPin[i], HIGH);
}
}
return;
}void setup() {
pinMode(startPin, INPUT);
pinMode(driverPin[0], OUTPUT);
pinMode(driverPin[1], OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);digitalWrite(driverPin[0], HIGH);
digitalWrite(driverPin[1], HIGH);
}
void loop() {
if(digitalRead(startPin) == LOW) {
for(int i=0; i<100; i++) {
int value = judgeNumber(i);
displayNumber(value);
}
}
}
ついでにブレッドボードです。
7 セグメント LED がピンが左右についている品物なので 2桁並べて置けません。ご愛嬌です。
回路図にはありませんが、IC の電源には 0.1μF のコンデンサをつけてます。またブレッドボードの電源ラインには 10μF 程度の電解コンデンサを置くようにしています。
電源が写真にはありませんが、12V の AC アダプタの出力から 3 端子レギュレータで 5V を作っています。Arduino の電源は 12V を Vin に供給しています。ただ、USB ケーブルを挿したまま AC アダプタを切っちゃうと Vin から 5V が逆流してしまうので、12V ラインにダイオードを入れて阻止しています。まぁ小ネタですけど。