ADC 读取模拟信号实战
📅 2026-05-05 · 📂 硬件编程 · ⏱ 阅读约 6 分钟
概述
真实世界是模拟的——温度、光线、声音、压力都是连续变化的量。ADC(模数转换器)把这些模拟信号变成 ESP32 能理解的数字。本篇通过电位器和光敏电阻两个实例,带你掌握 ADC 的使用。
学习目标:理解 ADC 工作原理和分辨率,掌握 analogRead(),学会用分压电路读取传感器。
物料清单
- ESP32 开发板 ×1
- 面包板 ×1
- 10kΩ 电位器(旋转式)×1
- 光敏电阻(LDR, GL5528)×1
- 10kΩ 固定电阻 ×1
- 杜邦线若干
约 5 元。电位器和光敏电阻是学习 ADC 的经典组合。
ESP32 ADC 技术参数
ESP32 有两个 12 位 SAR ADC(ADC1 和 ADC2),共 18 个通道。
| 参数 | 值 |
| 分辨率 | 12 位(0-4095),可配置 9/10/11 位 |
| 输入电压 | 0 ~ 3.3V(默认衰减 11dB 时约 0-3.6V) |
| ADC1 引脚 | GPIO 32-39(推荐使用,WiFi 不受影响) |
| ADC2 引脚 | GPIO 0,2,4,12-15,25-27(WiFi 开启时不可用) |
⚠️ ADC2 限制:WiFi 开启时 ADC2 被占用,读取会返回错误值。读取模拟信号请优先使用 ADC1 的 GPIO 32-39。
实战一:电位器控制 LED 亮度
🔌 接线图
电位器 (10kΩ)
┌───┐
│ ○────── 3.3V
│ │
│ ○────── GPIO32 (ADC1_CH4)
│ │
│ ○────── GND
└───┘
// ADC_Potentiometer.ino — 电位器调光
#define POT_PIN 32 // ADC1_CH4
#define LED_PIN 23
#define PWM_CH 0
void setup() {
Serial.begin(115200);
ledcSetup(PWM_CH, 5000, 8);
ledcAttachPin(LED_PIN, PWM_CH);
analogReadResolution(12); // 12位 = 0-4095
}
void loop() {
int raw = analogRead(POT_PIN); // 0-4095
int brightness = map(raw, 0, 4095, 0, 255);
ledcWrite(PWM_CH, brightness);
float voltage = raw * 3.3 / 4095.0; // 换算电压
Serial.printf("ADC=%4d → %.2fV → PWM=%3d
", raw, voltage, brightness);
delay(100);
}
旋转电位器,LED 亮度随之变化,串口监视器实时显示 ADC 值。
实战二:光敏电阻读取光照强度
🔌 分压电路
3.3V ──┬── (LDR 光敏电阻) ──┬── GPIO34 (ADC1_CH6)
│ │
│ (10kΩ 固定电阻)
│ │
│ GND
光照越强 → LDR电阻越小 → ADC值越大
光照越暗 → LDR电阻越大 → ADC值越小
// ADC_LightSensor.ino — 光敏电阻测光
#define LDR_PIN 34
#define LED_PIN 23
#define THRESHOLD 2000 // 暗/亮阈值
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
analogReadResolution(12);
}
void loop() {
int light = analogRead(LDR_PIN);
if (light < THRESHOLD) {
digitalWrite(LED_PIN, HIGH); // 天黑自动开灯
Serial.println("◑ 暗环境 → 开灯");
} else {
digitalWrite(LED_PIN, LOW);
Serial.println("◐ 明亮 → 关灯");
}
Serial.printf("光强ADC: %d
", light);
delay(500);
}
ADC 精度优化技巧
// 多次采样取平均,提高 ADC 精度
int readADC_Avg(uint8_t pin, int samples = 10) {
long sum = 0;
for (int i = 0; i < samples; i++) {
sum += analogRead(pin);
delay(1);
}
return sum / samples;
}
- ESP32 ADC 原始噪声约 ±30 LSB(约 25mV),多次采样取平均可显著降低噪声
- 硬件层面:在 ADC 引脚和 GND 之间并一个 100nF 电容,滤除高频噪声
- WiFi 开启时噪声会增大,关键测量时关闭 WiFi
常见问题
⚠️ ADC2 与 WiFi 冲突:GPIO 0/2/4/12-15/25-27 属于 ADC2,WiFi 开启时无法使用。采集模拟信号统一用 ADC1(GPIO 32-39)。
⚠️ 输入阻抗:ADC 输入阻抗约 100kΩ,接高阻抗传感器时读数会偏移。用电压跟随器(运放)缓冲信号。
💡 衰减配置:analogSetAttenuation(ADC_11db) 可扩展输入范围到约 3.6V。默认衰减为 11dB。
💡 校准:ESP32 ADC 有非线性。高精度场景(如电池电压监测)需查 Datasheet 中的 ADC 校准曲线,或使用 esp_adc_cal 库。
延伸练习
- 用两个光敏电阻(分压电路 ×2)判断光源方向
- 制作简易电压表(0-3.3V),OLED 显示实时电压
- 用 NTC 热敏电阻替代 LDR,制作温度报警器
- 结合 WiFi 把 ADC 数据上传到云端(ThingSpeak)