ADC 读取模拟信号实战

📅 2026-05-05 · 📂 硬件编程 · ⏱ 阅读约 6 分钟

📺 B站推荐视频:ESP32 入门教程

概述

真实世界是模拟的——温度、光线、声音、压力都是连续变化的量。ADC(模数转换器)把这些模拟信号变成 ESP32 能理解的数字。本篇通过电位器和光敏电阻两个实例,带你掌握 ADC 的使用。

学习目标:理解 ADC 工作原理和分辨率,掌握 analogRead(),学会用分压电路读取传感器。

物料清单

约 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; }

常见问题

⚠️ 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 库。

延伸练习

  1. 用两个光敏电阻(分压电路 ×2)判断光源方向
  2. 制作简易电压表(0-3.3V),OLED 显示实时电压
  3. 用 NTC 热敏电阻替代 LDR,制作温度报警器
  4. 结合 WiFi 把 ADC 数据上传到云端(ThingSpeak)