分圧回路の基本:公式、抵抗の選び方、Arduinoでの例
分圧回路はどう動くのでしょうか。Vout = Vin × R2 / (R1 + R2)の公式、抵抗の選び方、負荷効果、Arduinoでの12 Vの測定、5 Vから3.3 Vへの変換、LDRとNTCの読み取りを解説します。
分圧回路は、直列につないだ2本の抵抗を使って、ある電圧をより小さく予測可能な電圧に変える、いちばんシンプルな回路です。出力電圧はVout = Vin × R2 / (R1 + R2)で求められます。R1は電源側に、R2はグラウンド(GND)側につなぎ、出力は2本が接続される中点から取り出します。たとえば10 kΩの抵抗2本で、12 Vをちょうど半分の6 Vに分けられます。Arduinoで12 Vのバッテリーを測る、5 Vのセンサー信号をESP32の3.3 Vのピンに合わせて下げる、LDRやNTCサーミスタなどのセンサーを読み取るなど、数えきれないほどの回路の中心にこの2本の抵抗があります。
このガイドでは、公式がどこから来るのか、抵抗値をどう選ぶのか、分圧回路に何かをつなぐと出力が下がるのはなぜか(負荷効果)を、実際の数値で確認します。続いて、Arduino Uno、ESP32、Raspberry Pi Picoで電池の電圧を測るコードをステップごとに作り、5 Vを3.3 Vに変換するための適切な抵抗の組み合わせを選び、分圧回路でLDRとNTCを読み取ります。最後に、分圧回路を電源の代わりに使ってはいけない理由を説明します。

