Arduinoと光センサー(CdSセル)で作る自動点灯ライト【分圧回路・キャリブレーション・常夜灯まで完全解説】
「暗くなったら自動でライトが点く仕組み、自分で作れたら面白そう…」そう思ったことはありませんか?😊
実はArduinoと光センサー(CdSセル)を組み合わせるだけで、市販の常夜灯と同じ「明るさ連動の自動点灯ライト」が自作できます。しかも回路の仕組みをきちんと理解しながら作れるのが、電子工作の醍醐味です。
この記事では、光センサーの分圧回路の仕組みから、analogReadのしきい値キャリブレーション手順、シリアルモニタを使ったデバッグ、そして「暗くなったら点灯する常夜灯」の完成例まで、ひとつひとつ丁寧に解説します。
※ LEDの基本的な点滅(Lチカ)やPWM制御については、以下の記事で詳しく扱っています。本記事では光センサーの活用に特化して深掘りしていきます。
🔧 この記事の対象読者・難易度

- ✅ Arduinoで光センサーを使ってみたい方
- ✅ 分圧回路の仕組みをちゃんと理解したい方
- ✅ センサーのしきい値調整でつまずいている方
- ✅ シリアルモニタを使ったデバッグに慣れたい方
難易度:★★☆☆☆(初級〜初中級)
LEDのLチカ程度の経験があればスムーズに進められます。
📦 用意するもの
- Arduino Uno(またはArduino互換ボード)
- 光センサー(フォトレジスタ / CdSセル)× 1
- 抵抗 10kΩ × 1(分圧回路用)
- LED(色は好みで)× 1
- 抵抗 220Ω〜330Ω × 1(LED保護用)
- ジャンパーワイヤー(数本)
- ブレッドボード
- USBケーブル(Type-B)
- PC(Arduino IDEをインストール済み)
💡 光センサー(CdSセル)とは?仕組みをざっくり理解しよう
光センサー(フォトレジスタ、またはCdS=硫化カドミウムセル)は、光の量によって電気抵抗が変化する部品です。
- ☀️ 明るいとき:抵抗が小さくなる(数百Ω〜数kΩ程度)
- 🌙 暗いとき:抵抗が大きくなる(数十kΩ〜数百kΩ程度)
つまり「光の強さを抵抗値という電気的な量に変換してくれる」センサーです。Arduinoはこの抵抗値の変化を電圧の変化として読み取ることで、明るさを数値として把握できます。
なぜ10kΩの抵抗とセットで使うの?→ 分圧回路の仕組み
光センサー単体をArduinoにつないでも、残念ながら「明るさ」は読み取れません。抵抗値の変化を電圧の変化に変換する回路が必要で、これを分圧回路(ボルテージディバイダ)と呼びます。
回路のイメージはこうです:
5V ──── [CdSセル] ──── A0(Arduinoのアナログピン)
|
[10kΩ抵抗]
|
GND
5VとGNDの間に「CdSセルの抵抗」と「10kΩの固定抵抗」が直列に並んでいます。このとき、A0ピンにかかる電圧は次の式で求まります。
A0の電圧 = 5V × 10kΩ ÷ (CdSの抵抗 + 10kΩ)
たとえば……
- 🌞 明るいとき(CdS抵抗 ≒ 1kΩ):5V × 10 ÷ (1+10) ≒ 4.5V → 高い電圧
- 🌙 暗いとき(CdS抵抗 ≒ 100kΩ):5V × 10 ÷ (100+10) ≒ 0.45V → 低い電圧
このように光の量が「A0にかかる電圧」として現れるようになります。ArduinoのanalogRead()はこの電圧を0〜1023の整数値に変換して読み取ります(5V → 1023、0V → 0)。
⚠️ 10kΩ抵抗はCdSセルと同じオーダーの抵抗値を選ぶのがポイントです。抵抗が小さすぎると暗い場合の変化が読み取りにくくなり、大きすぎると明るい場合の変化が潰れてしまいます。一般的なCdSセルには10kΩがよく合います。
🔌 回路のつなぎ方
ブレッドボード上に以下のように接続してください。
光センサー(分圧回路)部分
- CdSセルの片方の足を 5Vピン に接続
- もう一方の足を アナログピンA0 に接続
- 同じA0の接続点から 10kΩ抵抗 を通して GND に接続
LED部分
- LEDの長い足(アノード)を 220Ω抵抗 を通して デジタルピン9番 に接続
- LEDの短い足(カソード)を GND に接続
⚠️ LEDの保護抵抗(220Ω)は必ず入れてください。省略するとLEDが壊れます。
📟 まずシリアルモニタでセンサー値を確認しよう
いきなりLEDを制御するのではなく、まずセンサーがどんな値を返しているか確認するのが成功への近道です。シリアルモニタはArduino内蔵のデバッグツールで、センサー値をリアルタイムにPC画面で確認できます。
// センサー値確認スケッチ:シリアルモニタで光センサーの値を見る
void setup() {
Serial.begin(9600); // シリアル通信を9600bpsで開始
}
void loop() {
int sensorValue = analogRead(A0); // センサーの値を読む(0〜1023)
Serial.print("センサー値: ");
Serial.println(sensorValue); // 値を改行付きで出力
delay(200); // 0.2秒ごとに更新
}
このスケッチをArduinoに書き込んだら、Arduino IDE上部の虫眼鏡アイコン(または「ツール」メニュー)からシリアルモニタを開いてください。ボーレートを9600に合わせることを忘れずに。
センサーの上に手をかざして暗くしたり、明るい場所にかざしたりしながら数値の変化を観察しましょう。たとえばこんな結果が得られるはずです 👇
- 室内の蛍光灯下:センサー値 650〜750 前後
- センサーを指で覆う(擬似的な暗闇):センサー値 100〜250 前後
- スマホのライトを直当て:センサー値 900〜1023 前後
※ 値は使用するCdSセルの個体差や室内環境によって大きく異なります。この観察が次のキャリブレーション作業の根拠になります。
🎛️ しきい値のキャリブレーション手順
「暗くなったらLEDを点灯する」には、「どの値以下になったら暗いとみなすか」のしきい値(threshold)を決める必要があります。これはコピペした数値で済む話ではなく、実際の環境に合わせたキャリブレーションが必要です。
キャリブレーションの手順
ステップ1:「点灯させたい暗さ」の値を記録する
先ほどのシリアルモニタ確認スケッチを使って、「ここより暗くなったらLEDを点けたい」と思う状況(たとえば部屋の電気を消した状態、夕暮れを模した状態など)でのセンサー値を記録します。
ステップ2:「消灯していてほしい明るさ」の値を記録する
次に「昼間の明るい状態でLEDは消えていてほしい」状況のセンサー値を記録します。
ステップ3:しきい値を2つの値の中間に設定する
たとえば、暗い状態が値200、明るい状態が値700であれば、しきい値は中間の400〜450あたりが妥当です。誤検知を防ぐため、両端の値からある程度余裕を持たせるのがコツです。
チャタリング(誤作動)を防ぐヒステリシスの考え方
しきい値をひとつだけ設定すると、センサー値がしきい値付近でわずかに揺れるたびにLEDがON/OFFを繰り返してしまいます(チャタリング)。これを防ぐためにヒステリシス(上限と下限を別々に設定する)という考え方を使います。
// ヒステリシスを使ったしきい値設定の例
// 点灯開始:センサー値が 350 以下になったら
// 消灯開始:センサー値が 500 以上になったら
#define THRESHOLD_ON 350 // この値以下になったらLED点灯
#define THRESHOLD_OFF 500 // この値以上になったらLED消灯
ON/OFFの境界に「幅」を持たせることで、センサー値が少々ばらついても安定した動作が実現できます。
🌙 完成形:暗くなったら点灯する常夜灯スケッチ
キャリブレーションで決めたしきい値を組み込んだ、常夜灯の完成スケッチです。シリアルモニタへの出力も残してあるので、動作確認しながら使えます。
// 自動点灯ライト完成版:暗くなったらLEDが光る常夜灯
// ヒステリシス付きで誤作動を防止
const int SENSOR_PIN = A0; // 光センサー(CdSセル)のアナログピン
const int LED_PIN = 9; // LEDのデジタルピン
// ★ 自分の環境に合わせてこの値を調整してください
const int THRESHOLD_ON = 350; // この値以下になったらLED点灯
const int THRESHOLD_OFF = 500; // この値以上になったらLED消灯
bool ledState = false; // 現在のLEDの状態(false=消灯)
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
Serial.println("=== 自動点灯ライト 起動 ===");
}
void loop() {
int sensorValue = analogRead(SENSOR_PIN);
// シリアルモニタでリアルタイム確認
Serial.print("センサー値: ");
Serial.print(sensorValue);
Serial.print(" LED: ");
Serial.println(ledState ? "点灯" : "消灯");
// ヒステリシスを使った点灯・消灯判定
if (!ledState && sensorValue <= THRESHOLD_ON) {
// 現在消灯中 かつ しきい値以下になった → 点灯
ledState = true;
digitalWrite(LED_PIN, HIGH);
Serial.println(">> 暗くなりました。LED点灯!");
} else if (ledState && sensorValue >= THRESHOLD_OFF) {
// 現在点灯中 かつ しきい値以上になった → 消灯
ledState = false;
digitalWrite(LED_PIN, LOW);
Serial.println(">> 明るくなりました。LED消灯。");
}
delay(100); // 0.1秒ごとにセンサーを読む
}
コードのポイント解説
const int THRESHOLD_ON = 350:点灯開始のしきい値。自分の環境に合わせて変更してくださいconst int THRESHOLD_OFF = 500:消灯開始のしきい値。ONより高めに設定することでヒステリシスを実現bool ledState:現在のLED状態を記憶する変数。「今点いているかどうか」を管理することで不要なdigitalWrite呼び出しを防ぎます!ledState && sensorValue <= THRESHOLD_ON:消灯中にしきい値以下になったときだけ点灯処理を実行ledState && sensorValue >= THRESHOLD_OFF:点灯中にしきい値以上になったときだけ消灯処理を実行
🔍 シリアルモニタを使ったデバッグの実践
「スケッチを書き込んだのにLEDが思うように動かない」……そんなときに頼りになるのがシリアルモニタです。上記の完成スケッチを書き込んだ状態でシリアルモニタを開くと、こんなログが流れるはずです。
=== 自動点灯ライト 起動 ===
センサー値: 712 LED: 消灯
センサー値: 698 LED: 消灯
センサー値: 421 LED: 消灯
センサー値: 312 LED: 消灯
>> 暗くなりました。LED点灯!
センサー値: 289 LED: 点灯
センサー値: 305 LED: 点灯
センサー値: 534 LED: 点灯
>> 明るくなりました。LED消灯。
センサー値: 650 LED: 消灯
よくあるトラブルと確認ポイント
❌ センサー値がずっと0か1023のまま変化しない
→ 分圧回路の接続を確認してください。CdSセルと10kΩ抵抗が直列に正しく接続されているか、A0ピンに中間点が接続されているかを見直しましょう。
❌ LEDがON/OFFを高速で繰り返す
→ THRESHOLD_ONとTHRESHOLD_OFFの差が小さすぎます。差を150〜200程度に広げてみてください。
❌ 暗くしてもLEDが点灯しない
→ シリアルモニタで暗い状態の実際の値を確認し、THRESHOLD_ONをその値より高く設定し直してください。
❌ シリアルモニタに文字化けした文字が出る
→ シリアルモニタ右下のボーレート設定が9600になっているか確認してください。スケッチのSerial.begin(9600)と一致させる必要があります。
🚀 発展:センサー値に比例してLEDの明るさを変える
「暗いほどLEDを明るく光らせる」という、より自然な常夜灯の動作にしてみましょう。map()関数を使うとセンサー値の範囲をPWMの範囲に変換できます。
※ PWM(analogWrite)自体の基礎は「Arduino入門|電子工作初心者が最初に作るべきLEDプロジェクト5選」で詳しく解説しています。ここではセンサー値と連動させる部分に絞って説明します。
// 発展版:センサー値に応じてLEDの明るさを変える(PWMピン使用)
const int SENSOR_PIN = A0;
const int LED_PIN = 9; // PWM対応ピン(~マーク付き)
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(SENSOR_PIN); // 0〜1023
// センサー値が低い(暗い)ほどLEDを明るく(255に近く)する
// map(値, 入力最小, 入力最大, 出力最小, 出力最大)
int brightness = map(sensorValue, 0, 1023, 255, 0);
brightness = constrain(brightness, 0, 255); // 0〜255に収める
analogWrite(LED_PIN, brightness);
Serial.print("センサー値: ");
Serial.print(sensorValue);
Serial.print(" 明るさ(PWM): ");
Serial.println(brightness);
delay(50);
}
map(sensorValue, 0, 1023, 255, 0):入力が0のとき出力255、入力が1023のとき出力0になるよう線形変換しますconstrain(brightness, 0, 255):変換後の値を必ず0〜255の範囲に収めるための安全措置です
手でセンサーを覆うほどLEDがじわっと明るくなる……まるで本物の常夜灯みたいな動作が確認できるはずです。✨
📝 まとめ
この記事では、Arduinoと光センサー(CdSセル)を使った自動点灯ライトの制作を通じて、以下のことを学びました。
- ✅ 分圧回路の仕組み:CdSセルと10kΩ抵抗を直列につなぐことで、抵抗値の変化を電圧の変化に変換できる
- ✅ シリアルモニタを使ったセンサー値の観察:まず数値の挙動を確認することがキャリブレーションの第一歩
- ✅ しきい値のキャリブレーション手順:環境ごとに「暗い状態の値」と「明るい状態の値」を実測して中間に設定する
- ✅ ヒステリシスによる安定動作:ON/OFFのしきい値に幅を持たせてチャタリングを防ぐ
- ✅ 発展:map()関数でPWM制御:明るさに連動してLEDの輝度を変化させる
「センサーの値を読んで、条件を判定して、出力を制御する」——この流れはArduino電子工作のあらゆる応用に共通する基本パターンです。光センサーで会得したこの感覚を、温度センサーや距離センサーにもぜひ応用してみてください。🎉
Lチカや電子工作キットの最初の一歩については、こちらの記事も参考にどうぞ。
こちらも読まれています
📡 Arduinoをもっと深く学ぼう!
Arduino・ラズパイ・ロボットプログラミングを体系的に学びたい方へ。おすすめのUdemyコースや電子部品もまとめています。
📚 関連商品・おすすめ書籍
※本記事にはアフィリエイトリンクが含まれます。





