動作
Arduinoボードのピンの出力電圧をデジタル制御します。
「出力電圧のデジタル制御」とは、ピンの電圧をONにするかOFFにする、というイメージです。
digitalWriteでONまたはOFFに設定すると、その状態を維持します。
出力電圧の値は、OFFの場合は0Vですが、ONの場合はArduinoボードにより異なります。
代表的なボードの電圧は以下になります。この電圧はArduinoボード仕様の「I/O電圧」や「動作電圧」という項目に記載されています。
| ONのときの電圧 | 代表的な純正ボード | 代表的な互換ボード |
|---|---|---|
| 5V | Arduino Uno Arduino Nano Arduino Mega | Seeduino V4.3 Seeduino Nano |
| 3.3V | Arduino Due Arcuino Zero Arduino MKRシリーズ | ESP8266 ESP32 Raspberry Pi Pico / Pico W Seeduino XIAOシリーズ |
主な用途
- LEDの点灯・消灯制御
- モーターのON・OFF制御
- リレーの制御
- 電子ブザーのON・OFF制御など
digitalWrite関数は、電子部品をONまたはOFFする制御です。
(「ONとOFFの2つの状態の制御」=「デジタル制御」)
LEDの明るさ調整やモーターの回転速度制御などONとOFFの中間の制御(アナログ制御)はできません。そのような場合はanalogWrite関数を使います。
書式
digitalWrite(pin, value);| 引数 | pin | 制御するピンを指定します。 ピン番号(10など)やピン名(A5)で指定します。 |
value | LOWまたはHIGHを指定します。LOWは0V、HIGHは5V(または3.3V)の電圧をピンに出力します。 | |
| 戻り値 | なし | |
引数valueはuint8_t型(符号なし8ビット)ですので、数値指定も可能です。
引数valueの数値の扱いは次のようになっています。
| valueの値 | 動作 |
| 0 | 0V出力(LOW指定と同じ動作) |
| 1 〜 255 | 5Vまたは3.3V出力(HIGH指定と同じ動作) |
なお、LOWは0、HIGHは1に定義されています。
使用例
次のコードにより、指定したピンの出力電圧をデジタル制御することができます。
digitalWrite(12, HIGH); // ピン番号による指定 - 12ピンをONにする
digitalWrite(A5, LOW); // ピン名による指定 - A5ピンをOFFにするサンプルスケッチ
5番端子に接続したLEDを1秒ごとにONOFF制御するスケッチ例です。
ボタンをクリックするとシミュレーターが動作します。
スケッチを変更することもできます。変更した場合、シミュレーションを一度
ボタンをクリックして停止してから再度シミュレーターを開始してください。
トラブルシューティング
HIGHを指定しても正しく動作しない
digitalWrite(pin, HIGH);と指定しても、LEDが点灯しない、モーターが動作しない、ということがあります。
回路の接続に問題がないと思われる場合、ほとんどのケースがpinMode関数でピンを出力モードに設定していないことが原因です。デフォルト(Arduinoボードの電源ON直後の状態)はI/Oピンは入力設定になっているため、明示的にプログラムでピンを出力モードに設定する必要があります。
次のように、pinMode関数によりピンのモード設定を行います。
void setup() {
pinMode(10, OUTPUT); // 10番ピンを出力モードにする
}
void loop() {
digitalWrite(10, HIGH);
delay(1000);
digitalWrite(10, LOW);
delay(1000);
}HIGHを指定するとLEDが暗く点灯する
主にArduino Uno R3やArduino Nanoなどのボードでは、digitalWrite(pin, HIGH);によりピンの出力をON状態にすると、接続したLEDが暗く点灯することがあります。
これはpinMode関数でピンを出力に設定していないことが原因です。pinMode関数により出力モード設定に設定する必要があります。
この現象は主にAVRマイコンを使用したArduinoボードに見られる現象でdigitalWrite(pin, HIGH);により、内部回路状態が変わることによってLEDに微小な電流が流れてしまうためです。(具体的には、digitalWrite関数でHIGHを指定すると、内部プルアップ抵抗が有効になり、ピンが入力モードでもプルアップ抵抗を通してLEDに電流が流れるためです)
pinMode関数でOUTPUTを指定しても動作しない
pinMode(ピン, OUTPUT);と指定したにもかかわらず、digitalWrite関数で制御できない場合、そのピンが入力専用(出力制御できない)ピンである可能性があります。
代表的なボードでは次のピンは出力制御できないため注意が必要です。
| 製品 | デジタル出力制御できないピン (digitalWriteが使えないピン) |
|---|---|
| Arduino Nano | A6、A7 |
| ESP32 | GPIO34、35、36、39 |
| ESP8266 | A0 |
シリアルモニタ・シリアルプロッタの表示がおかしくなる
シリアルモニタやシリアルプロッタを使用している時、表示がおかしくなることがあります。
0番ピンと1番ピンはシリアル通信に使用されるため、これらのピンに接続した回路をdigitalWriteで制御すると、通信が正常にできなくなったり、予期しない動作になることがあります。
ピンを使用するとき、0番ピンから順番に使用したくなりますが、できれば2番ピンから使用するとこのようなトラブルは避けられます。
実践テクニック
digitalWrite関数でデジタル制御を行う際のテクニック集です。
ON/OFFの状態を反転する
例えば、接続しているLEDがONであればOFF、OFFであればONというようにON/OFF状態を反転したいことがあります。(トグル動作と呼びます)
このような時は、次のように1行で処理することができます。
// 12番ピンのON/OFF状態を反転する
digitalWrite(12, !digitalRead(12));この1行は次のような処理になります。
最初に、digitalRead(12)の部分で12番ピンの状態を読み取ります。次に!でその状態を反転します。最後にdigitalWriteでピンに出力をその反転した状態に設定します。
次の回路とスケッチで、スイッチが押されるたびにLEDのONとOFFを切り替えることができます。なお、説明をシンプルにするために、スイッチ状態の判定として、スイッチが押された後しばらく待つ処理にしています。(実用的にするためにはスイッチ状態を保持し、前回と今回のスイッチ状態を比較してスイッチが押されたか判定する必要があります)
ボタンをクリックするとシミュレーターが動作します。ボタンをクリック(タップ)するとボタンを操作することができます。
アナログ値に応じてON/OFF制御
例えば「気温センサーで読み取った値が25以上であればLEDを点灯する」などのように、アナログ値に応じてLEDを制御したいことがあります。
通常はif文を使用してスケッチを作成しますが、次のようにdigitalWriteの出力設定に条件式を書く方法もあります。(スケッチは多少読みづらくなりますが…)
int sensorValue = センサーで読み取った値;
digitalWrite(5, sensorValue >= 25); // sensorValueが25以上であればONこの書き方は、sensorValue >= 25という条件式が、真の場合は1、偽の場合は0になるため、結果としてHIGHとLOWの設定と同じ意味になります。
次の回路は、A5ピンにボリューム(可変抵抗)を接続しています。ボリュームを回転すると、A5ピンの電圧が0V〜5Vまでアナログ変化します。
A5ピンをanalogRead関数で読み取ると、電圧に応じて0〜1023の値が返ってきます。この値を使用してdigitalWriteの第2引数で条件式にすると、判定結果に応じてLEDのON/OFFを制御することができます。具体的には、読み取った値が100以上であれば真となりLEDがONになります。それ以外はLEDがOFFになります。
ボタンをクリックするとシミュレーターが動作します。ボリュームをドラッグすると操作することができます。analogReadで読み取った値は右下に表示されるシリアルモニタで確認できます。
補足
電流の上限値
digitalWriteで電子部品を制御する際、ピンに流れる電流の上限値に注意する必要があります。
この電流の上限値にはピン1本に流せる電流の上限値と、全ピン合計の電流の上限値があります。
これらは製品ごとに異なりますので、利用するボードの仕様書やAIに確認してください。
ここではArduino純正ボードとして「Arduino Uno R4 Minima」を、互換ボードとして「ESP32-DevKitC-32E」を例に、それぞれの電流の最大値を説明します。
| ボード | Arduino Uno R4 Minima | ESP32-DevKitC-32E |
|---|---|---|
| 1ピンあたりの電流 | 8mA | 40mA(出力電流の場合) |
| 全ピン合計の電流 | 60mA | 150mA程度 |
このようにボードによって電流上限値は異なりますが、いずれのボードでも上限値ギリギリで使用するのはよくありません。電流を多く流し続けると一部の部品が発熱してトラブルになることがあります。
入出力ピンや電源ピンで使用する電流は極力少なくすることが望ましく、基本的には数mA程度で使用することをお勧めします。
LEDを直接ピンに接続すると多くの電流が流れてしまい、ArduinoボードとLEDを壊してしまう可能性があります。LEDの電流を制限するには「抵抗」や「定電流ダイオード」を使用して電流が流れすぎないように注意します。
デフォルト値
digitalWrite関数でピンの電圧状態を設定する前、つまりArduinoボードの電源ON直後のデフォルト状態はLOWになっています。
実際には、ピンモードのデフォルトは入力ですので(pinMode(pin, INPUT);)、ピンに電圧は出力されていませんが、Arduinoボード内部の出力制御スイッチはLOWになっています。
出力をHIGHにした時の内部プルアップ抵抗
主にAVRマイコンを使用したArduinoボードでは、digitalWrite(pin, HIGH);により、内部プルアップ抵抗が有効になります(pinMode関数でINPUTまたはOUTPUTを指定した場合でも内部プルアップ抵抗が有効になります)。
これはAVRマイコンの仕様に起因しています。AVRマイコンでは、「ピンの入出力モード設定」と「内部プルアップ抵抗設定」は2つのレジスタで設定をしています。具体的には、DDRレジスタ(Data Direction Register・データ方向レジスタ)とPORTレジスタ(Port・入出力制御)の2つのレジスタを0か1に設定し、それぞれの設定でピンのモードは次のようになっています。
| DDRレジスタ データ方向指定 | PORTレジスタ 入出力制御 | 動作 |
|---|---|---|
| 0 | 0 | 入力・プルアップ無効 |
| 0 | 1 | 入力・プルアップ有効 |
| 1 | 0 | 出力LOW(プルアップ無効) |
| 1 | 1 | 出力HIGH(プルアップ有効) |
なお、AVRマイコン以外ではプルアップ抵抗は独立して制御される場合もあります。例えばESP32系のボードでは、プルアップ抵抗の有効無効レジスタが別に用意されていて独立して制御できますので、出力をHIGHにしてもプルアップの有効無効は連動しません(Espressif社のArduinoボード情報ファイルで実機確認)。
ただし、プルアップ抵抗を独立に制御できる場合でも、AVRマイコンの挙動に合わせてdigitalWrite関数が実装されているケースもあります。
digitalWriteの実行時間
digitalWrite関数は、実動作としてはピンの出力をONまたはOFFに設定するだけですが、実際には他の処理をしています。そのため、低レベル(ハードウェアに近いレベル)のプログラムコードに比べ、少し余分に時間がかかります。
LEDマトリックスの表示制御(ダイナミック点灯)などのような高速ON/OFF制御が必要な場合、低レベルでのプログラミング(レジスタ直接制御)を行う必要があります。
Arduinoの場合、このような高速制御が必要なケースではライブラリが提供されていることが多いので、ライブラリを積極的に活用すると良いと思います。
digitalWrite関数の中身の処理はマイコンによって異なります。以下はAVR系の純正Arduinoボードの実装です。
void digitalWrite(uint8_t pin, uint8_t val)
{
uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *out;
if (port == NOT_A_PIN) return;
// If the pin that support PWM output, we need to turn it off
// before doing a digital write.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);
out = portOutputRegister(port);
uint8_t oldSREG = SREG;
cli();
if (val == LOW) {
*out &= ~bit;
} else {
*out |= bふえit;
}
SREG = oldSREG;
}
参照元: Arduino GitHub – wiring_digital.c
実際のピンのON/OFF設定は、LOWの場合は20行目、HIGHの場合は22行目のコードです。
他の処理は、現在のピンの状態を確認(3〜5行目)、指定されたピンが有効か確認(8行目)、PWM制御中であればPWM機能をOFF(12行目)、実際に設定する前処理(14〜17行目)、後処理(25行目)という内容です。
Arduinoボード内部動作
Arduinoボードの内部動作は次のようになっています。次のイラストは、例として5番ピンの内部のようすを示しています。(以下の回路は実際にこのようになっているわけではなく、実際には半導体部品(FETなど)で構成されています)
なお、ピンの内部にはプルアップ抵抗と有効無効スイッチが内蔵されていますが、以下のイラストでは省略しています。

例えばdigitalWrite(5, HIGH);という処理を行うと、イラストの赤枠のように電源のプラス側に接続されます。
また、5番ピンには緑枠のように、digitalWrite関数の制御を有効にするためのスイッチが接続されています。
このスイッチはpinMode関数で制御し、pinMode(5, OUTPUT);とするとイラストのようにdigitalWriteの制御スイッチが有効になります。pinMode(5, INPUT);またはpinMode(5, INPUT_PULLUP);の場合はこのスイッチはOFFとなり、digitalWriteの制御から切り離されます。
