このページの本文へ

秋の夜長に楽しむ電子工作 “Lチカ”から1歩先へ

40代、Arduinoをイチから始めてみる【Arduinoいまさら超入門】

2016年09月09日 09時00分更新

文● 宮里圭介 編集●北島幹雄/ASCII STARTUP

  • この記事をはてなブックマークに追加
  • 本文印刷

自分で用意したLEDを光らせてみる

 さて、この「Blink」というスケッチをArduinoに書き込むと、基板上のLEDが点滅するわけですが……これでLチカができたというには、あまりにも何もやっていません。そこで、小さなブレッドボードを使って、別のLEDを光らせてみましょう。

 まずはLEDと抵抗、ブレッドボード、ジャンプワイヤーを用意します。ここでは330Ωの抵抗を用意しましたが、抵抗の値はLEDによって変わってきますので、まずはこの計算方法を解説しておきます。

 使用するLEDの順方向電圧が2V、最大電流が20mA、ArduinoのIO出力が5Vの場合を考えてみましょう。抵抗にかかる電圧はLEDの順方向電圧ぶん電圧が降下すると考えられるので、5Vから2Vを引いた3Vとなります。ここを流れる電流が20mA未満になればいいのですから、抵抗は150Ω以上となるわけです。上限ギリギリで使うのは怖いので、できれば200Ω以上にするといいですね。

必要な抵抗値の計算方法

 ちなみに、今回使用したGenuino 101のIO出力は3.3Vです。この場合、3.3VからLEDの順方向電圧2Vを引いた1.3Vで20mA未満となればいいのですから、抵抗値は65Ω以上を選べばいいことになります。

 とはいえ、最大電流近くでLEDを光らせると大抵まぶしく、見づらいことが多くあります。輝度を低くしたい場合は抵抗値を大きくし、LEDに流れる電流を小さくすることで暗くしてあげましょう(実際、今回は330Ωを使っています)。ちなみに、LEDはあるけどスペックがよくわからないという場合は、とりあえず300~1kΩくらいの抵抗を使っておけばだいたい大丈夫です。

 配線はとてもシンプルで、ブレッドボードに抵抗とLEDを直列に接続。あとはArduinoの13番ピンとGNDをジャンプワイヤーでArduinoと接続するというだけです。

ブレッドボード上で、抵抗とLEDを接続

ジャンプワイヤーで「13」と「GND」を接続

 ブレッドボードは内部でピンが一列に接続されているので、実際の回路図とブレッドボード上の回路を合わせるみると、このような感じになっているわけですね。

 これで「Blink」を動かすと、基板上のLEDだけでなくブレッドボード上のLEDも点滅するようになったハズです。

ブレッドボードのLEDが光る!

 ここまでで、Blinkという“ソフト”と、LEDの接続という“ハード”の両方を作ったことになります。立派な電子工作です。とはいえ、これだけではただの動作確認みたいなものですので、もう少しちゃんと機能があるものを考えてみましょう。

ステップ1:3分でLEDがすべて消える「3分タイマー」を作る

 イチから何かを作るのは難しいので、先ほどのLチカを応用したものとして「3分タイマー」を作ってみましょう。動作としては、1分経つごとにLEDが消えていき、すべてのLEDが消えれば3分が経過したとわかるというものです。砂時計みたいなものですね。

 まずはハードの設計から。ブレッドボード上にLEDを3つ並べ、それぞれが光るように抵抗を入れて配線します。先ほどのLチカでは13番ピンを使いましたが、今回はそれに加え、12番と8番も使います。(ちなみに、単機能のデジタル入出力ピンを優先して使っているだけなので、どの番号でも大丈夫です)

 次はソフトの設計です。こちらもLチカで使った「Blink」を元に作っていきます。ポイントは、LEDを3つ光らせるためピンの出力をそれぞれ設定することと、「delay()」で1分待つようにすることです。

// LEDを接続するピンを設定
int LED_1 = 13;
int LED_2 = 12;
int LED_3 = 8;

void setup() {
  // ピンのモードを出力に設定
  pinMode(LED_1, OUTPUT);
  pinMode(LED_2, OUTPUT);
  pinMode(LED_3, OUTPUT);
}

