Arduino模拟信号控制实战:电位器PWM调控电机与LED
1. 项目概述与核心价值如果你刚接触Arduino或者嵌入式开发可能会觉得“模拟信号控制”这个概念听起来有点抽象。其实它离我们很近——你拧动音响的音量旋钮或者调节台灯的亮度背后都是这个原理在起作用。简单来说就是把一个连续的物理动作比如旋转变成一个连续变化的电信号再用这个信号去控制其他设备。这次我们要做的就是亲手搭建一个这样的系统用一个可调电阻电位器同时控制一个小风扇的转速和一个LED灯的亮度。这个项目麻雀虽小五脏俱全。它绝不仅仅是一个“让马达转起来、让灯亮起来”的简单实验。通过它你能一次性接触到嵌入式开发的几个核心环节电路设计如何安全地驱动功率更大的直流电机、信号采集如何读取电位器的模拟值、信号处理如何把采集到的值映射成控制指令以及执行器控制如何使用PWM技术精确控制电机和LED。对于初学者而言成功完成这个项目意味着你跨过了从点亮一个LED到实现“交互式控制”的关键门槛。你会发现那些智能家居里的自动调光、风扇无极调速其底层逻辑和你手头这个小小的实验是完全相通的。我之所以选择直流电机和LED作为控制对象是因为它们代表了两种典型的负载LED是简单的数字/模拟负载而直流电机则属于感性负载在控制时需要额外考虑反向电动势和电流冲击等问题这就需要用到晶体管作为电子开关来隔离和保护我们的核心控制板Arduino。这其中的选型、接线逻辑正是实际项目中硬件设计的缩影。2. 核心硬件选型与电路设计解析动手之前我们先得把桌上的“积木”认识清楚知道为什么选它以及怎么把它们拼在一起才不会“冒烟”。硬件选型不是随便抓一个就用每个元器件的参数背后都有其道理。2.1 核心控制器Arduino UNO我们选用Arduino UNO R3作为大脑。它足够经典资料丰富社区支持强大。其核心是一块ATmega328P微控制器。对于本项目我们主要用到它的两个功能模拟输入Analog Input板载一个10位精度的模数转换器ADC能将0-5V的模拟电压转换为0-1023的数字整数值。我们用它来读取电位器的电压。数字输出与PWMDigital Output PWM部分数字引脚如3, 5, 6, 9, 10, 11支持PWM输出。PWM脉冲宽度调制是一种用数字信号模拟模拟量的技术通过快速开关来控制一个周期内高电平所占的比例占空比从而等效输出不同的平均电压。我们用它来控制电机速度和LED亮度。注意务必确认你使用的是“Arduino UNO”或完全兼容的板子。一些其他开发板的引脚定义或PWM频率可能不同直接套用代码可能导致电机不转或控制异常。2.2 执行器与驱动方案直流电机这是一个小型的直流有刷电机。它的工作电压通常在3-6V工作电流可能在100-200mA左右。关键点来了Arduino的数字引脚直接输出电流能力非常有限约20-40mA远不足以驱动电机。直接连接会损坏Arduino引脚。因此我们必须使用一个“开关”来间接控制电机这个开关就是晶体管。NPN晶体管2N2222或BC547这里我们把它当作一个由电流控制的电子开关。其工作原理是基极Base接收来自Arduino PWM引脚如引脚3的小电流控制信号。集电极Collector连接电机和电源正极。当基极有电流时集电极和发射极之间“导通”相当于开关闭合电机通电。发射极Emitter连接电源地GND。当开关闭合电流从电源正极经电机、晶体管集电极流向发射极至地形成回路电机转动。为什么是2N2222或BC547它们都是非常通用的小信号NPN晶体管价格低廉易于获取。2N2222的电流驱动能力更强一些峰值可达800mA更适合驱动小型电机。BC547100mA左右用于本项目中的小电机也完全足够。选择它们是因为其开关特性好完全满足PWM频率通常490Hz或980Hz下的快速开关需求。LED及其限流电阻LED是电流驱动器件必须串联一个电阻来限制电流防止烧毁。电阻值通过欧姆定律计算R (Vcc - Vf) / I。其中Vcc是电源电压5VVf是LED正向压降通常红色约1.8-2.2V其他颜色可能不同I是期望的工作电流通常5-20mA。选择330Ω电阻是一个经验值假设Vf2V则电流I (5V-2V)/330Ω ≈ 9mA处于安全且足够明亮的范围。2.3 传感器电位器我们使用一个10kΩ的线性电位器。它本质上是一个可调电阻器有三个引脚两端分别接电源VCC和地GND中间是滑动抽头Wiper。旋转旋钮抽头与两端的电阻比例发生变化根据分压原理抽头输出的电压就在0V到VCC5V之间连续变化。这个连续的电压就是我们的“模拟信号”。Arduino的ADC会以每秒近万次的速度采样这个电压并将其量化为0-1023的数字。为什么是10kΩ这个阻值是一个很好的折中。阻值太小如100Ω从电源汲取的电流会很大I5V/100Ω50mA可能造成不必要的功耗和电源波动。阻值太大如1MΩ虽然电流极小但会更容易受到电路板上杂散电磁干扰的影响导致读取的模拟值不稳定、跳动。10kΩ在功耗和抗干扰性之间取得了平衡是Arduino模拟输入口的推荐负载。2.4 电路连接原理深度剖析根据提供的描述我重新梳理并绘制了更清晰的连接逻辑图。理解这个连接图比死记硬背“线插哪里”更重要。电源部分 Arduino 5V引脚 ---(红线)--- 面包板正极电源轨 Arduino GND引脚 ---(黑线)--- 面包板负极电源轨- 传感器部分电位器 电位器左侧引脚 ---(红线)--- 面包板正极电源轨 电位器右侧引脚 ---(黑线)--- 面包板负极电源轨- 电位器中间引脚 ---(黄线)--- Arduino 模拟引脚 A0 执行器驱动部分电机与晶体管 1. 电机一端 ---(红线)--- 面包板正极电源轨 2. 电机另一端 ---(黑线)--- 面包板某行例如行9列B 3. 晶体管集电极C ---- 与电机黑线端接在同一行行9列D 4. 晶体管发射极E ---- 面包板负极电源轨- 5. 晶体管基极B ---- 面包板某行例如行8列D 6. Arduino 数字PWM引脚3 ---(蓝线)--- 连接至晶体管基极所在行行8列A LED控制部分 1. LED阳极长脚 ---- 面包板某行例如行11列D 2. LED阴极短脚 ---- 面包板某行例如行10列D 3. 限流电阻330Ω一端 ---- 与LED阴极同一点行10列B 4. 限流电阻另一端 ---- 面包板负极电源轨- 5. Arduino 数字PWM引脚11 ---(蓝线)--- 连接至LED阳极所在行行11列A关键点解析电机的供电路径电流从面包板正极轨5V出发流经电机从电机另一端流出进入晶体管集电极C。当晶体管导通时电流再从发射极E流回负极轨GND形成完整回路。晶体管在这里充当了电机回路中的“低压侧开关”。基极电阻的缺失细心的你可能发现原始描述中Arduino引脚3直接连接到了晶体管基极。这在理论上是可行的因为Arduino引脚输出的电流足以驱动单个晶体管的基极。但在更严谨或驱动更大晶体管的电路中通常会在基极串联一个电阻如1kΩ用于限制基极电流保护Arduino引脚。本项目省略了它简化了电路但对于学习而言知道这个潜在优化点是好的。共地的重要性整个系统Arduino、电位器、电机、LED必须共享同一个“地”GND这是所有电压的参考基准点确保信号能被正确解读。3. 代码逐行解读与PWM控制原理把电路搭好只是完成了硬件舞台的搭建。让这个舞台活起来的是Arduino上运行的程序Sketch。下面我们深入剖析提供的代码理解每一行背后的意图。#define LED_PIN 11 #define MOTOR_PWM_PIN 3 #define POT_PIN A0第一部分宏定义。这不是可执行代码而是给编译器看的“别名”。我们将数字引脚11、3和模拟引脚A0分别定义为LED_PIN、MOTOR_PWM_PIN和POT_PIN。这样做有两大好处一是提高代码可读性一看就知道哪个引脚做什么用二是便于维护如果想更换控制引脚只需修改这里的一处定义而不必在代码中到处寻找替换。void setup() { pinMode(LED_PIN, OUTPUT); pinMode(MOTOR_PWM_PIN, OUTPUT); }第二部分初始化设置setup函数。这个函数只在设备上电或复位后运行一次。我们在这里配置引脚的工作模式pinMode(LED_PIN, OUTPUT);将LED引脚设置为输出模式因为我们要向它发送PWM信号来控制亮度。pinMode(MOTOR_PWM_PIN, OUTPUT);同样将电机控制引脚也设置为输出模式。注意对于模拟输入引脚POT_PINA0我们不需要在setup中特别设置。Arduino的模拟引脚默认就是输入状态用于读取外部电压。void loop() { int potValue analogRead(POT_PIN); // 读取电位器 (0-1023)第三部分主循环loop函数。这里的代码会一遍又一遍、永不停止地执行。int potValue analogRead(POT_PIN);这是模拟信号采集的核心。analogRead()函数读取指定模拟引脚A0上的电压并将其转换为一个0到1023之间的整数。当你旋转电位器这个值就会随之变化。int类型用于存储这个整数。int pwmValue map(potValue, 0, 1023, 0, 255); // 映射为PWM值int pwmValue map(potValue, 0, 1023, 0, 255);这是信号映射的关键一步。我们读取到的potValue范围是0-102310位ADC的结果但控制LED和电机PWM的analogWrite()函数其输入值范围是0-2558位分辨率。map()函数就像一个数学缩放器它把potValue从原来的“0到1023”区间线性地映射到“0到255”的新区间。例如当potValue为512中间值时经过map计算pwmValue就会是127也是中间值。analogWrite(LED_PIN, pwmValue); // 控制LED亮度 analogWrite(MOTOR_PWM_PIN, pwmValue); // 控制电机速度这两行是执行器控制。analogWrite()函数向指定的PWM引脚写入一个0-255的值。这个值决定了输出波形的占空比高电平时间占整个周期的比例。写入0占空比0%等效输出电压为0VLED熄灭电机停止。写入255占空比100%实际约97%等效输出电压接近5VLED最亮电机全速。写入127占空比约50%等效输出电压约2.5VLED半亮电机半速。PWM控制电机的原理电机是一个大电感它对于电压变化的响应是“平均化”的。虽然我们给电机的是频率固定如引脚3和11的PWM频率约为490Hz、电压在0V和5V之间高速切换的方波但由于电机线圈的惯性它感受到的是一个平均电压。占空比50%的PWM波其平均电压就是2.5V因此电机以大约一半的转速运行。delay(10); // 短暂延时以保持稳定 }delay(10);这是一个10毫秒的短暂延时。它的主要作用有两个一是降低loop循环的执行速度避免Arduino以极限速度每秒数十万次疯狂读取电位器值这既没必要也浪费资源二是给硬件一点反应时间让ADC转换和PWM输出更加稳定。在一些对响应速度要求极高的场合这个延时可以缩短甚至移除但对于本项目10ms是一个合理的值既能保证平滑控制又不会让人感到操作延迟。4. 分步组装与焊接级实操要点理论清楚了现在让我们拿起面包板和跳线开始真正的“搭积木”。我建议你严格按照以下顺序操作并在每一步完成后都检查一遍这能极大降低后续排查故障的难度。4.1 准备工作与布局规划在把任何元件插到面包板上之前先花一分钟规划一下布局。一个好的布局能让电路清晰、整洁避免跳线交叉混乱。我的习惯是将电源轨放在面包板两侧左侧为负极-右侧为正极。用红、黑跳线从Arduino接出5V和GND。将电位器、晶体管、LED、电机等主要元件放在面包板中央区域给连接留出空间。尽量让信号流向从左到右或从上到下符合阅读习惯。实操心得对于晶体管、LED这类有极性的元件务必在插入前再次确认方向。NPN晶体管如2N2222的平面一侧通常朝向自己引脚从左到右为Emitter发射极 Base基极 Collector集电极。LED长脚是阳极正极短脚是阴极负极。插反了不会立即损坏但电路肯定无法工作。4.2 逐步搭建电路第一步建立电源系统用一根红色跳线连接Arduino的5V引脚到面包板右侧正极电源轨的任意一个孔。用一根黑色跳线连接Arduino的GND引脚到面包板左侧负极电源轨的任意一个孔。可选但推荐用另一根短的红/黑跳线将面包板上下两半的电源轨分别连接起来这样整个面包板的电源就贯通了。注意确保所有需要电源和地的元件最终都连接到这两条电源轨上而不是直接接到Arduino这样可以减少Arduino板上的电流负载使接线更规整。第二步连接电位器传感器将10kΩ电位器跨接在面包板中间凹槽的两侧。假设三个引脚从上到下分别为A左、B中、C右。用跳线连接引脚A左侧到面包板正极电源轨。用跳线连接引脚C右侧到面包板负极电源轨-。用跳线连接引脚B中间抽头到Arduino的模拟输入引脚A0。第三步连接NPN晶体管与直流电机驱动核心放置晶体管将2N2222晶体管跨接在面包板中间凹槽上。确保其平面朝向你可以看清的一侧。假设从左到右三个引脚分别插在面包板的行8、行9、行10的列D位置具体行号可根据你的布局调整。连接电机将直流电机的红线正极连接到面包板的正极电源轨。将直流电机的黑线负极连接到面包板上晶体管集电极C所在的同一行例如行9列B。连接晶体管用一根跳线从晶体管发射极E所在的孔例如行10列D连接到面包板的负极电源轨-。用一根跳线从Arduino的数字PWM引脚3连接到晶体管基极B所在的同一行例如行8列A。第四步连接LED与限流电阻放置LED将LED跨接在面包板中间凹槽上。假设长脚阳极在行11列D短脚阴极在行10列D。连接限流电阻将一个330Ω电阻的一端与LED的阴极短脚连接在同一行行10列B。电阻的另一端连接到面包板的负极电源轨-。连接控制线用一根跳线从Arduino的数字PWM引脚11连接到LED阳极长脚所在的同一行行11列A。4.3 上电前最终检查与首次上电在连接USB线之前请像飞机起飞前的检查员一样对照以下清单逐一核对[ ]电源极性所有VCC/5V是否都接到了正极轨所有GND是否都接到了负极轨绝对禁止将电源正负极接反尤其是对晶体管和LED。[ ]元件方向晶体管引脚E, B, C是否正确LED长脚阳极是否接向了控制信号引脚11[ ]连接牢固所有跳线和元件引脚是否都插紧在面包板孔内面包板使用久了内部弹片可能会松动导致接触不良。[ ]短路风险检查是否有裸露的导线或元件引脚意外触碰导致不同网络如5V和GND短接。确认无误后将Arduino通过USB线连接到电脑。此时Arduino板上的电源指示灯通常标有ON或PWR应该亮起。先不要上传代码用手轻轻触摸晶体管和电机。如果任何元件在未上传代码时就异常发热请立即拔掉USB线这很可能存在短路或接线错误。5. 软件环境配置、代码上传与基础调试硬件检查完毕现在轮到软件上场。即使你从未用过Arduino IDE跟着步骤走也能轻松完成。5.1 搭建开发环境下载IDE访问Arduino官网下载对应你操作系统Windows, macOS, Linux的Arduino IDE集成开发环境。建议下载较新的稳定版本。安装驱动主要针对Windows首次将Arduino UNO插入电脑时系统可能需要安装驱动。通常Windows会自动完成如果未识别可在设备管理器中手动指定驱动或使用第三方驱动安装工具。选择板卡与端口打开Arduino IDE在工具-开发板中选择Arduino Uno。然后在工具-端口中选择对应的串口在Windows上通常是COMx在macOS/Linux上是/dev/cu.usbmodemxxx。如果端口列表中有多个拔掉Arduino再查看消失的那个就是正确的端口。5.2 编写与上传代码在IDE中新建一个空白项目Sketch。将前面章节提供的完整代码复制粘贴到编辑窗口中。点击左上角的“验证”对勾图标编译代码。如果下方控制台没有报错显示“编译完成”说明代码语法正确。点击“上传”右箭头图标将代码烧录到Arduino板中。上传时Arduino板上的TX/RX指示灯会快速闪烁。上传成功后控制台会显示“上传成功”。5.3 基础功能测试与现象观察上传成功后你的电路应该已经“活”了。尝试以下操作旋转电位器缓慢旋转电位器的旋钮。你应该观察到LED的亮度平滑地变化同时直流电机风扇的转速也随之改变。顺时针旋转到底LED最亮风扇全速逆时针旋转到底LED熄灭风扇停止。听与看仔细听电机的声音。在低速时由于PWM频率约490Hz在人耳可听范围内你可能会听到轻微的“滋滋”声或啸叫声这是正常的。观察风扇叶片转速变化应该是平滑的不应有卡顿或突然跳动。串口监视器调试进阶如果你想“看见”Arduino读取到的具体数值可以在loop函数里添加两行代码void loop() { int potValue analogRead(POT_PIN); int pwmValue map(potValue, 0, 1023, 0, 255); // 添加以下两行用于调试 Serial.print(Pot: ); Serial.print(potValue); Serial.print( - PWM: ); Serial.println(pwmValue); analogWrite(LED_PIN, pwmValue); analogWrite(MOTOR_PWM_PIN, pwmValue); delay(10); }同时需要在setup函数里添加Serial.begin(9600);来初始化串口通信。上传后打开IDE的工具-串口监视器设置波特率为9600。当你旋转电位器时就能实时看到potValue和pwmValue的数值变化这对于理解map函数的映射关系非常有帮助。6. 故障排查大全从现象到根因即使按照指南操作第一次成功也常常伴随着一些小波折。别担心几乎所有问题都有迹可循。下面是我在多年教学和项目中总结的常见故障清单你可以像查字典一样对照解决。6.1 整体完全无反应LED不亮电机不转检查1电源与连接现象Arduino板载电源指示灯不亮。排查检查USB线是否插紧电脑USB口是否供电正常。尝试更换USB线或USB口。用万用表测量面包板电源轨电压是否为5V左右。检查2代码上传与执行现象Arduino电源灯亮但无任何反应。排查确认代码已成功上传上传时无错误提示。尝试上传一个最简单的Blink示例程序控制板载LED闪烁以确认Arduino主板本身和开发环境是正常的。检查3核心接线错误现象电源正常代码已上传。排查这是最可能的原因。重点检查共地确保Arduino的GND、电位器的GND引脚、晶体管发射极E、LED/电阻的接地端全部通过面包板负极轨连接在一起。地线不通整个电路就无法形成回路。电位器接线确认电位器三个引脚是否接错。中间抽头是否接到了A0两端是否分别接5V和GND可以用万用表电阻档测量旋转旋钮时中间脚与任一端脚的电阻应连续变化。6.2 LED工作异常现象1LED完全不亮但电机可能转排查LED极性接反这是最常见的原因。将LED拔下调转180度重新插入。限流电阻未接或开路检查330Ω电阻是否两端连接牢固电阻本身是否损坏色环橙-橙-棕。控制引脚错误检查连接LED阳极的跳线是否确实接到了Arduino的引脚11代码中定义的LED_PIN。代码引脚定义错误检查代码开头#define LED_PIN 11中的数字是否与实际物理连接一致。现象2LED常亮不受电位器控制排查LED阴极未接地检查LED短脚阴极是否通过电阻可靠地接到了GND。如果悬空或接触不良LED可能会微亮或常亮。电位器读取失败可能是电位器损坏或接线错误导致analogRead(POT_PIN)始终返回一个固定值如1023或0。使用串口监视器打印potValue值来确认。现象3LED亮度变化不线性或低亮度时闪烁排查PWM频率感知在极低占空比下PWM值很小LED的闪烁可能会被人眼察觉这是正常的物理现象。电位器接触不良劣质或磨损的电位器在旋转时中间抽头与电阻膜接触可能不稳定导致读取值跳动。尝试更换一个电位器或在代码中对potValue进行简单的软件滤波例如取多次读取的平均值。6.3 直流电机工作异常现象1电机完全不转但LED正常排查晶体管方向错误确认2N2222的引脚E, B, C顺序是否正确。最常见的错误是将集电极C和发射极E接反。接反后晶体管无法正常导通。电机供电路径不通检查电机红线是否接5V黑线是否接晶体管集电极C。检查晶体管发射极E是否接地。用万用表通断档沿着这条路径逐一测量。晶体管损坏在早期接线错误如电源反接时晶体管可能已被击穿。可以尝试更换一个同型号晶体管。PWM引脚错误检查连接到晶体管基极B的跳线是否来自Arduino引脚3。现象2电机一直全速转动不受控制排查晶体管基极B悬空或一直为高电平检查连接基极的导线是否脱落。如果代码错误地将控制引脚模式设为INPUT或INPUT_PULLUP也可能导致引脚处于不确定状态。确保代码中pinMode(MOTOR_PWM_PIN, OUTPUT);已执行。电位器故障同LED部分检查电位器是否损坏导致输出始终为高电压。现象3电机发出“吱吱”声转动无力或抖动排查电源功率不足USB口提供的电流可能有限通常500mA。当电机启动或负载稍大时可能导致电压被拉低整个系统不稳定。尝试使用外部电源如9V电池通过Arduino的DC接口供电或使用独立的5V/1A以上电源适配器为面包板供电。PWM频率不适Arduino UNO的引脚3和11的PWM频率约为490Hz。对于某些电机这个频率可能偏低会产生可闻噪音。可以尝试更换到引脚5或6PWM频率约为980Hz看是否有改善。但这需要修改代码中的引脚定义。需要续流二极管直流电机是感性负载在晶体管突然关闭时电机线圈会产生一个很高的反向电动势电压尖峰可能损坏晶体管。虽然在小电流、低电压的本项目中问题不突出但为了可靠性和学习完整性最佳实践是在电机两端并联一个续流二极管阴极接电机正极阳极接电机负极。这能有效吸收反向电动势保护晶体管。6.4 电位器控制不灵敏或跳动现象旋转电位器时LED或电机响应不平滑有时跳变有时在某段无反应。排查与优化硬件滤波在电位器中间抽头接A0的引脚与地GND之间并联一个0.1uF104的陶瓷电容。这可以滤除因手部触摸或导线引入的高频噪声。软件滤波在代码中实现。最简单的是“移动平均滤波”。例如#define SAMPLE_SIZE 10 // 采样次数 int potReadings[SAMPLE_SIZE]; int readIndex 0; long total 0; int average 0; void loop() { total total - potReadings[readIndex]; // 减去最旧的读数 potReadings[readIndex] analogRead(POT_PIN); // 读取新值 total total potReadings[readIndex]; // 加上最新读数 readIndex (readIndex 1) % SAMPLE_SIZE; // 循环索引 average total / SAMPLE_SIZE; // 计算平均值 int pwmValue map(average, 0, 1023, 0, 255); // ... 后续控制代码 }这段代码会计算最近10次读数的平均值能显著平滑控制曲线消除毛刺。7. 项目优化与扩展思路当你的基础项目稳定运行后就可以思考如何让它变得更“聪明”、更实用。这里有几个方向供你探索这也是从“完成实验”到“解决实际问题”的思维跨越。7.1 硬件层面的优化与增强增加电机保护如前所述在直流电机两端并联一个续流二极管如1N4007。这是工业控制中的标准做法能大幅提高电路的可靠性防止开关瞬间的电压尖峰损坏晶体管或干扰微控制器。使用电机驱动模块如果想驱动更大功率的电机比如玩具车电机或需要控制电机正反转一个集成的电机驱动模块如L298N、TB6612FNG是更好的选择。它们内部集成了H桥电路和必要的保护二极管只需几根控制线就能实现更强大的功能且让主电路更简洁。改善用户体验为电位器加装一个漂亮的旋钮。将整个电路安装到一个小型塑料盒或3D打印的外壳中做成一个桌面迷你调温风扇或创意台灯。7.2 软件层面的进阶控制非线性映射map函数是线性映射。但人眼对光强的感知、电机转速与风量的关系可能并非线性。你可以尝试使用非线性函数来映射例如使用pwmValue map(potValue, 0, 1023, 0, 255);之后再对pwmValue进行平方运算pwmValue pwmValue * pwmValue / 255;这样在电位器低角度时变化平缓高角度时变化剧烈可能更符合人的感觉。加入按钮切换模式增加一个 tactile 按钮。通过编程实现按一下按钮在“电机与LED同步控制”和“仅控制LED或仅控制电机”两种模式间切换。这需要学习Arduino的中断或按钮消抖检测。实现自动控制用其他传感器替代电位器。例如用一个热敏电阻或DHT11温湿度传感器检测环境温度当温度超过设定阈值时自动启动风扇并随温度升高而加速。这就变成了一个简易的智能温控风扇原型。加入状态指示除了被控制的LED可以增加另一个不同颜色的LED作为状态指示灯。例如风扇全速时亮红灯中速时亮黄灯低速时亮绿灯让状态一目了然。7.3 从原型到产品的思考这个项目虽然简单但其“传感器-控制器-执行器”的架构是绝大多数自动化、物联网设备的缩影。电位器是传感器Arduino是控制器或叫微控制器单元MCU电机和LED是执行器。传感器可以换成光敏电阻自动夜灯、声音传感器声控开关、超声波测距防撞小车、陀螺仪平衡装置等等。控制器可以升级为更强大的ESP32带Wi-Fi/蓝牙从而将数据上传到云端或通过手机APP进行远程控制。执行器可以换成继电器控制家电、舵机控制角度、步进电机精密定位、电磁阀控制水流/气流等等。我个人在带学生做项目时常把这个实验作为“第一课”。它的价值不在于做出了多酷的东西而在于完整地走通了一个闭环物理世界的变化旋转- 模拟信号电压- 数字信号0-1023- 程序处理map映射- 控制信号PWM- 物理世界的变化转速/亮度。理解了这个闭环你就掌握了嵌入式硬件交互最核心的脉络。下次当你再看到任何智能设备试着去拆解它你会发现很多看似复杂的功能底层都是这样一个或多个类似的闭环在协同工作。