模块熟悉

第 10 课:电位器与 ADC

从"高或低"跨到"连续的值",这是模拟量世界的大门

我是吴老师。这节课是「模块熟悉」单元的开篇,也是整套课里一个重要的分界线。

前面几节课你接触的输入,都是数字的——按钮要么按下、要么没按,没有中间状态。非黑即白。

从这节课开始,我们进入模拟的世界——连续变化的量。光线有多亮、温度有多高、声音有多响,这些都不是"是/否",而是"多少"。

而电位器,是最适合入门模拟输入的东西。因为它最简单:你转一下旋钮,数值就变。

一、先认识电位器

电位器就是一个能拧的旋钮。你家里的音响音量旋钮、老式台灯的调光旋钮,都是这东西。

它长这样:一个蓝色的方块,上面有个小十字槽,可以用小螺丝刀拧。

针脚 接到
VCC 3.3V
GND GND
OUT 一个模拟引脚GPIO0 ~ GPIO5

注意最后一行——模拟引脚只有 6 个。 这件事第 4 课提过:

ESP32-C3 能用的引脚有 13 个,但支持模拟输入的只有 GPIO0GPIO5 这 6 个。

你手上的光敏、热敏、麦克风、电位器,全都要往这 6 个里面挤。 接之前先规划好。

好,接好了。现在跑一下程序,拧旋钮看数字——你大概会看到它从 0 慢慢变到 4095。

为什么是 4095? 这就是这节课要讲的东西。

二、ADC:把电压翻译成数字

先抛出一个问题。

你的手拧旋钮,这是个物理动作。板子读到的是一串数字。这中间发生了什么?

答案叫 ADC(Analog-to-Digital Converter,模数转换器)。

模拟输入的过程:连续电压经 ADC 转换成一串数字

它干的事,说白了就是"翻译"

  • 引脚上的电压是连续的——理论上可以是 1.23456…… 伏,有无数种可能
  • 数字只能是一格一格的,不能有无穷多种

ADC 把电压切成 4096 格,看它在第几格。

电压 读到的数字
0V 0
1.65V(大约一半) 2048(大约一半)
3.3V 4095

为什么要切成 4096 格? 因为 ESP32-C3 的 ADC 是 12 位的。

"12 位"的意思是:用 12 个二进制位来表示一个数。 2 的 12 次方 = 4096,所以能表示 0 到 4095 这 4096 个值。

打个比方:你用一把尺子量东西。尺子上有多少条刻度线,你就能量得多细。

  • 8 位 ADC = 尺子上 256 条刻度 → 比较粗
  • 10 位 ADC = 1024 条刻度 → 中等(这是老式 Arduino Uno 的水平)
  • 12 位 ADC = 4096 条刻度 → 比较细(我们的板子)

这里有个特别容易搞混的地方,我要提醒你:

网上很多教程写"模拟读数范围是 0~1023"——那是 Arduino Uno,不是我们的板子。

你要是照着一份 Uno 的教程写 if (读数 > 500),在你的板子上可能完全不 work,因为你的范围是 0~4095,500 在那上面是非常暗的水平。

看教程先看它是哪块板子。 这个坑很常见。

三、电位器凭什么能调电压

现在回答另一个问题:转旋钮,电压为什么会变?

答案是分压

电位器靠两个电阻分压,转动旋钮改变上下两个电阻的比例,中间点的电压就跟着变

电位器内部其实是两个电阻串联,而那个旋钮控制的是两个电阻的比例

  • 你往一头拧 → 上面那个电阻变小,中间点的电压接近 3.3V
  • 你往另一头拧 → 下面那个电阻变小,中间点的电压接近 0V
  • 拧到中间 → 电压大概是一半

而板子读的,就是那个"中间点"的电压。

所以:

你拧到哪 中间点电压 读数
一头 3.3V ≈ 4095
中间 ≈ 1.65V ≈ 2048
另一头 ≈ 0V ≈ 0

这套"两个电阻分压"的结构,不只是电位器有——光敏、热敏内部也是同样的原理。

区别只是:电位器是你用手转,光敏是光线强弱自动改变其中一个电阻的阻值,热敏是温度改变

所以这节课学明白了,后面光敏、热敏、麦克风那几节课,你就只需要学"是什么在改变电阻",原理部分是共通的。

四、动手:读一个模拟值

代码跟读按钮几乎一样,就一个词的区别:

C++
int value = analogRead(0);    // 读 GPIO0 上的模拟值

注意是 analogRead(模拟读),不是 digitalRead(数字读)。

函数 读什么 返回什么
digitalRead 数字 HIGHLOW(只有两种)
analogRead 模拟 0 到 4095 之间的一个整数

完整代码:

C++
void setup() {
  Serial.begin(115200);
  // 模拟输入不需要 pinMode
}

void loop() {
  Serial.println(analogRead(0));
  delay(200);
}

有个细节要说明

你注意到没有——我没有写 pinMode

按钮那节课我写了 pinMode(4, INPUT_PULLUP),这里为什么不用?

因为模拟引脚不需要设置方向。它天生就是用来读的,不存在"输入还是输出"的选择,所以不用 pinMode