分圧回路とは?どのように動作するのか
分圧回路の公式は、オームの法則からそのまま導かれます。電源とグラウンドの間に直列につないだR1とR2には、同じ電流が流れます。I = Vin / (R1 + R2)です。出力であるR2の両端の電圧は、この電流にR2を掛けたもので、Vout = I × R2 = Vin × R2 / (R1 + R2)となります。つまり、電源電圧は抵抗値に比例して各抵抗に分配され、大きい抵抗ほど大きな電圧を受け持ちます。R2 / (R1 + R2)の比は1より小さいので、出力は常に入力より小さくなります。直列回路で電圧がどのように分配されるかは、抵抗の直列・並列の計算で詳しく説明しています。
| 求める値 | 公式 | 例(Vin = 12 V、R1 = 22 kΩ、R2 = 10 kΩ) |
|---|---|---|
| 出力電圧 | Vout = Vin × R2 / (R1 + R2) | 12 × 10 / 32 = 3.75 V |
| 分圧比 | k = R2 / (R1 + R2) | 10 / 32 = 0.3125 |
| 出力から入力を求める | Vin = Vout × (R1 + R2) / R2 | 3.75 × 3.2 = 12 V |
| 目的の比に合わせたR1 | R1 = R2 × (Vin / Vout − 1) | 10 kΩ × (12 / 3.75 − 1) = 22 kΩ |
| 分圧回路の電流 | I = Vin / (R1 + R2) | 12 / 32 kΩ = 0.375 mA |
| 全体の電力 | P = Vin² / (R1 + R2) | 144 / 32 kΩ = 4.5 mW |
| 出力抵抗(テブナン) | Rth = R1 × R2 / (R1 + R2) | 22 × 10 / 32 = 6.875 kΩ |
逆から考えることもできます。12 Vを3.3 Vに下げたいとき、R2に10 kΩを選んだなら、R1 = 10 × (12 / 3.3 − 1) ≈ 26.4 kΩになります。この値の抵抗は売られていないので、1つ上の標準値である27 kΩを選ぶと、出力は12 × 10 / 37 ≈ 3.24 Vになります。R1を切り上げると出力が少し下がり、ピンにとっては安全側になります。ポテンショメーターも実は可変の分圧回路で、ワイパー(中央の端子)が抵抗体をR1とR2に分けています。手で計算したくない場合は、分圧計算ツールに入力電圧と抵抗値を入れれば、すぐに出力がわかります。電子工作では、分圧回路はおもに次のような用途で使われます。
- 高い電圧の測定:12 Vのバッテリーや7.4 Vのリチウムパックなどの電源を、アナログ入力で測れる範囲まで下げます。
- 信号レベルを下げる:5 Vの信号を、ESP32やRaspberry Pi Picoの3.3 Vの入力に安全な電圧にします。
- 抵抗が変化するセンサーの読み取り:LDR、NTC、曲げセンサー(フレックスセンサー)、感圧センサー(FSR)などの部品の抵抗変化を、電圧に変えます。
- 1本のピンで複数のボタンを読む:抵抗ラダーでボタンごとに異なる電圧を与えれば、5個のボタンで1本のアナログピンを共有できます。
- レギュレーターのフィードバック:LM317や可変出力のLM2596などのレギュレーターは、出力を分圧回路で測って一定に保ちます。LM317ではVout = 1.25 × (1 + R2 / R1)です。
- 基準電圧の生成:オペアンプ回路で、電源電圧の半分を基準電圧として作ります。
抵抗値の選び方
公式が気にするのは比だけです。1 kΩ + 1 kΩでも100 kΩ + 100 kΩでも、同じようにちょうど半分に分けます。しかし実際には、抵抗値そのものの大きさも重要です。小さい抵抗では、分圧回路に多くの電流が流れます。この電流は無駄なエネルギーで、電池で動くプロジェクトでは電池を無駄に消耗させます。大きい抵抗では電流はごくわずかですが、出力が弱くなります。つないだ負荷やアナログ入力内部のサンプリングコンデンサが出力電圧を簡単に乱し、配線が拾うノイズも入り込みやすくなります。適切な選択は、この2つの極端の間でバランスを取ることです。
| 合計抵抗(R1 + R2) | 12 Vでの電流 | 長所 | 短所 | 主な用途 |
|---|---|---|---|---|
| 100 Ω〜1 kΩ | 12〜120 mA | 負荷の影響をほとんど受けず、非常に高速 | 発熱し、電流を多く無駄にする | 測定回路ではほぼ使わない |
| 1 kΩ〜30 kΩ | 0.4〜12 mA | ADCに理想的な出力抵抗で、高速な信号に向く | 電池のプロジェクトでは電流が常に流れる | 5 V → 3.3 Vの信号変換、Arduinoでの測定 |
| 30 kΩ〜300 kΩ | 40〜400 µA | 電池にやさしく、発熱しない | アナログ入力に100 nFのコンデンサが必要な場合がある | 電池の監視 |
| 1 MΩ以上 | 12 µA未満 | 電流をほとんど流さない | ノイズに弱く、ADCで正確に読めず、テスターでさえ負荷になる | オペアンプのバッファと組み合わせる場合のみ |
- 最大入力電圧を確認します。12 Vの鉛蓄電池は、充電中に14.4 Vまで上がることがあります。測る電圧の最悪の場合を考え、さらに10%の余裕を加えます。
- ピンが受け付ける最大電圧を確認します。Arduino Unoは5 V、ESP32とPicoは3.3 Vです。安全な目標として、Unoでは約4.5 V、ESP32では2.5 V、Picoでは3.0 Vを選びます。
- 比を計算します:k = 目標の出力 / 最大入力です。たとえば4.5 / 14.4 ≈ 0.31になります。
- R2を選び(ほとんどの場合、10 kΩから始めるのがおすすめです)、R1 = R2 × (1 / k − 1)でR1を求めます。結果は抵抗の標準値の中から、1つ上の値に切り上げます。
- 電流と電力を確認します:I = Vin / (R1 + R2)、P = Vin² / (R1 + R2)です。電池のプロジェクトでは、電流をマイクロアンペアの範囲に抑えるようにします。
- 出力抵抗を確認します:Arduino Unoでは、R1 × R2 / (R1 + R2)が10 kΩ未満になるようにします。そうならない場合は、アナログピンとGNDの間に100 nFのコンデンサを追加します。
- 実際の比をコードに書きます:選んだ標準値で比を計算し直し、回路を組んだらテスターで測ってキャリブレーションします。
負荷効果:分圧回路に何かをつなぐとどうなる?
公式は、出力から電流を取り出さないことを前提にしています。負荷をつないだ瞬間、負荷はR2と並列になり、下側の合成抵抗が小さくなって、出力電圧が下がります。これを簡単に計算するには、分圧回路をテブナンの等価回路として考えます。無負荷で測った電圧(Vth)と、内部抵抗Rth = R1 × R2 / (R1 + R2)を持つ電源とみなすのです。負荷RLをつなぐと、出力はVth × RL / (Rth + RL)になります。下の表は、10 Vの電源を10 kΩ + 10 kΩで分圧し(Vth = 5 V、Rth = 5 kΩ)、出力にさまざまな負荷をつないだ場合です。
| 出力の負荷(RL) | 出力電圧 | 誤差 |
|---|---|---|
| 無負荷 | 5.00 V | 0% |
| 1 MΩ | 4.98 V | 0.5% |
| 100 kΩ | 4.76 V | 4.8% |
| 10 kΩ | 3.33 V | 33% |
| 1 kΩ | 0.83 V | 83% |
目安として、負荷の抵抗が分圧回路の出力抵抗(Rth)の100倍以上あれば、誤差は1%未満に収まります。負荷がそれより小さい場合は、抵抗値を小さくするか、間にオペアンプのボルテージフォロワ(バッファ)を入れます。マイコンのアナログ入力自体は非常に高い抵抗を持っていますが、内部には変換のたびに充電される小さなサンプリングコンデンサがあります(ATmega328Pでは約14 pF)。そのため、データシートでは信号源の出力抵抗を約10 kΩ以下にするよう推奨しています。それより大きな抵抗の分圧回路を使う場合は、アナログピンとGNDの間に100 nFのコンデンサを追加してください。サンプリングの瞬間に必要な電荷を、このコンデンサが用意しておいてくれます。また、複数のアナログピンを順番に読む場合は、各ピンの最初の読み取り値を捨てると、チャンネルの切り替えで残った誤差を取り除けます。
分圧回路を電源として使えない理由
初心者がいちばん陥りやすい落とし穴は、12 VのACアダプターから2本の抵抗で5 Vを取り出し、それでArduinoやモジュールを動かそうとすることです。計算上は7 kΩと5 kΩの分圧回路で12 Vからちょうど5 Vが得られますが、それは出力から電流を取り出さない場合に限ります。50 mAを消費するボードは約100 Ωの負荷のように振る舞い、5 kΩのR2と並列になると下側の抵抗は98 Ωまで下がって、出力は0.17 Vまで落ち込みます。抵抗を70 Ωと50 Ωまで小さくすると、今度は何もつないでいなくても回路に100 mAが流れ、1.2 Wが熱になります。負荷をつなげば出力はやはり3.9 Vまで下がり、ボードの消費電流が変わるたびに(Wi-Fi、サーボ、リレー)電圧も変動します。さらに、負荷を外すと電圧が再び上がり、繊細な部品を壊すおそれがあります。
Arduinoで12 Vのバッテリーと電池の電圧を測る
Arduino Unoのアナログ入力で読めるのは最大5 Vまでで、12 Vのバッテリーを直接つなぐとピンが壊れます。解決策は、22 kΩ(R1)と10 kΩ(R2)の分圧回路です。比が0.3125なので、充電時の14.4 Vはピンに4.5 Vとして届き、この回路で最大16 Vまで測れます。12 Vでの分圧回路の電流はわずか0.375 mAで、出力抵抗の6.9 kΩも推奨される10 kΩの上限を下回ります。10ビットADCの1ステップは約4.9 mVなので、分圧回路と合わせると、入力側の分解能は約15.6 mVになります。ESP32とPicoは3.3 Vで動作するので、これらのボードではより大きなR1(56 kΩ)を使います。
| 接続 | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| R1(上側の抵抗) | 22 kΩ | 56 kΩ | 56 kΩ |
| R2(下側の抵抗) | 10 kΩ | 10 kΩ | 10 kΩ |
| R1の上端 | 電源のプラス(+12 V) | 電源のプラス(+12 V) | 電源のプラス(+12 V) |
| 中点(R1–R2) | A0 | GPIO 34(ADC1) | GP26(ADC0、31番ピン) |
| R2の下端と電源のマイナス | GND | GND | GND(例:38番ピン) |
| 14.4 Vでのピンの電圧 | 4.50 V | 2.18 V | 2.18 V |
| 測れる最大入力 | 16 V | 約16 V(正確に測れる範囲) | 約21 V |
1// 12 V akü gerilimini gerilim bölücüyle ölçme / Measuring a 12 V battery with a voltage divider
2// Kaynak + -> 22k (R1) -> A0 -> 10k (R2) -> GND / Source + -> 22k (R1) -> A0 -> 10k (R2) -> GND
3// Kaynağın eksisi Arduino GND'sine bağlı / Source minus is tied to the Arduino GND
4const int VIN_PIN = A0;
5const float VREF = 5.0; // 5V pininde ölçtüğün gerilim / voltage you measured on the 5V pin
6const float R1 = 22000.0; // üst direnç (ohm) / top resistor (ohms)
7const float R2 = 10000.0; // alt direnç (ohm) / bottom resistor (ohms)
8const float CAL = 1.000; // kalibrasyon: gerçek / okunan / calibration: real / measured
9const float LOW_V = 11.8; // düşük akü eşiği (V) / low battery threshold (V)
10
11float readInputVoltage() {
12 analogRead(VIN_PIN); // ilk okumayı at / discard the first reading
13 long sum = 0;
14 for (int i = 0; i < 16; i++) { // 16 ölçümün ortalaması / average of 16 readings
15 sum += analogRead(VIN_PIN);
16 delay(2);
17 }
18 float vPin = (sum / 16.0) * VREF / 1024.0; // pindeki gerilim / voltage at the pin
19 return vPin * (R1 + R2) / R2 * CAL; // bölücüden önceki gerilim / voltage before the divider
20}
21
22void setup() {
23 Serial.begin(9600);
24 pinMode(LED_BUILTIN, OUTPUT);
25}
26
27void loop() {
28 float v = readInputVoltage();
29 Serial.print(F("Giris / Input: "));
30 Serial.print(v, 2);
31 Serial.println(F(" V"));
32 digitalWrite(LED_BUILTIN, v < LOW_V ? HIGH : LOW); // akü zayıfsa LED yanar / LED on when the battery is low
33 delay(1000);
34}このコードは、ADCのサンプリングコンデンサが安定するように最初の読み取り値を捨て、その後16回の平均をとってノイズを減らします。読み取った数値はまずピンの電圧に変換され(ATmega328PのデータシートではADC = Vin × 1024 / Vrefとされているので、1024で割ります)、次に(R1 + R2) / R2 = 3.2を掛けて分圧前の電圧を求めます。最大の誤差の原因はVrefです。USB給電のUnoの5Vピンは、4.7〜5.1 Vのどこかになっていることがよくあります。そこで、5Vピンをテスターで測ってその値をVREFに入れ、さらにバッテリーの実際の電圧もテスターで測ってシリアルモニタの値と比べ、CAL = 実測値 / 読み取り値をコードに入力します。この1ステップで、Vrefと抵抗の誤差をまとめて補正できます。分圧回路を機器の電源スイッチの後ろにつなげば、電源がオフの間は電流が流れません。0.375 mAは1日で約9 mAhになり、車のバッテリーなら問題になりませんが、小さな電池でははっきりと影響が出ます。ほかの電源に合う抵抗の組み合わせは次のとおりです。
| 測る電源 | 電圧範囲 | Arduino Uno(5 V):R1 + R2 | ESP32 / Pico(3.3 V):R1 + R2 |
|---|---|---|---|
| 1セルのLi-ion / LiPo(1S) | 3.0〜4.2 V | 分圧回路は不要(4.2 V < 5 V) | 100 kΩ + 100 kΩ → 最大2.10 V |
| 2SのLi-ionパック | 6.0〜8.4 V | 10 kΩ + 10 kΩ → 最大4.20 V | 100 kΩ + 33 kΩ → 最大2.08 V |
| 3SのLiPoパック | 9.0〜12.6 V | 22 kΩ + 10 kΩ → 最大3.94 V | 56 kΩ + 10 kΩ → 最大1.91 V |
| 12 Vの鉛蓄電池 | 10.5〜14.4 V | 22 kΩ + 10 kΩ → 最大4.50 V | 56 kΩ + 10 kΩ → 最大2.18 V |
| 24 Vのシステム | 21〜29 V | 56 kΩ + 10 kΩ → 最大4.39 V | 120 kΩ + 10 kΩ → 最大2.23 V |
ESP32で電圧を測る
ESP32のADCは12ビット(0〜4095)ですが、2つの重要な違いがあります。1つ目は、Wi-Fiがオンの間はADC2のピンを読めないことです。分圧回路は必ず、ADC1のピンであるGPIO 32〜39のどれかにつないでください(GPIO 34〜39は入力専用で、この用途に最適です)。2つ目は、ADCが両端付近で直線的でないことです。初期設定の11 dBの減衰では、Espressifはおよそ150〜2450 mVをもっとも正確な範囲として推奨しています。ピンは約3.1 Vまでの値を示しますが、その領域では誤差が大きくなります。そのため、56 kΩ + 10 kΩの分圧回路を選びました。14.4 Vはピンに2.18 Vとして届き、正確な範囲に収まります。生のanalogRead()の代わりに、工場でチップに書き込まれたキャリブレーションデータを使ってミリボルト値を直接返すanalogReadMilliVolts()を使います。
1// ESP32: 56k + 10k bölücüyle 12 V ölçme / ESP32: measuring 12 V with a 56k + 10k divider
2const int VIN_PIN = 34; // ADC1_CH6, Wi-Fi açıkken de çalışır / ADC1_CH6, works with Wi-Fi on
3const float R1 = 56000.0; // üst direnç (ohm) / top resistor (ohms)
4const float R2 = 10000.0; // alt direnç (ohm) / bottom resistor (ohms)
5const float CAL = 1.000; // multimetreyle ayarla / tune with a multimeter
6
7void setup() {
8 Serial.begin(115200);
9 analogReadResolution(12); // 0-4095 (varsayılan / default)
10}
11
12void loop() {
13 uint32_t mv = 0;
14 for (int i = 0; i < 32; i++) {
15 mv += analogReadMilliVolts(VIN_PIN); // kalibre edilmiş milivolt / calibrated millivolts
16 }
17 float vPin = mv / 32.0 / 1000.0; // pindeki gerilim (V) / voltage at the pin (V)
18 float vIn = vPin * (R1 + R2) / R2 * CAL; // bölücüden önceki gerilim / voltage before the divider
19 Serial.printf("Pin: %.3f V Giris / Input: %.2f V\n", vPin, vIn);
20 delay(1000);
21}Raspberry Pi Picoで電圧を測る(MicroPython)
Raspberry Pi Picoのアナログ入力は、GP26、GP27、GP28(ADC0〜ADC2)です。MicroPythonのread_u16()は12ビットの測定値を0〜65535の範囲にスケーリングし、基準はボードの3.3 Vから来るADC_VREFです。PicoのADCは3.3 Vまで測れるので、56 kΩ + 10 kΩの分圧回路で約21 Vまで測定できます。おもしろいことに、Pico自身も分圧回路を使っています。ボード上の分圧回路がVSYSの電源電圧を3分の1にしてGP29(ADC3)に入力しているので、ADC(29)で読み取った電圧に3を掛ければ、ボードの電源電圧がわかります(Pico WではGP29が無線チップと共用されているため、この方法はそのままでは使えません)。
1from machine import ADC
2import time
3
4adc = ADC(26) # GP26 = ADC0 (pin 31)
5VREF = 3.3 # ADC_VREF; multimetreyle ölçüp düzelt / measure and correct with a multimeter
6R1 = 56000 # üst direnç (ohm) / top resistor (ohms)
7R2 = 10000 # alt direnç (ohm) / bottom resistor (ohms)
8CAL = 1.000 # kalibrasyon katsayısı / calibration factor
9
10
11def read_input_voltage(samples=32):
12 total = 0
13 for _ in range(samples):
14 total += adc.read_u16() # 0-65535
15 v_pin = total / samples * VREF / 65535 # pindeki gerilim / voltage at the pin
16 return v_pin * (R1 + R2) / R2 * CAL # bölücüden önceki gerilim / voltage before the divider
17
18
19while True:
20 v_in = read_input_voltage()
21 print("Giris / Input: {:.2f} V".format(v_in))
22 time.sleep(1)5 V信号を3.3 Vに下げる(ESP32とPico向け)
ESP32とPicoのピンは5 Vトレラントではありません。HC-SR04のECHO出力、Arduino UnoのTXピン、5 Vで動くモジュールのデジタル出力をこれらのボードに直接つなぐと、入力の保護ダイオードに負担がかかり、ピンがしだいに壊れることがあります。一方向の信号なら、いちばん安い解決策は分圧回路です。目標は、3.3 Vを超えることはないものの、ボードがHIGHと読める程度には高い電圧です。ESP32は電源電圧の75%(約2.5 V)を、PicoのRP2040は2.0 VをHIGHの最低レベルとしています。つまり、3.0〜3.3 Vの出力なら、どちらのボードでも十分な余裕があります。これはHC-SR04距離センサーのガイドで、ECHOピンを3.3 Vのボードにつなぐ方法として紹介しているのと同じやり方です。
| R1(信号側) | R2(GND側) | 5 V入力時の出力 | 出力抵抗 | 評価 |
|---|---|---|---|---|
| 1 kΩ | 2 kΩ(1 kΩ×2本を直列) | 3.33 V | 667 Ω | 定番の組み合わせ。高速な信号にも使える |
| 1.2 kΩ | 2.2 kΩ | 3.24 V | 776 Ω | E12系列の標準値で、3.3 Vのすぐ下 |
| 10 kΩ | 20 kΩ | 3.33 V | 6.7 kΩ | 電流が少ない。UARTとHC-SR04には十分 |
| 2.2 kΩ | 3.3 kΩ | 3.00 V | 1.3 kΩ | もっとも安全な余裕。どちらのボードもHIGHと読める |
| 4.7 kΩ | 10 kΩ | 3.40 V | 3.2 kΩ | ぎりぎり。5 Vラインが5.25 Vまで上がると3.57 Vになるため、非推奨 |
分圧回路は、ピン自体の静電容量と合わさって小さなRCフィルタを作ります。10 kΩ + 20 kΩの分圧回路の出力抵抗6.7 kΩと、ピンとブレッドボードの約15 pFの静電容量では、時定数はおよそ100 nsになります。115200ボーのUART(1ビットあたり8.7 µs)には影響しませんが、数MHzのSPI信号ではエッジが丸くなってしまいます。高速な信号線には1 kΩ + 2 kΩを選んでください。また、分圧回路が働くのは、高い電圧から低い電圧への一方向だけであることも覚えておきましょう。逆方向では、たいてい何もする必要はありません。Arduino Unoは3.0 Vを超える電圧をHIGHとみなすので、余裕は小さいものの、ESP32の3.3 Vの出力を読み取れます。ただし、I2Cのような双方向の信号線では分圧回路は役に立たず、MOSFETを使ったレベル変換モジュールを使います。
分圧回路でLDRとNTCを読み取る

