LDR光センサーとは?Arduinoで明るさを測り、自動常夜灯を作る
LDR(フォトレジスター)はどう動くのか。分圧回路の配線、合う抵抗の選び方、analogReadでの明るさの読み取り、ヒステリシス付きの常夜灯、LDRモジュール、ESP32とPicoでの使い方、よくあるミスを解説します。
LDR(Light Dependent Resistor)は、名前のとおり光によって抵抗値が変わる抵抗で、フォトレジスターや光導電セルとも呼ばれます。暗いところでは抵抗値がとても高く、光が強くなるほど抵抗値が下がります。夕暮れに点く街灯、自動常夜灯、光に反応するおもちゃは、どれもこのシンプルな部品で動いています。安くて極性がなく、抵抗1本でArduinoにつなげるので、初めての光のプロジェクトにぴったりです。

LDRはどう動く?
LDRの表面のジグザグ模様は、光に反応する半導体の硫化カドミウム(CdS)です。光が当たると光子が材料の中の電子を自由にし、電気が流れやすくなって抵抗値が下がります。この変化は直線的ではなく、比較的ゆっくり(数十ミリ秒)です。そのため、LDRは光をルクス単位で正確に測るのではなく、「暗いか明るいか」の判断や、おおまかな明るさのレベルに向いています。
| 状況 | LDRのおおよその抵抗値(GL5528) |
|---|---|
| 真っ暗 | 1 MΩ以上 |
| 常夜灯の明かり(約1ルクス) | 50〜100 kΩ |
| 薄暗い部屋(約10ルクス) | 10〜20 kΩ |
| 明るい部屋(約100ルクス) | 3〜5 kΩ |
| デスクライトの下(約1000ルクス) | 約1 kΩ |
| 昼光 | 数百Ω |
値はモデルによって違います。キットでいちばんよく見かけるのはGL5528で、GL5516、GL5537、GL5539のような兄弟モデルは、同じ明るさでも違う抵抗値を示します。自分のLDRの値は、暗いところと明るいところでテスターを使って測れば簡単にわかります。
Arduinoへのつなぎ方:分圧回路
Arduinoが測るのは抵抗ではなく電圧です。そこでLDRを固定抵抗と組み合わせ、分圧回路を作ります。5V → LDR → A0 → 10 kΩ → GNDという配線です。光が強くなるとLDRの抵抗値が下がり、A0の電圧が上がります。A0の電圧はV = 5 × R固定 / (RLDR + R固定)で求められ、analogRead()がそれを0〜1023の数値に変えます。いろいろな抵抗値を試すには分圧回路計算ツールを使ってください。
| 明るさ | LDRの抵抗値 | A0の電圧 | analogRead |
|---|---|---|---|
| 真っ暗 | 1 MΩ | 0.05 V | 約10 |
| 薄暗い部屋 | 15 kΩ | 2.0 V | 約410 |
| 明るい部屋 | 4 kΩ | 3.6 V | 約730 |
| デスクライトの下 | 1 kΩ | 4.5 V | 約930 |
Arduinoで明るさを読み取る
1const int LDR_PIN = A0;
2
3void setup() {
4 Serial.begin(9600);
5}
6
7void loop() {
8 int raw = analogRead(LDR_PIN); // 0 (karanlık) – 1023 (aydınlık) / dark – bright
9 int percent = map(raw, 0, 1023, 0, 100); // yüzde / percent
10 Serial.print("Ham / raw: ");
11 Serial.print(raw);
12 Serial.print(" Işık / light: %");
13 Serial.println(percent);
14 delay(500);
15}Arduino IDEのシリアルプロッタを使うと、値をリアルタイムのグラフで見られます。LDRを手でおおうとグラフが下がり、懐中電灯で照らすと上がります。センサーを実際に置く場所に置いた状態で、プロジェクトに合うしきい値を見つけるいちばん簡単な方法です。
自動常夜灯:しきい値とヒステリシス
いちばん簡単な常夜灯は「値が300未満ならLEDを点ける」というものです。しかし、明るさがちょうどしきい値のあたりを行き来すると、ランプが点いたり消えたりを繰り返します。ランプ自身の光がLDRに当たると、さらにひどくなります。対策はヒステリシス、つまり2つの違うしきい値を使うことです。下のコードは、明るさが300を下回るとランプを点け、400を上回るまでは消しません。この間の幅のおかげで、ちらつきが完全になくなります。
1const int LDR_PIN = A0;
2const int LED_PIN = 9;
3const int ON_LEVEL = 300; // bunun altında yak / turn on below this
4const int OFF_LEVEL = 400; // bunun üstünde söndür / turn off above this
5
6bool lampOn = false;
7
8void setup() {
9 pinMode(LED_PIN, OUTPUT);
10}
11
12void loop() {
13 int light = analogRead(LDR_PIN);
14 if (!lampOn && light < ON_LEVEL) lampOn = true;
15 if (lampOn && light > OFF_LEVEL) lampOn = false;
16 digitalWrite(LED_PIN, lampOn ? HIGH : LOW);
17 delay(200);
18}暗くなるほど明るくなるLED
オン・オフで切り替えるのではなく、暗くなるにつれてLEDを少しずつ明るくすることもできます。map()関数は測った明るさを反比例するPWMの値に変えるので、部屋が暗くなるほどLEDは明るく光り、明るくなるほど暗くなります。LEDは~の付いたPWMピン(たとえば9番)につなぐのを忘れないでください。
1void loop() {
2 int light = analogRead(A0);
3 int brightness = map(light, 100, 900, 255, 0); // karanlık → parlak / dark → bright
4 analogWrite(9, constrain(brightness, 0, 255));
5 delay(50);
6}LDRモジュール:デジタル出力とアナログ出力
既製のLDRモジュールには、LDR、分圧用の抵抗、しきい値を決める青い半固定抵抗(トリマー)、LM393コンパレーターが1枚の基板に載っています。AOピンは分圧回路のアナログ出力を、DOピンは半固定抵抗で設定したしきい値に応じてHIGHかLOWだけを出します。ほとんどのモジュールでは、しきい値より明るいとDOがLOW、暗いとHIGHになります。お手元のモジュールは簡単なテストで確認してください。
| ピン | 機能 |
|---|---|
| VCC | 電源(3.3〜5 V) |
| GND | グラウンド |
| DO | デジタル出力:しきい値は半固定抵抗で設定 |
| AO | アナログ出力:分圧回路の中点 |
ESP32とRaspberry Pi PicoでLDRを使う
ESP32とPicoは3.3 Vで動くので、分圧回路は3V3ピンから給電します。ESP32のADCは12ビットで、0〜4095の値を返します。ADC2のピンはWi-Fiがオンの間は使えないので、LDRはADC1のピン(GPIO 32〜39)のどれかにつないでください。Picoのアナログ入力はGP26、GP27、GP28で、MicroPythonのread_u16()は0〜65535の値を返します。
1from machine import ADC, Pin
2import time
3
4ldr = ADC(26) # GP26 (ADC0); bölücü 3V3'ten / divider fed from 3V3
5led = Pin(15, Pin.OUT)
6
7while True:
8 light = ldr.read_u16() # 0 (karanlık) – 65535 (aydınlık) / dark – bright
9 led.value(light < 20000) # karanlıkta yak / on when dark
10 print(light)
11 time.sleep(0.5)LDRとデジタル光センサー、どちらを選ぶ?
| 項目 | LDR | BH1750(デジタル) |
|---|---|---|
| 出力 | アナログ(抵抗値の変化) | デジタル(I2C)、ルクスを直接出力 |
| 精度 | おおまか。温度やモデルの影響を受ける | 正確で校正済み |
| 反応速度 | 遅い(数十ミリ秒) | 速い |
| 価格 | とても安い | 少し高い |
| 向いている用途 | 暗い・明るいの判断、常夜灯 | 照度の測定、植物用照明、画面の明るさ |
LDRのプロジェクトアイデア
- 自動常夜灯:暗くなると点き、ヒステリシスのおかげでちらつかないランプです。
- スマート廊下灯:LDRとPIR人感センサーを組み合わせ、暗いときに人が通った場合だけ点けます。
- 太陽を追うパネル:2つのLDRの差に応じてサーボを回し、パネルをいちばん明るい方向に向けます。
- レーザー防犯システム:レーザー光をLDRに当てておき、光がさえぎられたらアラームを鳴らします。
- カラフルな間接照明:暗くなるにつれてRGB LEDを暖色に寄せていきます。
- 日の出アラーム:朝の最初の光でブザーを鳴らします。
よくあるミスと直し方
- 値がずっと0、またはずっと1023:固定抵抗がないか、LDRが5VとA0の間に直接つながっています。分圧回路を組んでください。
- 値が逆に動く:LDRと固定抵抗の位置が入れ替わっています。暗いと値が上がる場合は、2つを入れ替えるか、コードの比較を逆にしてください。
- ランプがちらつく:ランプの光がLDRに当たっているか、しきい値が1つしかありません。ヒステリシスを加えてください。
- 暗くなったときに遅れる:LDRは暗から明よりも、明から暗に戻るほうがゆっくりです。数秒の遅れは正常です。
- ルクスを測ろうとしている:LDRは校正されたセンサーではありません。本当のルクス値にはBH1750を使ってください。
- ESP32でWi-Fiが始まると読み取りがおかしくなる:LDRがADC2のピンにつながっています。GPIO 32〜39のADC1のピンに移してください。
LDRは、アナログ読み取りと分圧回路の考え方を学ぶいちばん簡単な方法で、ここで学んだことは土壌水分、ガス、温度などの多くのアナログセンサーにも役立ちます。分圧用の抵抗のしくみが気になる場合は抵抗とは?を見てください。BlueGraysアプリには、LDRの常夜灯、明るさレベル、レーザー防犯のプロジェクトがステップごとに載っています。
よくある質問
LDRにはどの抵抗を使えばいいですか?
いちばん一般的なのは10 kΩで、ほとんどの屋内プロジェクトでうまく動きます。暗い場所で感度を上げたいなら47 kΩ、とても明るい環境なら1 kΩを選びます。基本は、気にしたい明るさでのLDRの抵抗値に近い固定抵抗を選ぶことです。
LDRにプラスとマイナスの足はありますか?
いいえ。LDRはふつうの抵抗と同じく極性がないので、どちら向きに付けてもかまいません。大事なのは、固定抵抗と組み合わせて正しい分圧回路を作ることです。
LDRでルクスを測れますか?
おおよその推定はできますが、正確ではありません。LDRの反応は直線的ではなく、モデルによって、さらには温度によっても変わります。本当のルクス値が必要なら、BH1750やTSL2561のようなデジタル光センサーを使ってください。
LDRモジュールのDOピンとAOピンの違いは何ですか?
AOは光の強さに応じて変わるアナログ電圧を出し、analogRead()で読み取ります。DOはモジュールの半固定抵抗で設定したしきい値に応じてHIGHかLOWだけを出し、digitalRead()で読み取ります。オン・オフで済む用途に便利です。
暗くなったときにLDRの反応が遅いのはなぜですか?
光がなくなってからCdS材料が暗いときの抵抗値に戻るまでには数秒かかりますが、明るいほうへの変化はずっと速く起こります。これはLDRがもともと持つ性質です。速い反応が必要な用途には、フォトダイオードやフォトトランジスタが使われます。
ESP32でLDRの値がずっと4095のまま、またはまったく変わらないのはなぜですか?
分圧回路を5Vから給電していると、電圧がADCの上限を超えて値が4095に張り付きます。分圧回路は3V3から給電してください。まったく変わらない場合は、LDRがADC2のピンにつながっている可能性があります。ADC2はWi-Fiがオンの間は動かないので、GPIO 32〜39のADC1のピンを使ってください。
この記事を読んだ後に作れるプロジェクト
全プロジェクトを見る
LDRで光の強さを測定
部屋の明るさを数値で見てみませんか?光に反応する小さな部品、LDRで周囲の光を測定し、Arduinoが0.5秒ごとにその値をコンピューターの画面に表示します。手で覆うと数値が変わる様子を確認できます。自動で点灯する常夜灯などのプロジェクトへの第一歩です。

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

