2026/8/27 7:09:03

用433MHz射频模块自制遥控小车:从原理到实战完整教程

用433MHz射频模块自制遥控小车:从原理到实战完整教程 自己动手做一辆能用射频遥控的机器人小车这个项目我在不同场合反复带人做过很多次从给电子爱好者入门到给工程类学生做课程设计都特别合适。这里的“RF”指的是Radio Frequency也就是无线电频率遥控通常用433MHz或315MHz这类工业科学医疗频段不是蓝牙、不是Wi-Fi、也不是红外。整套东西做下来你学到的东西非常实在无线收发模块怎么用、电机驱动怎么搭、电池系统怎么分配电流、通信协议怎么设计还有一堆只有实际调试时才会遇到的坑。这篇文章我把整个项目从头拆到尾包括方案选型、原理讲解、完整烧录代码、常见故障排查甚至后续想加双向通信和RF SoC进阶方向的思路也带上。适合刚接触单片机和机器人制作的新手也适合拿来当教学案例的老手。只要你手里有Arduino或者类似开发板、一对433MHz模块、一块电机驱动板就能照着做出来。1. 项目设计思路与方案选型1.1 为什么遥控方案选RF而不是红外、蓝牙或Wi-Fi很多第一次接触遥控小车的人第一反应是用手机蓝牙或者干脆用Wi-Fi做视频小车。但回到“遥控”这个需求本身射频模块是很多场景下性价比最高的选择。我列一个对比表这样看得更清楚方案通信距离抗遮挡能力配对方式功耗成本典型场景红外IR5米内差必须对准无天然点对点低极低旧式电视遥控器蓝牙BLE10-50米中等需要配对绑定中中遥控小车/键鼠Wi-Fi30-100米中等需要连接AP很高高视频图传小车433MHz RF50-200米空旷较好能穿墙无需配对地址码识别很低极低车库门遥控器/遥控插座射频方案最大的优势是低调、务实、不用管什么“连接”状态。发射模块发数据接收模块收数据一开一合就是一条单向链路没有配对过程、没有断开重连问题。在家里做一个小车不需要复杂的组网去空旷场地测试几十米甚至上百米的距离也够用。再加上433MHz模块一对才几块钱坏了不心疼。当然它也有局限最明显的是半双工/单向通信意味着你很难让小车把状态回传给你。但咱们做的是遥控车不是远程数据采集平台单向开环就足够了。前面提到的RF SoC、双向高频方案是后话第5章会讲。1.2 底盘、电机和驱动板怎么搭配底盘选择会直接影响整车的负载能力和走线难度。市面上常见的亚克力三轮底盘、四轮底盘、铝合金底盘价格从十几块到几十块不等。新手我建议用两驱万向轮结构也就是两个直流减速电机各带一个驱动轮前/后加一个万向轮。结构简单转向靠两个轮子的转速差就能实现代码也容易写。电机选TT马达也叫黄铜减速电机这几乎是入门小车标配。它自带减速齿轮扭矩足够推动一块电池板和几块电路板工作电压在3-6V之间直接可以吃电池电压。如果要更精确的速度控制可以选带霍尔编码器的版本但那属于进阶玩法这个项目用普通TT马达就够了。电机驱动板有两个经典选择L298N和TB6612FNG。对比一下驱动模块最大电流导通压降PWM频率支持发热新手友好度L298N每路2A约1.5-2V一般高频PWM损耗大明显极高插线直白TB6612FNG每路1.2A约0.3V好适合高频PWM低高体型小L298N虽然老、压降大、发热明显但它自带5V输出引脚丝印清楚适合入门理解电机驱动原理。TB6612效率高但引脚细新手容易焊歪。如果是自己焊板子我更推荐L298N尤其是套件开发板的版本接线几乎不会出错。压降大的问题只要电池电量足够影响不大。电池方案上我建议用两节18650锂电池串联组一个7.4V左右的2S电源。L298N的电源脚接7.4V然后从它的5V输出脚给Arduino和接收模块供电。如果电池不是满电电压大概在7.0-8.4V之间经过L298N内部稳压后也能稳定在5V左右属于够用且不容易烧板子的范围。千万不要用普通干电池组电流能力不行一启动电机电压就拉垮。1.3 通信协议设计为什么不能直接把按键电平发过去很多刚入门的朋友会想我按下前进键发射端就给接收端发一个高电平接收端收到高电平就让电机转这不就完了吗理论上是通的但实际上你会遇到几个问题第一个问题是误触发。433MHz是开放频段周围的遥控插座、无线门铃、汽车钥匙都可能偶尔发一串信号你的接收模块不知道那是什么如果直接当控制信号处理小车就会自己跑。第二个问题是无法区分数据来源。同一个频段上有两个遥控器都能控制你的小车那就乱套了。第三个问题是数据完整性。无线链路会受到干扰一个高电平可能被拉成低电平或者一串信号中间漏了一位小车就会执行错误动作。所以必须设计一个“数据帧”把真正要传输的信息包在一个固定的格式里。我用的帧格式是[8位设备地址] [8位指令码] [8位校验码]整体拼成一个24位的数据块来发送。设备地址可以用来区分不同的遥控器比如我设置地址为0x5A接收端只响应地址匹配的帧。指令码对应前进、后退、左转、右转、停止这些操作。最后的校验码用来检查数据在传输过程中有没有被干扰具体做法是校验码 设备地址 XOR 指令码 XOR 0xAA。接收端重新算一次如果和收到的校验码不一致就丢弃这帧数据。这样设计之后即使偶尔收到一串干扰信号由于地址和校验码大概率对不上小车也不会乱动。2. 核心模块原理与关键细节2.1 433MHz RF收发模块是怎么工作的市面上一对最常见的433MHz模块是那种蓝色或者黑色的超再生接收模块配一个硬币大小的发射模块型号经常是FS1000A/XD-RF-5V。它们的原理其实不复杂发射模块就是一个工作在433.92MHz的振荡器可以通过数据引脚控制载波的通断这种方式叫ASK幅度键控或者OOK开关键控。简单理解就是用手电筒打信号载波亮代表1载波灭代表0。接收模块负责检测这个载波的有无把它还原成高电平或低电平输出给单片机。需要注意的是433MHz接收模块尤其是超再生型的输出引脚在没有信号时也不是干净的低电平而是会输出一堆随机噪声脉冲。这意味着你不能把接收端的数据引脚直接接一个普通按键来读必须通过协议层的校验去过滤这些噪声。这就是前面说的数据帧设计和校验存在的第二个原因。还有一个参数要记住这类ASK模块的实用数据速率大约在1-10kbps之间最稳的是2-5kbps。速率太高的话接收端还原波形时容易出现位失真。所以哪怕我们的单片机可以跑很快也要在发送端主动降低码率比如用rc-switch库时把脉冲宽度调大一点让每个比特“慢下来”。接收模块还分超再生和超外差两种。超再生便宜灵敏度在低速率时做得还不错但抗干扰能力弱遇到强信号容易阻塞而且它会向外辐射微弱的杂波。超外差接收模块稳定性和抗干扰能力都要好不少但价格大概是超再生的几倍。如果想让小车跑得远、跑得稳接收端可以换超外差模块发射端其实还是那个FS1000A因为它发射载波的特点是不变的。2.2 电源纹波对接收模块的影响不可忽视这是我带这个项目时反复强调的一个点绝大多数“距离变近”“偶尔失控”的问题根因不在天线而在电源。电机的换向电流冲击很大尤其是PWM调速时电流是断续的会在电源线上形成很明显的纹波。如果驱动板和接收模块共用一组电源线纹波会顺着导线窜到接收模块的供电脚上导致接收模块内部电路工作点漂移灵敏度大幅下降。症状非常典型小车静止时无线控制距离很远电机一转起来距离立刻缩到几米甚至原地失控。对策有三个层面。第一结构上分层供电电机电源从电池直接到L298NArduino和接收模块从L298N的5V引脚取电逻辑电路和动力电路只在电池端和共地处有交汇不要在控制板附近串在一起。第二在接收模块的电源脚旁边加去耦电容常见的组合是100nF陶瓷电容并联一个10uF电解电容陶瓷电容滤高频毛刺电解电容扛低频波动。第三电机两端各焊一个104陶瓷电容作用是吸收电机换向时产生的火花噪声防止它通过空间辐射干扰接收模块。实操中我会建议先做第二、三层因为很多套件的接线方式已经把共地做死了改布局不如加电容直接。我之前做测试时给电机加了一个104电容之后失控明显减少效果肉眼可见。2.3 天线长度和摆放位置决定实际距离433MHz的波长大约是69.1厘米光速除以频率1/4波长就是17.3厘米。标准做法是给发射和接收模块各接一根17.3厘米左右的直导线作为天线这是最有效、阻抗匹配最简单的天线形式。市面上很多模块自带的是一根很短的弹簧天线出厂主要是为了体积小并不是性能最优。如果你想让小车跑得远一点可以把接收模块的弹簧天线拆掉焊一根17.3厘米的漆包线或者杜邦线上去直直地立起来。注意天线离地、离金属物体、离电机和电池越远越好。小车车体有大量金属螺丝、电池盒天线如果贴着电池等效长度被破坏距离可能直接腰斩。天线摆放也是门学问。最好把接收模块的天线从底盘向上拉起来尽量竖直。同一个道理发射端遥控器里面的天线也要尽量竖直不要握在手里完全贴住手人体对无线电波有吸收作用。我在室外测试时把遥控器天线从平躺改成竖直距离从60米拉到了150米左右非常明显。还有一个细节不要在信号路径上放金属物体。小车底盘如果是金属的要注意把模块架空不要让pcb地直接贴到金属底座形成大的屏蔽面。3. 完整实操从接线到烧录代码3.1 硬件清单与接线示例下面是这个项目我用到的完整材料清单大部分淘宝/数码商店都有整体成本可以控制在100元以内不含Arduino的话几十块。组件型号/规格数量说明主控MCUArduino Nano/Uno1接收端和发射端各需要一片也可以共用一片测试433MHz发射模块FS1000A / XD-FST1数据引脚接MCU的TX或任意GPIO433MHz接收模块XD-RF-5V / 超外差接收1DATA引脚接MCU中断引脚电机驱动板L298N1至少带动两个DC电机直流减速电机TT马达黄铜减速2带轮子更好底盘亚克力/3D打印两驱万向轮1尽量选轻的电池18650两节串联 / 7.4V锂电池1组给电机和逻辑电路供电电池盒/接头两节18650电池盒DC插头1注意正负极电弧消除电容100nF陶瓷电容2-4焊在电机电极两端去耦电容100nF 10uF若干接收模块电源脚附近按键自锁或不自锁5个左右遥控按键前/后/左/右/停导线杜邦线、漆包线若干天线也用它天线17.3cm直导线2根收发各一根接线部分我分发射端和接收端两路说明。发射端比较简单Arduino Nano GND接地VCC接5V。FS1000A的DATA脚接Nano的D11我习惯用D11后面代码里一致。5个按键分别接D2、D3、D4、D5、D6每个按键另一端接地内部上拉模式读取。接收端接线稍微多一点Arduino Nano VCC接L298N的5V输出GND和L298N的GND共地。接收模块VCC接Nano 5VGND接GNDDATA接Nano的D2Uno的D2是中断0rc-switch库默认用到。L298N的IN1-IN4分别接Nano的D4-D7。L298N的ENA和ENB接Nano的D9和D10用PWM调速。电机A的两根线接L298N的OUT1/OUT2电机B接OUT3/OUT4。电池正负极接L298N的12V输入和GND注意L298N的12V输入只是用于逻辑参考不是非要12V7.4V也行。上电之前用万用表测一遍重点确认电池正负没有反L298N输出端和接收模块之间没有直接导通。3.2 发射端代码按键编码并发送我用rc-switch库来发送这个库在Arduino IDE库管理器里直接搜索“rc-switch”就能装。它支持很多常见的433MHz遥控协议也可以自定义脉冲宽度。#include RCSwitch.h RCSwitch mySwitch RCSwitch(); // 按键引脚 const int BTN_FORWARD 2; const int BTN_BACK 3; const int BTN_LEFT 4; const int BTN_RIGHT 5; const int BTN_STOP 6; // 自定义设备地址可以改成其他值避免和别人冲突 const unsigned long ADDR 0x5A; // 指令码定义 const unsigned long CMD_STOP 0x00; const unsigned long CMD_FORWARD 0x01; const unsigned long CMD_BACK 0x02; const unsigned long CMD_LEFT 0x03; const unsigned long CMD_RIGHT 0x04; unsigned long buildFrame(unsigned long cmd) { unsigned long checksum (ADDR ^ cmd ^ 0xAA) 0xFF; unsigned long frame (ADDR 16) | (cmd 8) | checksum; return frame; } void setup() { pinMode(BTN_FORWARD, INPUT_PULLUP); pinMode(BTN_BACK, INPUT_PULLUP); pinMode(BTN_LEFT, INPUT_PULLUP); pinMode(BTN_RIGHT, INPUT_PULLUP); pinMode(BTN_STOP, INPUT_PULLUP); // 发射引脚D11 mySwitch.enableTransmit(11); // 脉冲宽度350us大约对应4.8kbps对433模块比较稳 mySwitch.setPulseLength(350); mySwitch.setProtocol(1); } void sendCommand(unsigned long cmd) { mySwitch.send(buildFrame(cmd), 24); } void loop() { if (digitalRead(BTN_FORWARD) LOW) { sendCommand(CMD_FORWARD); } else if (digitalRead(BTN_BACK) LOW) { sendCommand(CMD_BACK); } else if (digitalRead(BTN_LEFT) LOW) { sendCommand(CMD_LEFT); } else if (digitalRead(BTN_RIGHT) LOW) { sendCommand(CMD_RIGHT); } else if (digitalRead(BTN_STOP) LOW) { sendCommand(CMD_STOP); } delay(50); }这段代码做了一件事把“方向”映射成固定指令码组合成24位帧后无线发出。这里把地址左移16位、命令左移8位、校验码放最低8位。接收端解析时按同样的位宽拆开比对即可。值得说一下为什么用setPulseLength(350)。rc-switch库里的protocol 1默认脉冲长度是350us比较适中。如果你的模块距离不理想可以把脉冲长度增加到450-500us也就是降低数据速率让接收端更容易判别0和1。速度慢一点距离和稳定性都能上来。按键部分我用了INPUT_PULLUP按键另一端接GND按下读取到LOW。这样省掉外部上拉电阻接线更少。3.3 接收端代码解码、校验和超时停车接收端比发射端多两个关键逻辑校验和超时保护。校验保证收到的指令不是噪声超时保护保证小车在遥控器丢信号时自动停下。#include RCSwitch.h RCSwitch mySwitch RCSwitch(); // 电机驱动引脚 const int IN1 4; const int IN2 5; const int IN3 6; const int IN4 7; const int ENA 9; const int ENB 10; const unsigned long ADDR 0x5A; const unsigned long CMD_STOP 0x00; const unsigned long CMD_FORWARD 0x01; const unsigned long CMD_BACK 0x02; const unsigned long CMD_LEFT 0x03; const unsigned long CMD_RIGHT 0x04; const unsigned long TIMEOUT_MS 300; unsigned long lastCmdTime 0; void setup() { pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT); pinMode(ENA, OUTPUT); pinMode(ENB, OUTPUT); // 初始状态电机不转 stopMotors(); // 接收模块DATA接D2对应Uno中断0 mySwitch.enableReceive(0); lastCmdTime millis(); } void stopMotors() { digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); } void setMotors(int leftSpeed, int rightSpeed) { // 正值正转负值反转0停止 if (leftSpeed 0) { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); analogWrite(ENA, leftSpeed); } else if (leftSpeed 0) { digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); analogWrite(ENA, -leftSpeed); } else { digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); analogWrite(ENA, 0); } if (rightSpeed 0) { digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); analogWrite(ENB, rightSpeed); } else if (rightSpeed 0) { digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH); analogWrite(ENB, -rightSpeed); } else { digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); analogWrite(ENB, 0); } } void executeCommand(unsigned long cmd) { switch (cmd) { case CMD_FORWARD: setMotors(200, 200); // 全速范围0-255 break; case CMD_BACK: setMotors(-200, -200); break; case CMD_LEFT: setMotors(-120, 200); // 左轮反转右轮正转原地左转 break; case CMD_RIGHT: setMotors(200, -120); // 右轮反转左轮正转原地右转 break; case CMD_STOP: default: stopMotors(); break; } } bool checkFrame(unsigned long frame) { unsigned long recvAddr (frame 16) 0xFF; unsigned long recvCmd (frame 8) 0xFF; unsigned long recvSum frame 0xFF; if (recvAddr ! ADDR) return false; unsigned long calcSum (recvAddr ^ recvCmd ^ 0xAA) 0xFF; if (calcSum ! recvSum) return false; return true; } void loop() { if (mySwitch.available()) { unsigned long frame mySwitch.getReceivedValue(); unsigned int bitLength mySwitch.getReceivedBitlength(); if (bitLength 24 checkFrame(frame)) { unsigned long cmd (frame 8) 0xFF; executeCommand(cmd); lastCmdTime millis(); } mySwitch.resetAvailable(); } // 超时保护收不到新指令就停车 if (millis() - lastCmdTime TIMEOUT_MS) { stopMotors(); } }这段代码中setMotors函数用了analogWrite输出PWM所以速度可调。前进时200/255大约是80%占空比留给电机一点余量。左转/右转我用了一个正一个负相当于原地转圈这样转弯半径为零比较适合狭小空间。如果你更希望平滑转弯可以改成左轮停止、右轮正转左转那就是绕轮子中心转的“扫弯”各有取舍。超时保护这里我设了300ms也就是一旦超过300ms没有收到合法指令电机就会被强制关闭。这个设计不是说遥控器必须每300ms发一次而是说当你松开按键后发射端就不发指令了接收端经过300ms就会把车停下来。因此遥控器不需要额外发送停止指令更安全。3.4 组装和调试的先后顺序拿到材料之后别急着全焊死。我的习惯是分成“上下位机”两部分独立调试第一步先把发射端和接收端分别烧录好程序使用USB-TTL串口把接收端的Serial输出打出来或者用一块OLED/1602屏幕显示收到的帧内容。没有屏幕也没关系先用万用表测量接收端引脚电平变化能明显看到指示灯的闪烁。第二步把接收端Arduino和电脑连在一起先不接电机用手按遥控器按键看串口是否正确输出对应的帧值。这个阶段主要验证无线链路是否通。如果串口完全没反应先查接收模块DATA有没有接对再查发射端有没有通电最后换一对模块。第三步确认无线链路正常后再接上L298N和电机。先在桌面上把小车架空轮胎离地用手按前进键观察两个轮子的转向是否一致。如果不一致把其中一个电机的两根线对调一下。第四步全部正常后装到地盘上用扎带固定电池、驱动板和接收模块最后再把天线固定好。记住一个原则先逻辑后动力先链路后整车。4. 调试心得与常见问题速查4.1 典型故障现象和排查方法当年我自己第一次做这个小车时遇到过信号一会儿有一会儿没的情况。后来总结出一张速查表现在每次调试都是按这张表来定位故障现象可能原因排查/解决办法接收端串口完全没有数据发射端没有供电/接线错用万用表量发射端VCC和GND确认DATA引脚接对换一对模块排除个体问题按键按下时串口有数据但小车不动电机驱动板电源问题或GPIO映射错先检查L298N有没有输入电压再检查IN1-IN4和代码里引脚是否一致最后用串口打印接收到的cmd值距离非常短空旷场地不到10米天线缺失/天线贴地/电源纹波严重换17.3cm直导线并竖直摆放接收模块远离驱动板电机两端加104电容电机一转小车就失控或乱跑电源纹波干扰接收模块给接收模块电源加100nF10uF去耦电容驱动板和逻辑电路分层供电电机端加吸收电容松开按键后小车还会继续跑一段接收端没有超时保护或者超时时间太长检查代码里millis()逻辑设300ms会立即停确保每次有合法帧都更新时间戳两个同样的遥控器会互相干扰地址码没区分把不同遥控器的ADDR改成不同值重新烧录发射端这里面最容易踩的坑是“电源纹波”。很多人一开始怀疑天线、怀疑模块质量问题换了三套模块也没解决最后把驱动板和接收板电源分开就马上好了。如果你是自己画板或者用面包板一定要在接收模块的VCC和GND之间紧挨着引脚位置放一个100nF电容这一点非常重要。4.2 稳定性与距离优化的实操经验如果做出来能跑但距离不理想按下面的顺序优化效果一般比无脑换模块更明显第一步加长天线。模块自带的螺旋天线换掉直接用一根17.3cm的漆包线或杜邦线焊到ANT引脚尽量竖直。第二步降低数据速率。rc-switch库里把setPulseLength从350改成450甚至500肉眼可见误码率下降。第三步给接收模块“擦干净”电源。接收模块的VCC前面串一个10欧姆电阻后面并联两个电容100nF10uF这样电源纹波会被进一步压制。第四步把接收模块远离驱动板和电池。布局上至少保持5厘米以上距离天线不要和电机线平行走线。第五步如果还不行考虑换超外差接收模块。超外差接收的灵敏度在同样环境下能比超再生好不少抗干扰也是质变级别的。另外测试时注意环境因素。433MHz信号穿过人体、金属、潮湿植物时衰减很厉害。你在室内测的距离和楼下公园测的距离没有可比性所以测试报告要说清楚环境自己心里也别因为室内距离短而怀疑模块坏了。4.3 安全和合规问题简要说明433MHz属于ISM频段在中国属于微功率短距离无线电发射设备管理范围合法使用通常要求发射功率在10mW以内。像FS1000A这种模块本身设计就是在允许范围内正常使用完全没问题但不要去加功率放大器、不要乱拆天线改成大增益天线也不要长时间占用频段干扰同频设备。一个常见问题这类模块可能会被周围环境中的同频设备干扰比如楼宇对讲机、无线遥控器。你的小车“莫名”动一下未必是坏了很可能是捕捉到了同频干扰。所以我才反复强调地址码和校验码的作用——它们能挡住绝大多数误触发。至于老旧设备容易被干扰的问题属于正常现象不要为了抗干扰私自加大功率。锂电池的使用也要注意两节18650串联后不要继续用USB口充电必须用平衡充电器。小车不玩时记得把电池断开防止L298N空载时还在缓慢放电。长期不用电池电压低于3.0V会损坏电芯。5. 还能怎么玩进阶方向5.1 增加遥测回传做成双向通信单向遥控做通之后加一套回传链路会立刻让项目“高级”起来。你可以再买一对433MHz模块反向安装把小车上的电池电压、温度、超声波避障传感器数据传回遥控器遥控器上接一块OLED屏幕实时显示。这样做的难点在于收发要错开时间不能同时发否则同频段会撞。简单做法是发射端每100ms发一次控制指令接收端在小车上收到指令后立刻切换到一个“发送窗口”把遥测数据发回去。这种时分复用虽然慢但够用。如果需要真正的全双工建议换成HC-12这种半双工模块或者直接上LoRa距离和稳定性都会更好。5.2 从分立RF模块到RF SoC和数据转换器如果玩到后面发现433MHz ASK只能传控制指令传不了高清视频你想往更高阶的射频方向走那会接触到RF SoC和射频数据转换器。RF SoC指的是把射频收发、模拟前端、ADC/DAC甚至基带处理都集成到一颗芯片里的方案典型的像ADI的AD9361系列、Xilinx的RFSoC。RFSoC里的核心就是射频数据转换器RF Data Converter它把高速ADC/DAC直接塞到了射频通路能够直接采样GHz级别的信号省掉了传统方案里一大堆混频器和中频电路。集成度高带来的一个严格问题就是电源完整性ADC/DAC的信噪比对电源纹波极其敏感稍微一点纹波就会直接转化为底噪恶化所以RFSoC的电源设计需要多路LDO、低纹波开关电源、精密PMU供电。这跟咱们小车里“电机纹波干扰接收模块”的问题是一脉相承的只是小车是电机的粗暴力干扰RFSoC是高速转换器的精密电源要求。如果你用Vivado做RFSoC的裸机开发还会碰到PMU文件、电源域配置这类事情本质都是在保证射频前端有一个干净的电源环境。做小车的这个项目虽然看起来是“低级”的433MHz ASK但你在调天线、调去耦电容、排查电机干扰过程中形成的直觉将来做RFSoC设计时依然用得上。5.3 其他可玩的扩展方向接一个HC-SR04超声波模块让小车在遥控模式下自动检测障碍物遇到障碍自动减速或鸣笛。加一个红外循迹模块把小车从“遥控模式”切换到“循迹模式”变成一辆巡线机器人。在遥控器上加一个摇杆模块读取模拟量来控制PWM速度比单纯的按键手感好很多。用NRF24L01模块替代433MHz能实现双向通信、多通道但距离和穿透性会差一些适合近距离高响应速度的场景。在小车上加摄像头模块把图传画面发回手机这就算真正的“远程机器人”了不过功耗、码率和电源设计都会复杂不少。整个项目做下来我最大的体会是看起来只是“小车会跑了”但里面涉及的东西足够撑起一个电子工程师的入门知识框架。无线通信里的地址和校验、电源设计里的纹波抑制、电机驱动里的PWM控制这些概念放在任何行业项目里都成立。尤其那个电源纹波问题如果你做第一个版本就没被它坑过那说明你运气好但只要你继续在这个领域做下去迟早会回来找这篇文章里的那几个电容。