マイコンは抵抗を直接測ることはできず、測れるのは電圧だけです。LDRやNTCのような抵抗が変化するセンサーを固定抵抗と直列につないで分圧回路を作ると、抵抗の変化が中点の電圧の変化になります。固定抵抗の値で感度が決まります。電圧の変化幅を最大にするには、固定抵抗を、測りたい範囲でのセンサーの最小抵抗と最大抵抗の幾何平均にします。R = √(Rmin × Rmax)です。明るいところで1 kΩ、暗いところで100 kΩになるLDRなら、√(1 k × 100 k) = 10 kΩです。5 Vの場合、10 kΩなら出力は4.09 Vの幅で変化しますが、1 kΩや100 kΩでは変化幅が2.45 Vに縮まります。スターターキットに10 kΩの抵抗が入っているのは、このためです。もう1つ利点があります。分圧回路とADCが同じ5 Vで動くので、計算した抵抗値は電源電圧に左右されません(レシオメトリック測定)。そのため、下のコードではVrefの値さえ必要ありません。
1// LDR ve NTC'yi gerilim bölücüyle okuma / Reading an LDR and an NTC with voltage dividers
2// A0: 5V -> LDR -> A0 -> 10k -> GND
3// A1: 5V -> 10k -> A1 -> NTC 10k (B = 3950) -> GND
4const float R_FIXED = 10000.0; // sabit dirençler (ohm) / fixed resistors (ohms)
5const float R0 = 10000.0; // NTC'nin 25 °C direnci / NTC resistance at 25 °C
6const float BETA = 3950.0; // NTC B katsayısı / NTC beta coefficient
7const float T0 = 298.15; // 25 °C kelvin cinsinden / 25 °C in kelvin
8
9void setup() {
10 Serial.begin(9600);
11}
12
13void loop() {
14 analogRead(A0); // kanal değişti, ilk okumayı at / channel changed, discard first reading
15 int ldrRaw = analogRead(A0);
16 analogRead(A1);
17 int ntcRaw = analogRead(A1);
18 if (ldrRaw < 1) ldrRaw = 1; // sıfıra bölmeyi önle / avoid division by zero
19
20 // Oransal ölçüm: besleme gerilimi hesaptan düşer / ratiometric: the supply voltage cancels out
21 float rLdr = R_FIXED * (1024.0 / ldrRaw - 1.0);
22 float rNtc = R_FIXED * ntcRaw / (1024.0 - ntcRaw);
23 float tempC = 1.0 / (1.0 / T0 + log(rNtc / R0) / BETA) - 273.15; // Beta denklemi / Beta equation
24
25 Serial.print(F("LDR: "));
26 Serial.print(rLdr / 1000.0, 1);
27 Serial.print(F(" kOhm NTC: "));
28 Serial.print(rNtc / 1000.0, 2);
29 Serial.print(F(" kOhm "));
30 Serial.print(tempC, 1);
31 Serial.println(F(" C"));
32 delay(1000);
33}コードではLDRを上側に置いているので、明るくなるほど読み取り値が大きくなります。LDRの抵抗はR = 10 kΩ × (1024 / ADC − 1)です。NTCは下側に置いていて、温度が上がると抵抗が下がり、読み取る電圧も下がります。25 °Cで10 kΩ、B定数3950の一般的なNTCでは、温度はB定数の式(Beta式)で求めます。1 / T = 1 / T0 + ln(R / R0) / B(温度はケルビン)です。固定抵抗をNTCの25 °Cでの抵抗値と同じにしているので、室温では出力がちょうど電源電圧の半分になり、そこで感度がもっとも高くなります。広い温度範囲でより高い精度が必要な場合のSteinhart-Hartの式や、NTCの自己発熱については、NTCサーミスタのガイドで取り上げています。
分圧回路を使ったプロジェクトアイデア
- バッテリーモニターと低電圧アラーム:キャンピングカーやソーラー発電システムのバッテリーを監視し、11.8 Vを下回ったらブザーを鳴らします。電池で動くプロジェクトの電源の選択肢については、Arduinoを電池で動かす方法を参照してください。
- デジタル電圧計:測定した電圧をLCDやOLEDディスプレイに表示します。手順はArduinoで電圧計を作るで説明しています。
- 自動常夜灯:LDRの分圧回路を使い、暗くなったらLEDやリレーをオンにします。
- 太陽追尾装置:2つのLDR分圧回路の電圧を比べ、パネルを光の方向に向けます(太陽追尾装置)。
- 1本のピンに5個のボタン:異なる抵抗でラダーを組み、アナログ値からどのボタンが押されたかを判断します(ボタンの配線)。
- サーモスタット:NTCの分圧回路で温度を測り、設定した温度になったらファンやヒーターをリレーで切り替えます。
よくある間違いと対処法
| 症状 | 考えられる原因 | 対処法 |
|---|---|---|
| 値が意味をなさず、ずっと飛び回る | 電源のマイナスがArduinoのGNDにつながっていない | GNDを共通にする |
| ピンの電圧が予想よりずっと高い | R1とR2が逆になっている | 大きい抵抗を電源側(上側)に付ける。つなぐ前にテスターで測る |
| 測定値が実際の値と5〜10%ずれる | 誤差5%の抵抗、またはVrefが5.00 Vではない | 誤差1%の金属皮膜抵抗を使い、コードのVREFとCALでキャリブレーションする |
| モジュールをつなぐと出力が下がる | 負荷効果:負荷がR2と並列になっている | 負荷をRthの100倍以上にする、抵抗を小さくする、またはオペアンプのバッファを使う |
| 高抵抗の分圧回路で値がずれていく | ADCのサンプリングコンデンサが十分に充電されない | ピンに100 nFのコンデンサを追加し、最初の読み取り値を捨てる |
| Wi-Fiを開始するとESP32の読み取りが動かなくなる | 分圧回路がADC2のピンにつながっている | GPIO 32〜39(ADC1)を使う |
| 機器がオフでも電池が減る | 分圧回路が電池から常に電流を流している | 分圧回路をスイッチの後ろにつなぎ、高い値の抵抗を使う |
| 分圧回路から給電したモジュールが動かない | 分圧回路は電源ではない | 7805、AMS1117、LM2596などのレギュレーターを使う |
| 分圧回路を通すとI2Cが動かない | 分圧回路は一方向、I2Cは双方向 | MOSFETを使ったレベル変換モジュールを使う |
分圧回路は抵抗2本と公式1つだけですが、何かを測るほぼすべてのプロジェクトのどこかに登場します。比は公式で選び、抵抗値そのものは電流と出力抵抗のバランスで選び、負荷効果を考慮して、結果をテスターでキャリブレーションすれば、信頼できる測定値が得られます。アナログ読み取りの背景はADCとは?で読めます。BlueGraysアプリには、LDRで光の強さを測る、LDRで作る常夜灯、LCD付きのデジタル電圧計、NTCで温度を測る、ESP32とHC-SR04で作る距離計などのプロジェクトがあり、どれも回路図とコード付きで、ステップごとに解説しています。
よくある質問
分圧回路の公式は?
出力電圧はVout = Vin × R2 / (R1 + R2)で、R1は電源側、R2はグラウンド側の抵抗です。たとえば9 Vを10 kΩと10 kΩで分けると4.5 Vになります。この公式が正確に成り立つのは、出力から電流を取り出さない場合だけです。
分圧回路で12 Vから5 Vを作れますか?
測定や信号用ならできます。22 kΩと10 kΩで12 Vを3.75 Vに下げ、Arduinoのアナログ入力で読み取れます。ボードやモジュールに電源を供給する用途ではできません。負荷が電流を流した途端に、出力が落ち込みます。電源には、7805のようなレギュレーターや、LM2596のような降圧コンバーターを使ってください。
5 Vを3.3 Vに変換するにはどの抵抗が必要ですか?
もっとも一般的な組み合わせは信号側1 kΩ、グラウンド側2 kΩで、5 Vを3.33 Vにします。10 kΩと20 kΩでも同じ比になりますが、高速な信号には小さい値のほうが適しています。2 kΩがなければ、2.2 kΩと3.3 kΩで3.0 Vになり、ESP32とPicoはこれでもHIGHと読み取ります。
分圧回路の抵抗値はどう選べばいいですか?
まず最大入力電圧とピンの上限から比を決め、次にR2(通常は10 kΩ)を選んでR1を計算します。合計抵抗が小さいと分圧回路が電流を無駄にし、大きすぎると負荷効果とADCの誤差が大きくなります。Arduinoでは出力抵抗を10 kΩ未満に、電池のプロジェクトでは合計を100 kΩ前後にすると、バランスが良くなります。
Arduinoで12 Vを測るには?
バッテリーのプラス端子を22 kΩを通してA0に、A0を10 kΩを通してGNDに、バッテリーのマイナス端子をArduinoのGNDにつなぎます。コードでは、analogRead()の値に5 / 1024を掛けてピンの電圧を求め、さらに3.2を掛けてバッテリーの電圧を求めます。この分圧回路なら、16 Vまで安全に測れます。
分圧回路は電池を消耗させますか?
はい。分圧回路には常にI = Vin / (R1 + R2)の電流が流れます。32 kΩの分圧回路は12 Vで0.375 mA、1日で約9 mAhを消費します。車のバッテリーなら問題になりませんが、小さな電池では無視できません。電池のプロジェクトでは、100 kΩ前後の抵抗とアナログピンの100 nFのコンデンサを使うか、分圧回路を機器のスイッチの後ろにつないでください。
この記事を読んだ後に作れるプロジェクト
全プロジェクトを見る
LDRで光の強さを測定
部屋の明るさを数値で見てみませんか?光に反応する小さな部品、LDRで周囲の光を測定し、Arduinoが0.5秒ごとにその値をコンピューターの画面に表示します。手で覆うと数値が変わる様子を確認できます。自動で点灯する常夜灯などのプロジェクトへの第一歩です。