レーザー警報システム
映画のような、目に見えない光のフェンスを作ります。向かい側の光センサーにレーザーを当て、人が通って光を遮るとすぐにLEDが点灯し、ブザーが鳴ります。光が再び届くと、LEDが消灯し、ブザーも止まります。ドアや廊下に使える、シンプルながら印象的な警報装置です。

レーザー防犯システム
映画のレーザーを使った強盗シーンのように、光センサーにレーザー光を当て、人が間に入って光を遮ると、赤いLEDが点灯してブザーが鳴り始めます。警報は自動では止まらず、ボタンやリモコンの電源ボタンで停止します。異常がないときは緑のLEDが点灯します。ドアや引き出しに、目に見えない見張り役を置くユニークな方法です。

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

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

ESP32スマート照明(PIR + LDR + リレー + OLED)
ESP32で廊下やトイレ、食品庫の照明をスマート化します!PIRモーションセンサー、LDR光センサー、リレーモジュールを使い、「暗い場所で動きを検知すると点灯する」定番の仕組みを作ります。周囲が明るければ動きを検知しても点灯しないため、日中の無駄な電力消費を抑えられます。照明は30秒間点灯し、動きが続くとタイマーがリセットされて点灯時間が延びます。SSD1306 OLEDには大きな文字で状態(ON / DAYTIME / WAITING)とカウントダウンを表示します。

ESP32 PIR人感センサーによる自動照明
このプロジェクトでは、HC-SR501 PIR人感センサーで部屋に入った人を検知し、LEDを自動で点灯させます。millis()で点灯時間を管理します。センサーの値がHIGHの間は最後に動きを検知した時刻を更新し、最後にHIGHを読み取ってから少なくとも10秒後にLEDを消灯します。現在のコードは各ループでdelay(50)により50 ms待機するため、完全にノンブロッキングではありません。階段や廊下、浴室、戸棚内の照明などに応用できます。
ほかの記事
BlueGraysアプリ
この回路をスマホでステップごとに作る
回路図、コード、部品リストを1つの画面で確認できます。Arduino、ESP32、Picoのプロジェクトを200件以上用意しています。

