基礎 · 読了まで13分

ブロックプログラミングのループと変数:Arduinoのforループと配列

ブロックプログラミングのループと変数を解説。「ずっと繰り返す」とloop()、カウントブロックとArduinoのforループ、配列とカウンターを、流れるLEDのブロックとC++のコードで比べます。

ブロックプログラミングのループと変数は、プログラムを「1回だけ実行する」ものから「賢く実行し続ける」ものに変える2つの基本要素です。ループ(繰り返し)は同じブロックを何度も実行し、変数はその繰り返しの間、数値を覚えておきます。BlueGraysのブロックでは、これらは「ずっと繰り返す」「i を … ずつ変えて数える」「グローバル変数(最初に宣言)」「… に … を代入」として登場します。ボードに書き込むArduinoのコードでは、それぞれloop()、forループ、int型の変数、代入の行に当たります。

この記事はブロックからコードへシリーズの第4回です。前回はボタンとifブロックをif/elseと対応させました。次回はブロックでのセンサーの読み取りと、PicoでのMicroPythonへの移行を取り上げます。

今回は、4つの無料プロジェクトのブロックを、実際のC++コードと並べて読んでいきます。6個のLEDを順番に点灯させる流れるLED、ポテンショメーターで速度を変える速度調整できる流れるLED、光を端から端まで往復させるKnight Rider風LED、そしてそのポテンショメーター版の速度調整できるKnight Rider風LEDです。4つとも同じ回路を使います。D2〜D7ピンに6個のLED、A0にポテンショメーターが1個です。最後に自分でカウンターの例を書き、初心者がよくする3つの間違い、つまり1回多く、または1回少なく数えてしまうこと、配列の末尾を越えてしまうこと、ボタンの入力を見逃す原因になる長い待ち時間を順に見ていきます。

「ずっと繰り返す」ブロックとloop():ボードはなぜ止まらないのか

パソコンのプログラムは仕事が終われば閉じますが、Arduinoのプログラムは閉じません。ボードにはOSがなく、プロセッサーにはほかにすることがないからです。そのため、ブロックのプロジェクトはどれも同じ骨組みになっています。「セットアップ(1回だけ実行)」の中身は、ボードに電源が入ったときかリセットボタンが押されたときに1回だけ実行され、「ずっと繰り返す」の中身は上から下まで止まらずに繰り返されます。C++側では、これがsetup()関数とloop()関数です。loop()の最後の行が終わると、ボードはすぐに最初の行へ戻ります。待ち時間のない短いloop()なら、1秒間に数万回実行されることもあります。ボードを止める方法は、電源を切るか、新しいプログラムを書き込むことだけです。この終わりのない繰り返しは欠陥ではなく、そういう設計です。ボタンの読み取りも、センサーの監視も、LEDの点滅も、1周ごとにやり直されるので、ボードは周りの変化に反応し続けられます。

ブロックC++での対応いつ実行される?
グローバル変数(最初に宣言)setup()より上の行プログラム開始時に1回。変数はメモリに残る
セットアップ(1回だけ実行)void setup() { ... }電源投入時かリセット後に1回
ずっと繰り返すvoid loop() { ... }setup()の終了後、電源が切れるまでずっと

ブロックプログラミングの変数:グローバル変数と宣言ブロック

変数は、数値を入れて名前で呼び出す小さな箱です。ブロックでは、変数は紫色の「グローバル変数(最初に宣言)」ブロックの中で作ります。その中にある「宣言:整数(int) potValue = 0」ブロックは、コードではint potValueという行になります。intが型、potValueが名前、0が初期値です。「最初に宣言」という部分が大事で、これらの行はファイルのいちばん上、setup()とloop()の外に置かれます。このように宣言したグローバル変数は、プログラムのどこからでも見え、loop()が最初からやり直されるたびに値を失うこともありません。Arduino Unoではintは2バイトで、-32768から32767までの整数を扱えます。analogRead()の0〜1023の範囲やピン番号には十分すぎるほどです。速度調整できる流れるLEDのブロックではpotValue = 0となっているのに、コードではint potValue;としか書かれていないことに気づくかもしれません。どちらも結果は同じです。C++では、初期値のないグローバル変数はゼロから始まります。

