本文へ移動
結局、そのピンは
「送る係」か「受け取る係」か。
Arduinoのコードには、必ずと言っていいほどpinMode(ピン番号, モード)という1行が登場します。カッコの中に入るINPUT・OUTPUT・INPUT_PULLUP、この3つの違いが分かれば、LEDが光らない・ボタンが反応しないといった初心者の悩みの大半は解決します。この記事では、専門用語ゼロの比喩と豊富なコード例を使って、pinMode()の役割と3つのモードの違いを1分で理解できるように解説します。
| モード | ピンの役割 | 主な用途 | 配線 |
|---|---|---|---|
OUTPUT |
信号を送り出す係 | LED点灯、モーター駆動 | 通常配線 |
INPUT |
信号を受け取る係 | センサーの読み取り | センサー側の仕様通り |
INPUT_PULLUP |
信号を受け取る係(内部抵抗つき) | ボタン・スイッチ | 外付け抵抗が不要 |
pinMode()とは何をする関数か
Arduinoのボードには、多数の「ピン」と呼ばれる端子が並んでいます。これらのピンは、使う前に「今回はどんな役割で使うか」をArduino自身に伝えてあげる必要があります。その役割分担を決めるのがpinMode()という関数です。
受付窓口に例えると分かりやすいかもしれません。同じ窓口でも「今日は書類を発行する窓口」なのか「今日は書類を受け取る窓口」なのかで、やることが正反対になります。pinMode()は、その日の窓口の役割を最初に貼り紙で示しておくようなものです。
void setup() {
pinMode(8, OUTPUT); // 8番ピンは「信号を送る係」
pinMode(2, INPUT_PULLUP); // 2番ピンは「信号を受け取る係」
}
pinMode()は基本的にsetup()の中に1回だけ書きます。役割分担は電源が入っている間ずっと変わらないため、繰り返し実行する必要がないからです。この考え方はArduinoのコードの書き方(コピペ可20選)でも詳しく解説しています。
正式な仕様はArduino公式のpinMode()言語リファレンス ↗で確認できます。
INPUT・OUTPUTの違い:送る係と受け取る係
pinMode()に指定できる代表的なモードは3つです。まずは基本の2つ、OUTPUTとINPUTの違いを整理しましょう。
OUTPUT(送る係)
- Arduinoからピンへ電圧を「送り出す」
- LEDを光らせる、モーターを回すなど
- digitalWrite()で電圧を指定する
INPUT(受け取る係)
- ピンからArduinoへ電圧を「受け取る」
- ボタンの状態、センサーの値を読む
- digitalRead()やanalogRead()で値を得る
矢印の向きが逆であることが、OUTPUTとINPUTの本質的な違いです。「Arduinoが命令する側」がOUTPUT、「Arduinoが状況を教えてもらう側」がINPUTと覚えると混乱しません。
OUTPUTの使い方:LEDを光らせる
OUTPUTに設定したピンは、digitalWrite()という関数を使って「HIGH(電気を流す)」か「LOW(電気を止める)」かを指示します。LEDを点灯させる、最も基本的な例を見てみましょう。
const int LED_PIN = 8;
void setup() {
pinMode(LED_PIN, OUTPUT); // 8番ピンを「送る係」に設定
}
void loop() {
digitalWrite(LED_PIN, HIGH); // 電気を流す=LED点灯
delay(500);
digitalWrite(LED_PIN, LOW); // 電気を止める=LED消灯
delay(500);
}
OUTPUTに設定したピンは「送る係」なので、ボタンやセンサーのような外部からの信号を正しく受け取ることはできません。「読み取りたいのに反応しない」という場合、pinModeがOUTPUTのままになっていないか確認しましょう。
INPUTの使い方:センサーの値を受け取る
INPUTに設定したピンは、digitalRead()やanalogRead()で外部からの信号を受け取ります。例えば、圧力センサーや光センサーのように、それ自体が電圧を出力する部品を接続する場合に使います。
const int SENSOR_PIN = 7;
void setup() {
pinMode(SENSOR_PIN, INPUT); // 7番ピンを「受け取る係」に設定
Serial.begin(9600);
}
void loop() {
int state = digitalRead(SENSOR_PIN);
Serial.println(state); // HIGH(1)かLOW(0)を表示
delay(200);
}
INPUTに設定したピンに何も接続しない、または配線が不安定な状態だと、ピンの電圧が定まらず、HIGHとLOWの値がランダムに入れ替わってしまうことがあります。この現象を「フローティング」と呼びます。ボタンのような単純なスイッチをINPUTで使う場合、この問題を避けるために外付けの抵抗(プルダウン抵抗・プルアップ抵抗)を配線するのが一般的でした。
この「配線の手間」を解消してくれるのが、次に紹介するINPUT_PULLUPです。
INPUT_PULLUPとは?配線が要らない理由
INPUT_PULLUPは、INPUTの仲間でありながら、Arduinoの内部にあらかじめ用意された抵抗(内部プルアップ抵抗)を自動的に有効にしてくれるモードです。これにより、ボタンを配線するときに外付けの抵抗を用意しなくてよくなります。
const int BUTTON_PIN = 2;
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP); // 内部プルアップ抵抗を有効にして「受け取る係」に
Serial.begin(9600);
}
void loop() {
int state = digitalRead(BUTTON_PIN);
Serial.println(state);
delay(200);
}
配線は、ボタンの片方をそのピンに、もう片方をGND(グランド)につなぐだけです。抵抗を別途はんだ付けしたり、ブレッドボードに挿したりする手間がかかりません。配線の基礎から確認したい方はブレッドボード完全攻略ガイドもあわせてご覧ください。
INPUT_PULLUPを使うと、「ボタンを押していない時はHIGH、押した時はLOW」という結果になります。これは直感と逆になりやすいので、次の章で詳しく比較します。
INPUTとINPUT_PULLUPを比較:フローティングとは
同じボタン回路でも、INPUTとINPUT_PULLUPでは配線と読み取り結果がどう変わるのか、並べて確認してみましょう。
INPUT + 外付け抵抗
- 抵抗を自分で配線する必要がある
- 抵抗の向きにより挙動が決まる
- 部品点数が増える
INPUT_PULLUP
- 外付け抵抗が不要
- 押していない時はHIGH、押した時はLOW
- 配線がシンプルになる
INPUT(抵抗なし)
- フローティングが起きやすい
- 値がランダムに変動する
- 実用にはおすすめしない
| 項目 | INPUT(抵抗なし) | INPUT_PULLUP |
|---|---|---|
| 外付け抵抗 | 必要(用意しないとフローティング) | 不要(内部抵抗を自動使用) |
| ボタンを押していない時 | 不定(HIGH/LOWがふらつく) | HIGHで安定 |
| ボタンを押した時 | 配線次第 | LOW |
| 初心者へのおすすめ度 | △(配線と理解が必要) | ◎(手軽で安定) |
「ボタンを押したらHIGHになるはず」と考えてしまいがちですが、INPUT_PULLUPでは逆に「押した時にLOW」になります。digitalRead()の結果がLOWだったら「押されている」と判定するのが正しい書き方です。
実践コード:ボタンでLEDを点灯する
ここまでの内容を組み合わせて、INPUT_PULLUPでボタンを読み取り、OUTPUTでLEDを点灯させる、実践的な回路のコードを見てみましょう。
const int BUTTON_PIN = 2;
const int LED_PIN = 8;
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP); // ボタンは受け取る係(内部抵抗つき)
pinMode(LED_PIN, OUTPUT); // LEDは送る係
}
void loop() {
int buttonState = digitalRead(BUTTON_PIN);
if (buttonState == LOW) { // LOW=ボタンが押されている
digitalWrite(LED_PIN, HIGH); // LEDを点灯
} else {
digitalWrite(LED_PIN, LOW); // LEDを消灯
}
}
ボタン回路の配線や仕組みをさらに詳しく知りたい方はボタン回路の基礎から応用までで、センサー全般の使い分けはArduino用センサー完全ガイド16選でそれぞれ詳しく解説しています。
ありがちな間違いと見分け方のコツ
pinMode周りでつまずきやすいポイントを、チェックリスト形式でまとめました。エラーは出ないのに動かない、という時はここを確認してみてください。
pinMode()を書き忘れていないか。setup()の中で、使うピンすべてにpinMode()を書いているか確認しましょう。
OUTPUTとINPUTを取り違えていないか。LEDを光らせたいのにINPUTになっている、ボタンを読みたいのにOUTPUTになっている、というミスは非常によくあります。
INPUT_PULLUPなのに、判定がHIGHになっていないか。INPUT_PULLUPでは「押した時にLOW」が正解です。ifの条件式が== HIGHになっていないか見直しましょう。
値がふらつく場合はフローティングを疑う。INPUTで外付け抵抗を使わず、値が安定しない時は、INPUT_PULLUPへの変更を検討してください。
pinMode()はsetup()に1回だけ。loop()の中に書くと毎回設定をやり直すことになり、無駄が多く不具合の原因にもなります。
「このピンは、Arduinoから信号を送りたいのか、それともArduinoが信号を受け取りたいのか?」——送るならOUTPUT、受け取るならINPUTかINPUT_PULLUPです。ボタンやスイッチで配線をシンプルにしたいなら、まずINPUT_PULLUPを試すのがおすすめです。
FAQ・まとめ
pinMode()を書き忘れるとどうなりますか?
多くのピンは初期状態でもある程度動いてしまうことがありますが、明示的にpinMode()を書かないと動作が不安定になったり、意図しない誤動作の原因になったりします。ピンを使う前には必ずpinMode()でINPUT・OUTPUT・INPUT_PULLUPのいずれかを設定する習慣をつけましょう。
INPUTとINPUT_PULLUPはどちらを使えばいいですか?
ボタンやスイッチを配線する場合は、外付けの抵抗を用意しなくてよいINPUT_PULLUPが手軽でおすすめです。センサーの中には出力電圧が明確に決まっているものもあり、その場合はINPUTで十分です。「配線を減らしたいか」「センサー側の出力仕様に従う必要があるか」で選ぶとよいでしょう。
INPUT_PULLUPを使うとボタンの判定が反転するのはなぜですか?
INPUT_PULLUPは内部でピンを常にHIGH(5V相当)に引き上げておき、ボタンを押した時だけGND(0V)につながる配線が一般的だからです。そのため「押していない時はHIGH、押した時はLOW」という、直感とは逆の関係になります。digitalRead()の結果がLOWの時が「押されている」と覚えておくと混乱しません。
OUTPUTに設定したピンをdigitalRead()で読み取ることはできますか?
文法的にはエラーになりませんが、正しい値は得られません。OUTPUTに設定したピンは「信号を送り出す係」であり、外部の状態を受け取る係ではないためです。センサーやボタンの状態を読み取りたい場合は、必ずそのピンをpinMode()でINPUTかINPUT_PULLUPに設定してください。
pinMode()は「そのピンが送る係か、受け取る係か」を決める最初の1行です。OUTPUTなら信号を送り出し、INPUTなら信号を受け取り、INPUT_PULLUPなら配線を省略しながら安定して受け取る——この3つの違いさえ押さえれば、LEDが光らない、ボタンが反応しないといったつまずきの多くを自力で解決できるようになります。まずは7章の実践コードを実際に配線して、押した瞬間の変化を体で確かめてみてください。
コメント