刚接触Arduino那会儿我也和大多数人一样看着那块巴掌大的蓝色电路板一脸茫然这东西到底能干嘛怎么这么多针脚代码写完了又要怎么弄进去后来靠着一路踩坑、翻文档、拆别人的项目才慢慢摸出了门道。这篇笔记不是官方手册的翻译是我把从零到能独立做小项目的整个学习过程重新梳理了一遍把那些卡住过我的、绕晕过我的、以及书上没写清楚的东西都摊开来讲。无论是完全没碰过硬件的小白还是有点编程基础但没玩过嵌入式的新手这篇笔记都能帮你把最关键的几步走稳。1. 入门之前先搞清楚Arduino到底是什么很多人一开始会把Arduino理解成“一块能编程的开发板”这个说法没错但不够准确。它其实是一整套软硬件生态硬件上是以AVR或ARM单片机为核心的各类开发板软件上是专门为简化单片机开发而设计的Arduino IDE和框架。整套设计的目标只有一个——让完全不懂硬件底层、也不会看芯片手册的人也能在十几分钟内点亮第一颗LED。说白了Arduino做了一件很关键的事把单片机开发里最折磨人的那部分——寄存器配置、时钟配置、引脚复用、中断向量表等——全部封装成了极其简单的函数接口。你写一个pinMode()、digitalWrite()它在背后帮你干掉了成百上千行的底层层代码配置。这就是为什么一个玩过Arduino的人去看裸机嵌入式开发会觉得像是从自动挡换到手动挡。那是不是说Arduino只适合玩具级项目也不是。虽然它的性能上限确实有限但在学习阶段、快速原型验证、智能硬件Demo、创客教育、甚至一些不需要极高实时性的物联网节点上它依然是效率极高的选择。我见过很多人把Arduino用在真实的温室环境监测、室内光照调节、自动化浇灌这类项目里跑几个月都很稳定。学Arduino的价值还不只是在学会用它本身。它打开的是一扇感知物理世界的大门你会开始理解传感器怎么把物理量变成电信号程序怎么通过时序去控制外部设备串口怎么把数据从板子搬回电脑。这些底层的直觉后来学树莓派、ESP32、STM32乃至去接触嵌入式Linux都能复用得上。所以新手最需要建立的第一认知是Arduino不是一个高深的技术目标而是一把钥匙。目标是你自己想做的那个东西Arduino只是最快让你看到结果的手段。2. 硬件和配件怎么选不被商家割韭菜2.1 开发板首选UNO R3但渠道要注意对零基础来说第一块板子基本不用犹豫就是UNO R3。理由很实在它的资料最多教程最多兼容的扩展板最多一旦出问题搜解决方案最容易。它的主控芯片是ATmega328P工作频率16MHz2KB RAM32KB Flash性能参数放到今天看确实很古董但对入门学习绰绰有余。买的时候注意两个点一是尽量选CH340G芯片版本的板子主控芯片方案成熟驱动兼容性好价格通常在二三十元左右二是要避开那些包装得花里胡哨、附赠一堆小配件的“豪华套装”里面大部分传感器你可能一学期都用不上不如把预算花在真正高频用到的模块上。我个人的建议配置是一块UNO R3板子 一块面包板 杜邦线若干公对公为主建议备一小把公对母 一个USB数据线确认能传数据而非只能充电的。这套配置足以完成从点亮LED到做超声波测距这整条入门路径。如果你预算稍充裕可以考虑直接买“UNO R3 传感器套件”的入门组合包但要注意看清单里有没有这几样核心传感器光敏电阻模块、超声波测距模块HC-SR04、红外避障模块、蜂鸣器模块、DHT11温湿度模块、LCD1602液晶屏、几个LED和按键、电位器。没有这几样的话这套件对你初期的学习价值会打折扣。2.2 常用传感器模块的认识网上套件的传感器五花八门新手很容易被名字唬住。我帮你按学习价值排个优先级第一梯队是入门必用的LED、按键、电位器、光敏电阻、蜂鸣器。它们要么让你理解数字输入输出要么让你理解模拟量的读取是建立基本概念的地基。第二梯队是传感器体验类的HC-SR04超声波测距模块、DHT11温湿度模块它们能让你真切地感受到“传感器把物理量变成电信号”这件事配合串口打印数据对理解数据采集的概念非常有用。第三梯队才是一些有趣的扩展LCD1602显示屏、舵机、四位数码管、红外接收模块、蓝牙模块等通常在你做了一个完整小项目之后按需去学更高效。记住一个要点无论买什么模块一定要优先挑选带“模块化引脚”的版本也就是已经引出了VCC、GND、信号脚三根线的那种。直接买裸芯片传感器需要自己搭外围电路对新手来说是额外的负担没有必要。2.3 为什么面包板和杜邦线是必须的很多新手贪图方便直接把传感器引脚插到UNO板的排母上觉得省事又牢固。但养成这个习惯会带来两个问题第一反复插拔极易损伤开发板的焊点和排母板子可能很快报废第二一旦接线出错排查起来完全没有头绪。正确做法是让面包板承担接线中枢的角色开发板的VCC和GND引脚分别通过杜邦线连接到面包板两侧的电源轨上传感器和LED则在面包板中央区域连接。这样做的好处非常明显——你需要同时供电给多个模块时直接从电源轨取电就行改电路时也只需要动面包板上的杜邦线不用反复折腾开发板本身。面包板要选那种带电源轨的也就是长条形的830孔板中间有凹槽两侧有正负电源轨。接线前先搞清楚面包板内部的连接规则中间每竖列的5个孔是导通的两侧电源轨是整条导通的。这个规则一开始不了解的话电路怎么接都不亮排查半天才找到原因——我以前就吃过这个亏。3. 环境搭建IDE安装、驱动和第一块板子上手3.1 IDE选择与安装细节Arduino官方IDE目前有两个路线旧版的1.8.x系列和2.x系列。对新手来说如果电脑配置不是特别老直接装2.x版本就好。它除了包含编辑器、编译器、上传功能外还内置了串口监视器、绘图器和更现代化的代码管理功能用起来顺畅不少。下载地址在Arduino官网的Software页面选择对应自己操作系统的安装包即可。安装过程一路Next基本没什么特别注意的。唯一想提醒的是如果你系统是Windows安装路径尽量不要带中文某些情况下编译器会因为路径编码问题报一些莫名其妙的错误不值得在这个地方浪费时间排查。装完之后建议顺手把界面语言切换成英文。我知道看中文界面更亲切但Arduino IDE毕竟是工具属性软件英文界面的报错信息、文档、论坛讨论全部能对应上后续查资料时会方便很多。3.2 CH340驱动装不上怎么办这是新手遇到的第一个经典拦路虎。绝大多数廉价的UNO板用的是CH340串口芯片Windows 10以上系统一般能自动识别但国内很多精简版系统会禁用驱动自动更新导致板子插上去系统提示“无法识别的USB设备”。解决方法很简单直接去搜索CH340G驱动找到官方驱动包通常是一个压缩包内含Windows/macOS/Linux各平台驱动解压后右键“以管理员身份运行”对应的安装程序装完重启一下系统。再把板子插上设备管理器里就能看到新的COM口了。看到这里我多说一句如果插上后设备管理器里连“未知设备”都没出现大概率是USB线的问题。很多手机的杂牌数据线只通电源不传数据你换一条“带数据传输功能”的线试试往往立竿见影。这个坑真的太大了我身边至少有三分之一的新手朋友卡在这里超过半小时。3.3 首次连接与测试步骤驱动装好之后我们来做一次完整的“开发板-电脑-IDE”链路测试这一步相当于给之后所有项目打个底。操作流程如下用USB线把UNO板连接到电脑等待系统识别出COM口在设备管理器/系统信息里确认端口号。打开Arduino IDE在“工具 开发板”菜单里选择“Arduino Uno”在“工具 端口”里选择刚才出现的COM口。在编辑区输入Blink示例代码void setup() { pinMode(LED_BUILTIN, OUTPUT); } void loop() { digitalWrite(LED_BUILTIN, HIGH); delay(1000); digitalWrite(LED_BUILTIN, LOW); delay(1000); }这段代码让板载LED每秒亮灭一次是Arduino世界的“Hellow World”。点击工具栏的上传按钮向右箭头图标等待状态栏出现“上传完成”。这里有个极易踩的坑上传之前IDE会先编译如果代码里语法有误或开发板型号选错会在输出栏给出报错信息而如果你的开发板型号选对了但COM口选错了会报类似“avrdude: stk500_getsync() attempt 1 of 10: not in sync”的错误——别慌网上说的“需要换板子”基本都是误导真正原因十有八九是端口选错或者驱动没装好。上传成功的那一刻会看到板载LED标着L或者Led13的那个开始有节奏地闪烁恭喜从这一刻起你算是真正入门了。4. 核心语法和程序结构其实就这几个要点4.1 程序骨架setup和loop的底层逻辑Arduino程序的骨架只有两部分void setup()和void loop()。很多新手不理解为什么要分这两个函数其实这是遵循单片机程序的经典范式——初始化与主循环分离。setup()函数在板子通电或复位后只执行一次聪明地用来做一切“只需要做一次”的事设置引脚模式、初始化串口、连接网络等。而loop()函数则会被反复无限循环执行用来处理主逻辑读取传感器、计算、控制输出。这套结构贴合了嵌入式系统“上电配置、死循环工作”的本质运行逻辑。有个细节新手可能不会注意loop()的执行速度非常快如果没有delay()或等待机制它每秒会执行成千上万次。所以写代码时务必想清楚“这段逻辑我到底希望它多久跑一次”否则传感器数据读取、串口输出这些高频操作很容易把数据刷屏甚至可能因为读写太快导致某些传感器模块工作异常。4.2 引脚与I/O模式pinMode、digitalWrite、analogReadArduino编码里最高频的三组I/O函数几乎每个项目都绕不开。pinMode(pin, mode)用来设置引脚工作模式。有两种模式可选OUTPUT表示该引脚输出高/低电平如驱动LED、蜂鸣器INPUT表示读取外部电平信号如按键、传感器信号脚。还有一个INPUT_PULLUP模式开启了芯片内部上拉电阻常见于按键读取场景可以让悬空引脚稳定在高电平按下接地后变低。digitalWrite(pin, value)用于输出电平参数是HIGH约5V或LOW约0V。需要注意UNO板上的数字引脚可以提供5V高电平但最大电流能力很有限——单个引脚通常建议不超过20mA所以直接驱动LED需要串联一个220Ω的限流电阻。有朋友直接不接电阻把LED插上去结果LED瞬间烧掉这不是板子的问题是电流太大了。analogRead(pin)则是读取模拟引脚A0~A5上的电压值返回0~1023之间的整数。原理是UNO的ATmega328P内置了10位ADC把0~5V电压线性映射到0~1023。理解这个映射关系很关键比如光敏电阻模块返回512意味着电压大约2.5V。另外还有一个没那么常用但要知道的analogWrite(pin, value)它其实不是真正的模拟输出而是通过PWM脉冲宽度调制技术以约490Hz的频率快速切换高低电平通过改变占空比来“模拟”一个介于0与5V之间的平均电压——这就是为什么你可以用它控制LED亮度、控制舵机角度。常见误区是把analogWrite写成数字引脚也可用实际上只有带~符号标记的引脚才支持PWM。4.3 串口通信调试三板斧串口是我眼中Arduino调试的第一神器。你写再多delay看LED闪烁都没用不如一行Serial.println()直接把数值打印到电脑屏幕上来得直观。使用套路是固定的setup()里设置Serial.begin(9600);括号里的9600是波特率也就是每秒传输9600比特位常见取值还有115200。需要打印的位置写Serial.print()或Serial.println()——前者不打换行后者自动换行。在IDE侧点击“工具 串口监视器”弹出窗口右下角选择与代码里一致的波特率就能看到板子发回来的数据了。新手最容易犯的错误就是波特率不匹配代码里写了115200监视器里却选9600出来的就是一些乱码符号。不过也别太焦虑调试工具都是练出来的最直接的办法是每行数据带上明确标识比如Serial.println(Distance: String(cm))这样既方便阅读又方便在多个数值里快速定位异常值。4.4 变量和作用域为什么你的代码会“串线”很多刚接触Arduino的新手在写多项目时会把所有变量一股脑放在代码开头。这在简单Demo里没问题但等代码长起来就麻烦了函数之间的变量被无意间修改传感器状态互相干扰想理清逻辑却一锅粥。这里的核心概念是“作用域”。定义在setup()、loop()等函数内部的变量叫局部变量只有那个函数内部能访问定义在函数外部的叫全局变量所有函数都能访问。初学者容易出问题的场景是在loop()里定义了一个变量然后想在下一次循环时继续用它的值结果发现每次循环它都被重新清零——因为局部变量每次进函数都会重新分配。我的建议是入门阶段保持简单直接的学习路径核心逻辑相关的变量放在文件顶部临时计算用的变量放到函数内部。等到对变量生命周期有更深理解了再去优化代码结构也不迟。4.5 条件判断和循环简洁控制流构建项目逻辑Arduino代码的控制流和通用C语言是一致的if、else if、else做分支for和while做循环。这里不想展开讲语法基础只想说一个实际经验项目逻辑越复杂越要把“状态机”的思想引进来。举个实际例子你想做一盏自动灯白天关晚上亮有人经过时闪烁提醒。如果全线用一堆if嵌套运行起来极易出现各种边缘问题天黑到一半时有人经过怎么处理闪烁到一半天亮了要不要急停用状态机思想来拆解把“白天待机”“夜间照明”“闪烁提醒”三个状态抽象出来每次loop()只处理“当前状态下的动作”和“状态切换条件”逻辑清晰度完全不一样。delay()本身会让整个程序阻塞——在延时期间Arduino什么也做不了。如果你希望程序在等待时还能响应按键、读取数据可以用“非阻塞”的办法记录时间戳配合millis()函数判断“距离上次执行是否超过500毫秒”。这是新手迈向进阶必过的一道坎。5. 五个从易到难的实战项目5.1 呼吸灯让LED从亮到灭像呼吸一样平滑呼吸灯是练习PWM和循环的绝佳入门项目。逻辑不复杂让LED亮度从0逐渐增加到255再从255逐渐减到0循环往复。关键在于理解analogWrite的取值和delay的配合int ledPin 9; // 9号引脚支持PWM int brightness 0; int fadeAmount 5; void setup() { pinMode(ledPin, OUTPUT); } void loop() { analogWrite(ledPin, brightness); brightness brightness fadeAmount; if (brightness 0 || brightness 255) { fadeAmount -fadeAmount; } delay(30); }这里每次改变亮度步进值设成5延时30ms效果会比较平滑且有呼吸感。你调起来会发现两个参数的感觉各有不同步进值越大变化看起来越生硬延时时间越短呼吸频率越快。推荐新手自己多改一改参数亲自感受“占空比变化”和“视觉亮度变化”之间的关系这是理解PWM性价比最高的一课。5.2 按键控制LED数字输入与防抖这个项目非常简单但引入了一个嵌入式开发中极其经典的topic——按键消抖。按键在物理上刚被按下和释放的一瞬间接触并不稳定会在几十毫秒内产生多次高低电平的抖动。如果不处理这些抖动程序可能会把“按一次”误判成“按好几次”。一种最简单的消抖思路是延时重读检测到电平变化后等待20ms~50ms再读取一次确认电平是否稳定。虽然不算最优方案但对入门阶段理解问题本质帮助很大。const int buttonPin 2; const int ledPin 13; int ledState LOW; int lastButtonState LOW; unsigned long lastDebounceTime 0; void setup() { pinMode(buttonPin, INPUT_PULLUP); // 开启内部上拉 pinMode(ledPin, OUTPUT); } void loop() { int reading digitalRead(buttonPin); if (reading ! lastButtonState) { lastDebounceTime millis(); // 记录状态变化时间 } if ((millis() - lastDebounceTime) 50) { if (reading ! ledState) { ledState reading; if (ledState LOW) { digitalWrite(ledPin, !digitalRead(ledPin)); // 切换LED } } } lastButtonState reading; }这版代码里用到了INPUT_PULLUP所以按键一端接GND另一端接2号引脚即可按下时读到LOW松开后读到HIGH。millis()在这里的用法也值得注意——它不是阻塞式的不会影响其他程序运行这是和delay()最大的区别。初学者自己实现时可以先不做消抖感受一下“按键控制LED但闪烁不定”的现象再对照消抖版本去找差异。有对比才有体感尤其是这些微妙的现象靠别人的文字描述远不如自己亲手碰一遍来得深刻。5.3 超声波测距传感器数据读取与换算超声波测距模块HC-SR04是我特别推荐新手尽早尝试的传感器因为它能让“测距”这件看起来有点抽象的事情变得无比直白。它的工作逻辑是触发脚Trig收到至少10微秒的高电平脉冲后模块发射8个40kHz的超声波脉冲同时回波脚Echo输出高电平高电平持续的时长就是超声波从发射到接收的总时间。代码里用pulseIn()函数来测量Echo引脚高电平的持续时间再根据声速340m/s换算出距离。公式是距离(cm) 时间(微秒) / 2 * 0.034因为声音来回走了两倍距离所以时间要先对半分。const int trigPin 7; const int echoPin 6; void setup() { pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); Serial.begin(9600); } void loop() { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); long duration pulseIn(echoPin, HIGH); float distanceCm duration * 0.034 / 2; Serial.print(Distance: ); Serial.print(distanceCm); Serial.println( cm); delay(500); }调这个项目时有两个实际经验一是传感器正前方不要对着杂物超声波会被提前反射导致读数偏小二是模块供电不稳定时读数会跳得很厉害最好用面包板电源轨统一供电不要直接从UNO的数字引脚扇出很多负载。测量结果在几十厘米到几米的范围内非常可靠还能在小伙伴面前秀一把。5.4 光控LED模拟量读取与阈值判断前面几个项目都在玩数字信号光控LED第一次让你接触到“世界的万物其实是连续变化”的模拟量。光敏电阻模块在不同的光照下输出不同电平或电压我们通过analogRead获取这个值再设定阈值决定LED亮灭。接线方式光敏模块VCC接5VGND接GNDDO或AO输出脚接A0。如果模块只有光敏电阻本体两个脚那么需要自己搭一个分压电路把光敏电阻与一个10kΩ电阻串联在5V和GND之间将中间点接到A0读取。思路很简单白天光强时电阻低或模块输出低晚上光弱时电阻高或模块输出高。程序里只要设置一个合适的阈值即可但这个阈值可能因环境差异需要反复调参。不想每次改代码烧录一遍的话可以用一颗电位器当可调电阻来做阈值调节——这种方式在真实产品里也常能看到。写代码的核心如下const int lightSensorPin A0; const int ledPin 9; int sensorValue 0; void setup() { pinMode(ledPin, OUTPUT); Serial.begin(9600); } void loop() { sensorValue analogRead(lightSensorPin); if (sensorValue 600) { digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } Serial.println(sensorValue); delay(200); }阈值为什么不设成500是因为我实测的白天空旷环境读数可能是850室内傍晚可能是500关灯全黑时可能就100多——所以你需要先在串口监视器里观察一段时间实际数据再挑选数值。学习模拟量的核心就是“别靠猜用数据说话”。5.5 蜂鸣器与温度报警器把传感器数据变成声音反馈到这一步你已经有能力串起一个小而完整的系统了DHT11温湿度传感器采集温度按键设置报警阈值蜂鸣器在超温时报警整机逻辑用串口打印状态。虽然听起来朴素但麻雀虽小五脏俱全做完整个流程会极大地建立自信。接线方面DHT11是3引脚VCC、DATA、GND 一个NC空脚DATA脚接数字引脚2并在DATA和VCC之间接一个4.7kΩ上拉电阻。这个电阻是DHT11数据手册要求的少了它通信会不稳定。蜂鸣器模块VCC接5V、GND接GND、中间信号脚接数字引脚8。用DHT库读取温湿度只需要两行代码但找库这一步新手容易卡住。在IDE的“库管理器”里搜索DHT sensor library由Adafruit维护的那个是标准选择装完记得同时安装它依赖的Adafruit Unified Sensor库否则编译会报错。这个“依赖库”的概念很多新人第一次遇到习惯就好。核心逻辑和前面项目差不多不展开太多。唯一值得说的是报警阈值不要写死在代码里用一个变量存储后续接上按键调节阈值就是另一个小项目了。做完整条路线你会发现所有传感器项目的图景都是如此相似数据输入、判断处理、输出反馈只是形式上从LED换成了蜂鸣器或屏幕而已。6. 常见报错和排查思路遇到问题不慌6.1 编译报错和上传报错的区分新手看到红字就慌其实只要分清错误出现在哪个阶段排查范围立刻缩小一半。编译阶段的报错输出栏会出现类似xxx.cpp: In function void loop()的提示后面跟着具体行号和错误描述。最常见的原因无非是拼写错误、括号不匹配、忘记加分号、库没装全。IDE输出栏里双击报错信息能直接跳转到代码对应行检查那行附近的小范围即可。上传阶段的报错则通常出现在编译完成后典型症状是输出栏刷出一长串“avrdude”开头的消息。这类错误优先级最高的排查项是开发板型号选对了没有端口选的是不是正确COM口板子上有没有其他软件占用串口很多情况下是上一秒刚打开串口监视器没关又去点击上传导致串口被占用关掉监视器再试一次就好。6.2 硬件故障的排查思路硬件层面的问题遵循“由简到繁、先电源后信号”的排查步骤准没错。首先确认板子电源指示灯亮不亮——不亮先查USB线。其次确认传感器电源脚有没有5V——用万用表量一下电源轨和开发板5V脚之间是否有电压。最后才去查信号线是不是接到了正确的引脚——用杜邦线一根一根对一下。一个我建议新手养成的好习惯任何传感器接入前先只给它接上VCC和GND在串口监视器里看它是否正常输出读数确认模块“活着”之后再接信号线。这一步虽然多花一分钟但能省下大量排查故障的时间。6.3 排查“为什么明明照着教程写却不出效果”很多新手最容易忽视的问题是电源。UNO板通过USB供电时最大输出电流通常在500mA左右如果同时驱动LED、蜂鸣器、多个传感器模块板子可能因为供电不足导致模块工作异常。现象就是运行时偶发复位、传感器读数飘忽、LED亮度变暗。这时外接一个5V/1A以上的电源适配器到UNO的电源插孔通常问题就解决了。第二个容易忽视的问题是引脚编号。有些教程用A0~A5代表模拟口又有一些用数字编号。如果接线接在A0代码却写了pinMode(14, OUTPUT)它其实指的不是A0——因为UNO里从A0开始编号是14~19。这种错位非常隐蔽排查时一定要先捋清楚编码对应关系。最后想说一个可能需要放平心态的事Arduino的学习曲线不是匀速的有时一个接线错位可能让你折腾一个晚上。这不是你不行而是硬件调试本来就有这样的属性。我的经验是先把串口打印用起来让数据自己告诉你答案再配合系统性排查绝大多数问题都能在十几分钟内定位到。7. 学完基础后下一步可以怎么走如果你顺利做完上面五个项目恭喜你已经掌握了Arduino的核心能力和单片机编程的基本思维方式。接下来大概有三个比较主流的方向可以选看你自己的兴趣。第一个方向是往物联网走。给Arduino加上ESP8266或ESP32模块它就能联网了然后可以往云平台上报数据、用手机远程控制开关、做环境数据的远程监测。这个方向会用到网络协议、JSON解析、MQTT等新概念但说实话有了Arduino的基础学习曲线不会太陡。第二个方向是往结构件和机器人方向走。买一个舵机云台或者小车底盘配合超声波/红外传感器做自动避障、遥控小车、机械臂抓取的小项目。这个方向涉及电机驱动、舵机控制、运动学基础趣味性很强很能拉人入坑。第三个方向是往纯嵌入式底层走。在用Arduino编程时看到那些库函数背后其实运行在真实的寄存器、中断、时钟系统上。买一块STM32最小系统板或者继续用好手上的ATmega328P裸机编程、查数据手册、操作寄存器学完会对计算机体系结构有更深刻的理解。不管选哪个方向有一点我的体会很深保持项目驱动是最有效的学习方法。不用试图把某本厚厚的教程从第一页读到最后一页而是先锁定一个小东西比如“给客厅加一个温湿度计”“给鱼缸做一个自动喂食器”然后为这个目标去学能用到的技术。做完一个东西的成就感比啃十章书都更能支撑你继续往前走。最后再补一句实操经验把每一个跑通的项目代码和接线图保存好命名清楚放在单独的文件夹里。这不仅是记录更是你后续做复杂项目的素材库。我自己的很多新项目都是从前几个月甚至前几年写的旧代码里拼拼改改拼出来的。对Arduino来说这大概也是最正常的打开方式。