LDRで作る常夜灯
暗くなると自動で点灯し、朝になると消灯する小さな常夜灯です。光センサーが部屋の明るさを測定し、Arduinoが十分に暗くなったらLEDを点灯させ、明るくなったら消灯させます。街灯が夕方になると自動で点灯する仕組みも理解できます。

ESP32とLDRモジュールで光の強さを読み取る
LDRモジュールの生のADC値と、暗い状態・明るい状態の基準値から計算した相対的な明るさの割合を、シリアルモニタでリアルタイムに確認します。この割合はルクスの測定値ではありません。モジュールの校正の仕組みを学べます。しきい値の決定に使うため、プロジェクト10の前に取り組むのが適しています。

LCDディスプレイ付きデジタル電圧計
自作の測定器で、電池や電源アダプターが出力する電圧を調べます。2つの抵抗で作る分圧回路が、高い電圧をボードで読み取れるレベルまで下げます。Arduinoが元の電圧を計算し、2行のLCDディスプレイにボルト単位で表示します。この回路では約55ボルトまでの直流電圧を測定できます。コンセントの商用電源には絶対に接続しないでください。

NTCと2x16 LCDディスプレイで温度を測定
小さなビーズのようなセンサーで周囲の温度を測ります。NTCというこの部品は、温まるほど電気が流れやすくなります。Arduinoがその変化を読み取り、数式で摂氏温度に変換して、2行のLCDディスプレイに0.5秒ごとに表示します。手のひらでセンサーを温めて、数値が上がる様子を見るのも楽しみの1つです。