変数の値をあとから変えるブロックは「… に … を代入」です。「potValue に A0 をアナログ読み取り を代入」ブロックは、コードではpotValue = analogRead(A0);になります。ここでの=は数学の等号ではなく、「右側の値を計算して、左側の箱に入れる」という意味です。2つの値が等しいかどうかを調べる比較は、C++では==と書きます。これはシリーズの前回、ifブロックで見ました。代入ブロックが実行されると、箱の古い値は消えて新しい値が書き込まれます。その変数を読むブロックは、どれもこの新しい値を使います。「potValue ms待つ」は、その時点でpotValueに入っているミリ秒数だけ待ちます。

回数を決めた繰り返し:「i を … ずつ変えて数える」ブロックとArduinoのforループ

決まった回数だけ繰り返すには、緑色の「i を 0 から 5 まで 1 ずつ変えて数える」ブロックを使います。このブロックはiというカウンターを作って0にし、中のブロックを実行したあとiに1を足してもう一度実行し、iが5を超えるまでこれを続けます。Arduinoでの対応はfor (int i = 0; i < 6; i++)という行です。かっこの中にはセミコロンで区切られた3つの部分があります。開始(int i = 0)、続ける条件(i < 6)、そして1周ごとに行う更新(i++、つまりiに1を足す)です。いちばん注意したいのは、ブロックの終了値はその値自体を含むという点です。「0 から 5 まで」は0、1、2、3、4、5を意味するので、ループは5回ではなく6回実行され、6個のLEDそれぞれに1回ずつ順番が回ります。だからコードではi < 6と書かれていて、これはi <= 5と同じ意味です。「ゼロから始めて、要素の数より小さい間は続ける」という書き方は、6という数字がそのままLEDの個数を表すので、Arduinoのコードでとてもよく使われます。

ブロックの設定同じ意味のC++iの値周回数
0から5まで1ずつfor (int i = 0; i < 6; i++)0, 1, 2, 3, 4, 56
0から5まで2ずつfor (int i = 0; i <= 5; i += 2)0, 2, 43
4から1まで1ずつfor (int i = 4; i > 0; i--)4, 3, 2, 14
1から6まで1ずつfor (int i = 1; i <= 6; i++)1, 2, 3, 4, 5, 66(ただしledPins[6]は存在しない)

配列ブロック:「配列 2 3 4 5 6 7」とledPins[i]

6個のLEDのために6つの変数を別々に宣言する代わりに、すべてを1つのリストにまとめられます。紫色の「配列 2 3 4 5 6 7」ブロックを「宣言:整数(int) ledPins = …」につなぐと、コードではint ledPins[] = {2, 3, 4, 5, 6, 7};という行になります。角かっこは配列であることを示し、波かっこの中に値が入ります。要素には位置の番号、つまりインデックスでアクセスします。C++ではインデックスは0から始まります。最初の要素はledPins[0]、最後の要素はledPins[5]です。ブロックでは「ledPins の i 番目の要素」がこれを行い、ledPins[i]になります。カウントのループも0から始まるので、両者はぴったり合います。1周ごとにiが次のインデックスを与え、ledPins[i]がそこに入っているピン番号を返します。配列のもう1つの便利な点は、LEDの順番を変えたいとき、ループには手を付けずにリストの数字を入れ替えるだけで済むことです。配列について詳しくはArduinoの配列を参照してください。

i(インデックス)ledPins[i]点灯するLED
02LED 1(D2)
13LED 2(D3)
24LED 3(D4)
35LED 4(D5)
46LED 5(D6)
57LED 6(D7)

流れるLED:ブロックとC++を1行ずつ