void loop() {
  digitalWrite(LED_1, HIGH);  //LED_1を光らせる
  digitalWrite(LED_2, HIGH);  //LED_2を光らせる
  digitalWrite(LED_3, HIGH);  //LED_3を光らせる

  delay(60000);              //1分待つ
  digitalWrite(LED_1, LOW);   //LED_1を消灯

  delay(60000);              //1分待つ
  digitalWrite(LED_2, LOW);   //LED_2を消灯

  delay(60000);              //1分待つ
  digitalWrite(LED_3, LOW);   //LED_3を消灯

  delay(3000);              //終了後、3秒待つ
}

 最初にある「int」では、整数変数としてLED_1からLED_3までを宣言しています。これはそのままLEDが接続してあるピン番号になっているもので、どのLEDを点灯、消灯するのかわかりやすくするものです。「12番」っていってもわかりにくいですが、「LED_2」といわれれば、2つ目のLEDだとすぐにわかりますよね。

 続く「setup()」では、Lチカでは1つだけだったピンの設定を3つ行っています。

 そしてメインとなる「loop()」。実はLチカとほとんど同じで、違う事といえば、delay()で待つ時間を1分(60秒)にしていることと、消灯するLEDを1つずつ変えているくらいです。

 実際に動かしてみると、時間が経過するごとにLED_1から順に1つずつ消灯していく様子がわかると思います。

ステップ2:スタートスイッチの追加で使いやすく

 ステップ1で3分タイマーは完成していますが、実は、タイマーの開始を指定できないという大きな問題があります。さらに、3つ目のLEDが消えた後、3秒経つとまた3分タイマーが自動で動き出すという、エンドレス砂時計のような動作もいただけません。

 そこでスタートスイッチを追加、自由にタイマーを開始できるようにしてみましょう。もちろん、3分カウントした後は、再度スイッチを押すまで開始されないようになります。

 まずはハードの改造からです。ステップ1で作ったブレッドボードにタクトスイッチ(押している間だけオンになるスイッチ)を追加し、2番ピンとGND(グラウンド)を接続します。

 これでハードの改造はおしまいです。こんな簡単でいいのかと心配になるほどですが、大丈夫です。続いてソフトを改造してみましょう。改造といっても、追加するのはたったの3行です。

// 使用するピンを設定
int LED_1 = 13;
int LED_2 = 12;
int LED_3 = 8;
int SW = 2;

void setup() {
  // ピンのモードを設定
  pinMode(LED_1, OUTPUT);
  pinMode(LED_2, OUTPUT);
  pinMode(LED_3, OUTPUT);
  pinMode(SW, INPUT_PULLUP);
}

void loop() {
  while (digitalRead(SW) == HIGH){}  //スイッチが押されるのを待つ

  digitalWrite(LED_1, HIGH);  //LED_1を光らせる
  digitalWrite(LED_2, HIGH);  //LED_2を光らせる
  digitalWrite(LED_3, HIGH);  //LED_3を光らせる

  delay(60000);              //1分待つ
  digitalWrite(LED_1, LOW);   //LED_1を消灯

  delay(60000);              //1分待つ
  digitalWrite(LED_2, LOW);   //LED_2を消灯

  delay(60000);              //1分待つ
  digitalWrite(LED_3, LOW);   //LED_3を消灯

  delay(3000);              //終了後、3秒待つ
}

 まず最初の追加部分ですが、これはLEDと同じく、スイッチに使うピン番号を代入しているだけなので、大丈夫かと思います。

>int SW = 2;

次の追加行はLEDと少し違っています。

>  pinMode(SW, INPUT_PULLUP);

スイッチはLEDと違って入力として使うために「INPUT」としているわけですね。ここで気づいたかと思いますが、ただのINPUTではなく、「INPUT_PULLUP」としています。これは、何も入力がない場合HIGHなのかLOWなのか不安定になってしまうのを、内部でHIGHに固定する(プルアップ抵抗を追加する)ものです。簡単な回路図で説明すると、以下のようなものとなります。

 自分でプルアップ抵抗を入れてもいいのですが、せっかくあるArduinoにある機能なので使わない手はありません。

 3つ目の追加行は、スイッチが押されるまで待つというものです。

>  while (digitalRead(SW) == HIGH){}

 「while」は、カッコ内の条件が満たされている間、波カッコ内を繰り返すというものです。また「digitalRead()」は、指定した入力ピンの状態を読み出してくれます。

 つまりこの行では、「digitalRead(SW)」でスイッチの状態を読み出し、これが「HIGH」の状態であれば波カッコ内を繰り返すという動作になっているわけです。ここで注目したいのが、波カッコ内には何も書かれていないこと。つまり、スイッチがHIGHの間は何もせずにひたすら待つだけです。

 ここで実際の動作を考えてみましょう。スイッチのピンはプルアップされているので、スイッチが押されてないときはHIGHなので、ひたすら待つことになります。スイッチを押すとGNDに接続されるのでLOWとなり、タイマーが動き出すという動作が実現できるわけです。

カテゴリートップへ

注目ニュース

ASCII倶楽部

プレミアムPC試用レポート

ピックアップ

ASCII.jp RSS2.0 配信中

ASCII.jpメール デジタルMac/iPodマガジン