ESP32とLDRで作るナイトライト
暗くなるとLEDが自動で点灯し、明るくなると消灯するナイトライトです。LDRセンサーモジュールのD0(デジタル出力)ピンを使います。モジュール上の小さな可変抵抗で暗さのしきい値を設定すると、モジュール自体がHIGH/LOWを出力します。ESP32はdigitalRead()でこの信号を読み取るだけなので、コードはとてもシンプルです。

ESP32とHC-SR04で作る超音波距離計
HC-SR04超音波センサーは、発した音波が物体に反射して戻るまでの時間(Time of Flight)を測定して距離を計算します。このプロジェクトでは、ESP32からセンサーのTRIGピンに10マイクロ秒のパルスを送り、ECHOピンからの反射波の持続時間をpulseIn()で読み取ります。計算した距離をcm単位で16x2 I2C LCDに表示します。HC-SR04は5Vで動作するため、ECHOピンには分圧回路が必須です。分圧しないとESP32の3.3V GPIOが破損します。

ESP32と可変抵抗でLEDの明るさを制御(アナログ→PWM)
可変抵抗を使ってLEDの明るさをアナログ操作で調整します。ESP32のADCピンで可変抵抗からの0-3.3Vの電圧を読み取り、PWM(パルス幅変調)信号に変換してLEDに出力します。可変抵抗を回すと、LEDが徐々に明るくなったり暗くなったりします。Arduino Core 3.0+ではanalogWrite()を直接使えます。ESP32-S2/S3ではADCの分解能を12ビットに固定します。
ほかの記事
BlueGraysアプリ
この回路をスマホでステップごとに作る
回路図、コード、部品リストを1つの画面で確認できます。Arduino、ESP32、Picoのプロジェクトを200件以上用意しています。