流れるLEDプロジェクトのブロック:配列、カウントのループ、ずっと繰り返す
流れるLEDのブロック。グローバル変数の下にledPins配列があり、セットアップの中のカウントループでピンを出力にし、「ずっと繰り返す」の中の2つ目のカウントループでLEDを1個ずつ150 ms点灯させます。
C++ (Arduino IDE)
1int ledPins[] = {2, 3, 4, 5, 6, 7};   // LED pinleri, yanma sırasıyla / LED pins in lighting order
2
3void setup() {
4  // Tüm LED pinlerini çıkış yap / Set all LED pins as outputs
5  for(int i = 0; i < 6; i++) {
6    pinMode(ledPins[i], OUTPUT);
7  }
8}
9
10void loop() {
11  // Her LED'i sırayla 150 ms yak / Light each LED in turn for 150 ms
12  for(int i = 0; i < 6; i++) {
13    digitalWrite(ledPins[i], HIGH);
14    delay(150);
15    digitalWrite(ledPins[i], LOW);
16  }
17}
ブロックC++の行動作
宣言:整数(int) ledPins = 配列 2 3 4 5 6 7int ledPins[] = {2, 3, 4, 5, 6, 7};6つのピン番号を点灯する順に保存
セットアップ(1回だけ実行)void setup() {中身は起動時に1回だけ実行
i を 0 から 5 まで 1 ずつ変えて数えるfor(int i = 0; i < 6; i++) {iを0から5まで数える:6周
ピン ledPins の i 番目の要素 を 出力 に設定pinMode(ledPins[i], OUTPUT);現在のピンを出力にする
ずっと繰り返すvoid loop() {中身を止まらずに繰り返す
ピン ledPins の i 番目の要素 に HIGH を書き込むdigitalWrite(ledPins[i], HIGH);現在のLEDを点灯
150 ms待つdelay(150);LEDが150 ms点灯したまま
ピン ledPins の i 番目の要素 に LOW を書き込むdigitalWrite(ledPins[i], LOW);LEDを消灯し、ループは次のLEDへ進む

プログラムを時間の流れとして考えてみましょう。ボードが起動すると、セットアップの中のループが0から5まで順に6つのピンを出力にします。これは二度と行われません。次に「ずっと繰り返す」が始まります。中のカウントループがD2のLEDを点灯し、150 ms待って消し、同じことをD3、D4、D5、D6、D7でも繰り返します。1周は6 × 150 = 900 msです。最後のLEDが消えるとloop()が終わり、ボードはすぐに先頭へ戻って、光は再びD2から始まります。周回の間にすき間がないので、光は止まらずに流れているように見えます。速度を変えるには、150という数字を1つ変えるだけです。50にすれば光は3倍速く走り、500にすればゆっくり進みます。この固定の速度をつまみで調整できるようにすると、次のプロジェクトになります。

速度調整できる流れるLED:ポテンショメーターの値が待ち時間になる

速度調整できる流れるLEDのブロック:potValue変数とA0のアナログ読み取り
速度調整できる流れるLED。カウントループの1周ごとにA0のアナログ読み取りの値がpotValueに入り、LEDはpotValueミリ秒だけ点灯します。
C++ (Arduino IDE)
1int ledPins[] = {2, 3, 4, 5, 6, 7};   // LED pinleri, yanma sırasıyla / LED pins in lighting order
2int potValue;                         // Pot değeri = bekleme (ms) / Pot value = delay (ms)
3
4void setup() {
5  // Tüm LED pinlerini çıkış yap / Set all LED pins as outputs
6  for(int i = 0; i < 6; i++) {
7    pinMode(ledPins[i], OUTPUT);
8  }
9}
10
11void loop() {
12  for(int i = 0; i < 6; i++) {
13    potValue = analogRead(A0);        // Hızı oku (0-1023) / Read the speed (0-1023)
14    digitalWrite(ledPins[i], HIGH);
15    delay(potValue);                  // Pot değeri kadar ms bekle / Wait as many ms as the pot value
16    digitalWrite(ledPins[i], LOW);
17  }
18}

流れるLEDとの違いは、新しい2つのブロックだけです。グローバル変数に「宣言:整数(int) potValue = 0」が加わり、カウントループの最初に「potValue に A0 をアナログ読み取り を代入」ブロックが入っています。analogRead(A0)は、ポテンショメーターの真ん中のピンの電圧を0〜1023の数値に変換します。その数値がそのまま「potValue ms待つ」、つまりdelay(potValue)の行に渡されます。つまみを一方の端まで回すと各LEDが約1秒(1023 ms)点灯し、1周に約6秒かかります。反対の端まで回すと待ち時間は0になり、LEDの切り替わりが速すぎて、全部が同時にうっすら光っているように見えます。ループの中でLEDごとにポテンショメーターを読むのは、意図的な選択です。つまみを回した瞬間から次のLEDが新しい速度を使うので、1周が終わるのを待つ必要がありません。ポテンショメーターの仕組みはポテンショメーターとは?で確認できます。

ナイトライダー:前に数えるループと後ろに数えるループ

Knight Rider風LEDプロジェクトのブロック:0から5まで数えるループと4から1まで数えるループ
Knight Rider風LEDのブロック。「ずっと繰り返す」の中に2つのカウントループがあります。1つ目は0から5まで数えて光をD2からD7へ動かし、2つ目は4から1まで逆に数えて光をD6からD3へ戻します。

ナイトライダーの効果では、光が端から端まで進み、また戻ってきます。Knight Rider風LEDのブロックでは、「ずっと繰り返す」の中に2つのカウントループが上下に並んでいます。1つ目はおなじみの「i を 0 から 5 まで 1 ずつ変えて数える」で、光をD2からD7へ動かします。2つ目は「i を 4 から 1 まで 1 ずつ変えて数える」です。開始値が終了値より大きいので、ブロックは逆向きに数え、iは4、3、2、1になります。コードではfor(int i = 4; i > 0; i--)の行で、i--はiから1を引きます。なぜ5から0ではなく、4から1なのでしょうか。ledPins[5](D7)は往路の最後に、ledPins[0](D2)は次の往路の最初に、すでに点灯するからです。帰り道で両端を飛ばすと、端のLEDが2回続けて点灯することがなくなり、折り返しがなめらかに見えます。1往復は6 + 4 = 10ステップで、1ステップが100 msなので合計1秒です。速度調整できるKnight Rider風LEDも同じ2つのループを使います。違いは、両方のループの最初に「potValue に A0 をアナログ読み取り を代入」ブロックを加え、100 msの代わりに「potValue ms待つ」を使う点だけです。ほかのパターンはArduinoでナイトライダー風LEDを見てください。

自分で作るカウンターの例:周回カウンターとシリアルポート

では、これまでの内容をすべて組み合わせた小さな例を書いてみましょう。流れるLEDが1周するたびにカウンターが1増え、ボードはiの値と周回数の両方をパソコンに送ります。画像のブロックを使うなら、次のように組み立てます。グローバル変数のledPins配列の下に「宣言:整数(int) rounds = 0」を追加します。セットアップには「シリアル通信を 9600 ボーで開始」ブロックを入れます。カウントループの中、LEDが点灯する前に「シリアル出力」ブロックを置き、文字列「i = 」、続いてi、続いて文字列「 pin = 」を「改行なし」の設定で出力し、最後に「ledPins の i 番目の要素」を「改行あり」の設定で出力します。カウントループのあと、まだ「ずっと繰り返す」の中で、「rounds に … を代入」ブロックにrounds + 1の合計を渡し、周回数を「シリアル出力 … 改行あり」で出力します。

C++ (Arduino IDE)
1int ledPins[] = {2, 3, 4, 5, 6, 7};   // LED pinleri / LED pins
2int rounds = 0;                       // tamamlanan tur sayısı / number of finished rounds
3
4void setup() {
5  Serial.begin(9600);                 // seri port 9600 baud / serial port at 9600 baud
6  for (int i = 0; i < 6; i++) {
7    pinMode(ledPins[i], OUTPUT);
8  }
9}
10
11void loop() {
12  for (int i = 0; i < 6; i++) {
13    Serial.print("i = ");             // aynı satırda kal / stay on the same line
14    Serial.print(i);
15    Serial.print("  pin = ");
16    Serial.println(ledPins[i]);       // alt satıra geç / new line
17    digitalWrite(ledPins[i], HIGH);
18    delay(300);
19    digitalWrite(ledPins[i], LOW);
20  }
21  rounds = rounds + 1;                // sayacı bir artır / add one to the counter
22  Serial.print("Tur / Round: ");
23  Serial.println(rounds);
24}

書き込みが終わったら、Arduino IDEでシリアルモニタを開き、9600ボーに設定します。1周ごとに「i = 0 pin = 2」から「i = 5 pin = 7」までの6行が表示され、そのあとに1、2、3と数える「Tur / Round」の行が続きます。この出力は、カウントブロックの終了値が含まれることのいちばんわかりやすい証拠です。「0 から 5 まで」からは、ちょうど6つの値が出てきます。また、roundsがグローバル変数の中で宣言されている点にも注目してください。loop()が始まるたびにリセットされないので、値が周回から周回へ引き継がれます。1周は6 × 300 = 1.8秒なので、intの上限32767には約16時間で達します。もっと長く数える必要があるなら、変数をunsigned longにしてください。シリアルモニタについて詳しくはArduinoのシリアルモニタにあります。

回路:LED 6個、220 Ωの抵抗、ポテンショメーター

部品接続(Arduino Uno)コード上
LED 1D2 → 220 Ω → LEDのアノード(長い足)、カソード → GNDledPins[0]
LED 2D3 → 220 Ω → アノード、カソード → GNDledPins[1]
LED 3D4 → 220 Ω → アノード、カソード → GNDledPins[2]
LED 4D5 → 220 Ω → アノード、カソード → GNDledPins[3]
LED 5D6 → 220 Ω → アノード、カソード → GNDledPins[4]
LED 6D7 → 220 Ω → アノード、カソード → GNDledPins[5]
ポテンショメーター(10 kΩ)一方の端を5V、真ん中のピンをA0、もう一方の端をGNDへanalogRead(A0)(速度調整できるプロジェクトのみ)

220 Ωの抵抗を使うと、5 Vで点灯させる赤色LEDには約(5 − 2)/ 220 ≈ 14 mAの電流が流れます。これはLEDにもArduinoのピンにも安全な値です。ほかの色のLEDを使う場合は、LED抵抗計算ツールで抵抗値を確認してください。すべてのカソードをブレッドボードのGNDのラインにまとめ、そのラインをArduinoのGNDピンにつなぎます。ポテンショメーターの両端の足を入れ替えても、何も壊れません。つまみを回す向きが逆になるだけです。流れるLEDとナイトライダーのプロジェクトはポテンショメーターを使いませんが、つないだままでも問題ないので、同じ回路で4つのプロジェクトを順番に試せます。

ループと変数のよくある間違い

間違い症状対処
1回多く数える:「0 から 6 まで」ループが7回実行され、最後の周回で存在しないledPins[6]を読む終了値は含まれる。LED 6個なら0から5(コードではi < 6)
インデックスを1から始めるD2の最初のLEDが一度も点灯せず、最後の周回で配列の外に出る配列のインデックスは0から始まるので、カウントブロックも0から始める
配列の末尾を越える関係のないピンが切り替わったり、プログラムがおかしな動きをしたりする。C++は配列の範囲をチェックしないインデックスは常に0から「要素数 − 1」の範囲に収める
カウンターをloop()の中で宣言する1周ごとにカウンターが0に戻り、いつも1と表示されるカウンターは「グローバル変数(最初に宣言)」ブロックで宣言する
セットアップのループを短くしすぎる(0から4)最後のLEDのピンが出力に設定されないため、とても暗く光るか、まったく点灯しないセットアップと「ずっと繰り返す」のカウント範囲は同じにする
代入と比較を混同するif (potValue = 0)は常に偽になり、値も消してしまう代入は=、比較は==
長い待ち時間は、ボタンの入力を見逃す原因になります。「… ms待つ」ブロック、つまりdelay()は、実行中ボードを完全に止めてしまい、その間はボタンも読まれず、センサーも確認されません。速度調整できる流れるLEDでつまみをいっぱいまで回すと、1周に約6秒かかります。このプロジェクトにボタンを追加して各周の最初に読むようにすると、短く押した操作はたいてい待ち時間の最中に来てしまい、見逃されます。対策は、時間を測って待つことです。millis()を使って「前回LEDを切り替えてから十分な時間がたったか」を確かめ、その間もボタンを読み続けます。この方法はmillis()とdelay()の違いで順を追って説明しています。

BlueGraysアプリでループと変数のブロックを見る

この記事の4つのプロジェクトと以下のプロジェクトは、BlueGraysアプリでブロックもコードも完全に無料です。プロジェクトのコード画面でブロックで表示スイッチをオンにすると、コードが同じプログラムのブロックに置き換わります。画像をタップすると全画面で開き、長いカウントループも拡大して楽に見られます。ブロック解説タブでは、プログラムを1ステップずつ、そのステップのブロックと動作だけを表示しながら案内します。ほかにもブロックで見る価値のある無料プロジェクトがあります。delayTime変数と2つのカウントループで動くLEDの警察車両風点滅、「ずっと繰り返す」の中で4つの状態を順に進む信号機、読み取った値を変数に保存してシリアルポートに出力するLDRで光の強さを測定、そしてLEDの状態を変数で覚えておくボタンでLEDの点灯・消灯を切り替えです。コードガイドのArduinoの例もすべてブロックで表示でき、今日のクイズでは、A1からC2まで1日5問で学んだことを定着させられます。ブロックのプロジェクトの一覧はブロックプログラミングのページにあります。ブロックがそのままボードに書き込まれるわけではありません。ボードに入るのは常にプロジェクトの実際のコードなので、ブロックで理解したプログラムをArduino IDEにコピーしてボードに書き込みます。

ループと変数がわかったら、次はその数値を現実の世界から取り込む番です。シリーズの第5回ではブロックでのセンサーの読み取り、シリアルポート、PicoでのMicroPythonへの移行を取り上げます。それまでに、BlueGraysアプリで流れるLED、ナイトライダー、そしてそれぞれの速度調整版を回路図とコード付きで見てみてください。ブロックで表示でブロックに、ブロック解説でステップごとの説明に切り替え、各カウントループがコードのどの行に当たるのかを自分で追ってみましょう。

よくある質問

ブロックプログラミングのループとは何ですか?

ループ(繰り返し)とは、中に入れたブロックを何度も実行するブロックです。BlueGraysでは主に2種類あります。「ずっと繰り返す」はプログラムのメインループで、ボードに電源が入っている間は止まりません。一方、「i を … ずつ変えて数える」は決まった回数だけ繰り返します。Arduinoのコードでは、それぞれloop()関数とforループに当たります。

Arduinoのforループはどう書きますか?

forループのかっこの中には、セミコロンで区切られた3つの部分があります。int i = 0でカウンターを開始し、「iが6より小さい間は続ける」のような条件でループを続ける長さを決め、i++で1周ごとにカウンターに1を足します。このループはiを0から5まで数え、波かっこの中のコードを6回実行します。ブロックでは「i を 0 から 5 まで 1 ずつ変えて数える」が同じ働きをします。

「0 から 5 まで」のカウントブロックは何回実行されますか?

6回です。BlueGraysのカウントブロックの終了値はその値自体を含むので、iは0、1、2、3、4、5と順に変わります。コードでは、iが6より小さい間実行されるforループとして表され、6要素の配列のすべてのインデックスをちょうど1回ずつたどります。

ブロックプログラミングで変数を作るにはどうしますか?

「グローバル変数(最初に宣言)」ブロックの中に「宣言:整数(int) … = …」ブロックを置き、変数に名前と初期値を付けます。これでコードの先頭に、int potValue = 0;のようなグローバル変数の行ができます。値はあとから「… に … を代入」ブロックで変更します。

Arduinoのloop()は止められますか?

loop()は自分では止まりません。最後の行が終わると、すぐにまた始まります。ボードを完全に止めるには、電源を切るか、別のプログラムを書き込む必要があります。何かを1回だけ実行したいなら、setup()、つまり「セットアップ(1回だけ実行)」ブロックに入れるか、変数を使ってすでに実行したかどうかを確認します。

Arduinoの配列のインデックスはなぜ0から始まるのですか?

CとC++では、インデックスは要素が配列の先頭から何ステップ離れているかを表します。最初の要素は先頭そのものにあるので、インデックスは0です。そのため、6要素のledPins配列のインデックスは0から5までになります。ledPins[6]と書くと配列の末尾を越えてしまいますが、C++はそれをチェックしてくれません。

全プロジェクトを見る
流れるLED
#5中級

流れるLED

LEDが次々に点灯し、光が走るように進みます。Arduinoが6個のLEDを1個ずつ短く点灯して消灯させることで、光が端から端へと移動し、また最初に戻ります。この簡単なプロジェクトで、1つのパターンで複数の光を制御する方法を学びます。

4.6(85)
207
Knight Rider風LED
#6中級

Knight Rider風LED

Knight Riderでおなじみの、光が左右に往復する動きです。6個のLEDの上を光の点が端から端へ進み、折り返します。Arduinoが各LEDを10分の1秒ずつ点灯させ、端に着くたびに向きを変えて往復し続けます。装飾用の照明や警告灯作りの第一歩にぴったりです。

4.8(106)
202
速度調整できる流れるLED
#7中級

速度調整できる流れるLED

6個のLEDが順番に点滅し、光が端から端へ走るように見えます。ポテンショメーターのつまみを回すと、その速さがすぐに変わります。一方に回すと光が素早く進み、反対に回すと各LEDが1秒近く点灯します。つまみで動きの速さを調整する仕組みを目で確かめられます。

4.6(72)
146
速度調整できるKnight Rider風LED
#8中級

速度調整できるKnight Rider風LED

6個のLEDの上を光が端から端へ走り、折り返して戻ってきます。ポテンショメーターのつまみを回すと、その速さをすぐに調整できます。つまみを一方の端にすると光が飛ぶように進み、反対の端にするとゆっくり進みます。1つのつまみで動作中のアニメーションを操る楽しさを体験できます。

4.5(60)
120
LEDの警察車両風点滅
#4初級

LEDの警察車両風点滅

警察車両の警光灯のように、赤いLEDが素早く3回点滅し、続いて青いLEDが3回点滅します。このパターンを途切れることなく繰り返します。Arduinoに2個のLEDと2個の抵抗をつなぐだけで、数分で組み立てられる、目を引く入門プロジェクトです。

4.7(103)
258
信号機
#3初級

信号機

毎日道路で見かける信号機の小さな模型です。赤が2秒点灯し、黄が一瞬点灯した後、緑が2秒点灯します。その後、再び黄を経て赤に戻り、この動作を繰り返します。3個のLEDを順番に点けたり消したりしながら、タイミングの組み立て方を学びます。

4.8(131)
397
LDRで光の強さを測定
#11初級

LDRで光の強さを測定

部屋の明るさを数値で見てみませんか?光に反応する小さな部品、LDRで周囲の光を測定し、Arduinoが0.5秒ごとにその値をコンピューターの画面に表示します。手で覆うと数値が変わる様子を確認できます。自動で点灯する常夜灯などのプロジェクトへの第一歩です。

4.6(81)
139
ボタンでLEDの点灯・消灯を切り替え
#10初級

ボタンでLEDの点灯・消灯を切り替え

部屋の照明スイッチのように、ボタンを1回押すと点灯し、もう1回押すと消灯します。Arduinoはボタンが押されるたびにLEDの状態を反転させます。ボタン内部の小さな接点の振動で誤動作しないよう、短い待ち時間も設けます。1つのボタンでオン・オフを切り替える、シンプルな仕組みです。

4.8(100)
167