光敏电阻
大约 3 分钟ESP32Arduino
本节课我们来学习如何通过光敏电阻控制 LED。
实验原理
光敏电阻(photoresistor/light-dependent resistor,缩写为 LDR)是一种基于内光电效应的模拟传感器,一般用于光的测量、控制以及光电转换。常见应用有:
- 光控开关;
- 环境检测系统中的日光追踪。

它包含两个电极引线,一片陶瓷基体,用硫化镉或者是硒化镉等材料制成,核心部分是光电导体。光敏电阻的工作原理基于光电效应,利用光照下半导体材料的电导率发生改变的特性。有光照时产生载流子参与导电,在外加电场的作用下做漂移运动,电子向正极,空穴向负极,电阻值减小;光照消失后,电子空穴对复合,阻值也恢复原值,就像是一个自动的滑动变阻器,能随着光照强度的不同改变阻值。
简单来说,光照越强,光敏电阻的阻值越小;光照越弱,阻值越大。
光敏电阻的电路非常简单,分为以下两种方法:
- 光敏电阻与一个电阻串联,电阻接 +5V,光敏电阻接 GND。光照越强,光敏电阻的阻值越小,分配到的电压越小,ADC 读取到的值就越小;
- 光敏电阻与一个电阻串联,电阻接 GND,光敏电阻接 +5V。光照越强,光敏电阻的阻值越小,分配到的电压越小,ADC 读取到的是固定电阻的电压,因此,ADC 读取到的值越大。

硬件电路设计
物料清单(BOM 表):
材料名称 | 数量 |
---|---|
光敏电阻 | 1 |
LED | 2 |
10KΩ 电阻 | 1 |
1kΩ 电阻 | 2 |
杜邦线(跳线) | 若干 |
将材料按照下图相连:

软件程序设计
1. 在串口监视器中显示
我们可以先把读取到的光敏电阻的值打印在串口监视器中,代码如下:
#define LDR 27
// 初始化光敏电阻输入信号
int ldr_value;
void setup() {
// 设置串口通信波特率 9600
Serial.begin(9600);
pinMode(LDR, INPUT);
}
void loop() {
// 读取光敏电阻模拟输入值
ldr_value = analogRead(LDR);
// 打印模拟值在串口屏上
Serial.println(ldr_value);
delay(100);
}
2. 根据光亮控制 LED
我们可以使用光敏电阻来控制 LED 的亮灭,这里需要准备 2 个 LED,其中一个 LED 负责接受 ADC 值,输出 PWM,光照越高,亮度越小;另一个 LED 则模拟日常生活中常见的楼梯间的光控灯,当光照强度过低时点亮,强度过高时熄灭。代码如下:
#define LDR 27
#define PWM 4
#define LED 2
#define FREQ 2000 // 频率
#define CHANNEL 0 // 通道
#define RESOLUTION 12 // 分辨率
// 初始化光敏电阻输入信号
int ldr_value;
void setup() {
// 设置串口通信波特率 9600
Serial.begin(9600);
// 设置引脚模式
pinMode(LDR, INPUT);
pinMode(PWM, OUTPUT);
pinMode(LED, OUTPUT);
// PWM初始化
ledcSetup(CHANNEL, FREQ, RESOLUTION); // 设置通道
ledcAttachPin(PWM, CHANNEL); // 将通道与对应的引脚连接
}
void loop() {
// 读取光敏电阻模拟输入值
ldr_value = analogRead(LDR);
// 打印模拟值在串口屏上
Serial.println(ldr_value);
// 将光敏电阻的模拟输入值转换成 LED 的 PWM
ledcWrite(CHANNEL, ldr_value);
// 控制 LED 的亮灭
if (ldr_value > 3000) {
digitalWrite(LED, HIGH);
}else {
digitalWrite(LED, LOW);
}
delay(100);
}
注意
如果你在搭建搭建光敏电阻电路的时候,使用的是第二种方法(固定电阻接 GND,光敏电阻接 VCC),那么你使用以上程序获取到的值是完全相反的,实现的效果也是相反的。