那要不要 INPUT_PULLUP 呢?也不要。

上拉电阻是为了让数字引脚有个确定的默认电平(还记得那个"悬空乱飘"的问题吗)。

而模拟引脚读的是电压值本身——如果给它加上拉,那就等于给读数加了个偏移量,反而读不准了。模拟输入要的就是那个原始电压。

烧进去,打开串口监视器,然后慢慢拧旋钮

你会看到数字平滑地变化,从 0 到 4095,中间有无数个值。

这就是"模拟"和"数字"的直观区别。 按钮只有两种可能,而它有你拧不完的中间值。

五、把数字变回电压

现在你已经会"读"了。再往前一步:怎么知道它对应的电压是多少?

其实很简单——反着算

数字 电压
0 0V
2048 3.3V ÷ 2 = 1.65V
4095 3.3V

所以换算公式是: 电压 = 读数 ÷ 4095 × 3.3

这里有个坑: 严格来说,4095 对应的是 3.3V,但实际板子上不一定正好是 3.3V

而且 ADC 本身有误差,参考电压也可能有偏差。所以别指望换算出小数点后两位——你的读数大概有个百分之几的误差是正常的。

想知道准不准?用万用表量一下那个引脚的实际电压,跟你算出来的比一比。 这就是第 5 课那个本事用在这儿。

验证一下:你把旋钮拧到中间,代码读出来 2048,然后拿万用表量 OUT 脚——应该是 1.65V 左右。

对上了,说明你理解了;对不上,那就有意思了——去查为什么。

六、这节课真正的意义

表面上看,你只是学会了读一个旋钮。

但实际发生的事比这大得多。

你回想一下:

  • 按钮只能告诉你"按了"或"没按"——两种可能
  • 电位器能告诉你 0 到 4095 之间的4096 种可能

这个跳跃,就是数字世界和模拟世界的分界线。

为什么这件事重要? 因为真实世界绝大多数东西都是连续的

现实中的量 是"是/否"还是"多少"
灯开着吗 是/否
房间有多亮 多少
有人经过吗 是/否
现在多少度 多少
门关好了吗 是/否
声音有多响 多少

"是/否"类的问题,用 digitalRead;"多少"类的问题,用 analogRead

你后面要学的光敏、热敏、麦克风,全是第二类。所以这节课的 analogRead 和那个 0~4095,你会反复用到。

还有一件事值得你自己想一想:既然 ADC 把连续的电压切成了 4096 格,那切掉的那些部分去哪了?

答案是——丢掉了。1.23456V 和 1.23457V 可能落在同一格里,读出来是同一个数。

这就是"精度"的含义:格子越密,丢失的信息越少。这就是为什么大家追求"16 位 ADC""24 位 ADC"——不是为了显示更多位数,是为了少丢一点信息。

自测

单选题ESP32-C3 的模拟输入,读出来的数值范围是多少?
单选题读模拟引脚的时候,为什么不用写 pinMode
单选题电位器转旋钮时,为什么会输出不同的电压?
问答题为什么 ADC 的"位数"越高越好?"12 位"具体是什么意思?
拓展ADC 把连续电压切成 4096 格,那被"切掉"的那部分去哪了?这会带来什么问题?

这个问题课上不讲,留给你自己找答案——**问 AI 是最好的办法**。

提示:搜"量化误差 是什么"、"ADC 分辨率 精度"。想一想:如果两个不同的电压落在同一格里,读出来会是什么结果?这在什么场景下会变成麻烦?

拓展万用表也能测电压,它和 ADC 有什么区别?为什么万用表能显示 1.653V 这么精确?

这个问题课上不讲,留给你自己找答案——**问 AI 是最好的办法**。

提示:搜"万用表 位数 ADC 位数 区别"、"万用表 双积分 ADC"。想一想:万用表一秒钟测几次?它用"慢"换来了什么?

本节你要动手做的事

  • [ ] 接好电位器VCC3.3VGNDGNDOUT一个模拟引脚GPIO0~GPIO5
  • [ ] 跑通读数:拧旋钮,看着数字在 0~4095 之间变化
  • [ ] 记两个极端:拧到两个尽头,记下最大和最小的读数分别是多少
  • [ ] 用万用表验证:拧到中间,看代码读数是多少;再用万用表量 OUT 脚的电压,看看跟你算出来的一样不一样
  • [ ] 做个"亮度调节":用这个读数去控制 LED 的亮灭——比如"读数过半就亮灯"(提示:这需要 if,第 9 课学的)

这节课的内容不多,但它的位置很关键。

后面你要学的光敏、热敏、麦克风,全是模拟输入——它们读回来的都是一段连续的值,都用 analogRead,都在 0~4095 之间。

而它们内部的原理,跟今天这个电位器一模一样:都是"某个东西改变了电阻,导致分压点电压变化"。

区别只是——电位器是手拧的,光敏是光控制的,热敏是温度控制的。

你今天把这一套走通了,后面那几节课,你就只需要关心一件事:是什么在改变那个电阻。

下一节我们学光敏——你用手一遮,数字就变。那是模拟输入里最直观的一个。