基础入门
第 9 课:走通第一条闭环
感知 → 判断 → 动作,把前两节课合起来,做出第一个完整的作品
我是吴老师。这节课是「基础入门」的最后一节。
前面八节课,你学的都是零件:怎么点灯、怎么读按钮、怎么打印、怎么量电压。
这节课把它们拼起来。 从这以后,你做的每一个东西,都是同一套结构的反复变奏。
一、先看一张图:所有作品的共同结构
不管多复杂的智能设备——智能灯泡、扫地机器人、电梯——扒开看,都只有三个部分:
| 环节 | 干什么 | 用你手上的东西举例 |
|---|---|---|
| 传感器 | 感知世界 | 按钮、光敏、超声波、温湿度…… |
| 主控 | 判断 | ESP32-C3 在跑你写的逻辑 |
| 执行器 | 做出动作 | LED、蜂鸣器、舵机、OLED…… |
听上去很理所当然,对吧?但这三个环节缺一不可。
- 只点灯、不判断 → 那叫演示,不叫作品
- 只读取、不动作 → 那叫白算,用户根本感知不到
真正的作品,必须走完这个循环。 而且循环不是"跑一次"——它是转圈圈的:传感器一直在看,主控一直在判断,执行器一直在动。
记住这句话,后面 12 个实战课题,每一个我都要拿这三个环节检查一遍。
如果哪个课题只做到了其中两个,那它就不是成品——我会直接说"这个不行"。
二、判断:if 是什么
前两节课,你学会了"读"和"写"。但这中间缺一样东西:"想"。
读到了按钮的值,然后呢? 你得决定"什么情况下该做A、什么情况下该做B"。这就是 if 干的活。
if (条件) {
// 条件成立时,执行这里
}if 就是个门卫。
条件成立 → 放行,执行大括号里的代码。 条件不成立 → 整块跳过去,当作没看见。
就这么简单。
有一点我要专门说:条件不成立不是"出错"。
很多新手写代码时会想"如果条件不成立怎么办,程序会不会崩"——不会。它只是安安静静地跳过那块代码,继续往下走。
你没按按钮,灯不想亮——这本来就是对的。 不是异常,是正常。
比较运算符:五个符号
if 里的"条件",通常是在比较两个东西:
| 符号 | 意思 | 例子 |
|---|---|---|
== |
等于 | if (x == 1) |
!= |
不等于 | if (x != 1) |
> < |
大于、小于 | if (x > 2000) |
>= <= |
大于等于、小于等于 | if (x >= 2000) |
这里有个特别容易踩的坑,我要重点说:
判断相等要用两个等号
==,不是一个!C++ if (x = 1) // ❌ 错:这是"赋值",把 x 改成 1,结果永远成立 if (x == 1) // ✅ 对:这是"比较",问 x 是不是等于 1
=是"赋值"(把右边给左边),==才是"比较"(问是不是相等)。写成一个等号会出大问题——那个 if 永远成立,因为赋值这个动作本身总是"成功"的。
而且它不一定报错,程序照跑,只是逻辑完全不对。这是初学者最难查的错误之一。记住了:比较用两个等号。
三、第一个完整作品:按键开关灯
现在把它拼起来。
目标
按住按钮,灯亮;松开,灯灭。
简单吧?但这是你的第一个完整闭环。
| 环节 | 用什么 |
|---|---|
| 传感器 | 按钮(读 GPIO4) |
| 主控 | 判断按钮是不是按下了 |
| 执行器 | LED 模块(写 GPIO3) |
接线
接之前先断电。
| 模块 | 引脚 | 接到 |
|---|---|---|
| 按钮 | VCC / GND / OUT |
3.3V / GND / GPIO4 |
| LED | VCC / GND / Signal |
3.3V / GND / GPIO3 |
注意:两个模块都要接 VCC 和 GND。 别只顾着信号线,忘了给它们供电——这是新手高频错误。
还有一件事:它们的 GND 必须接到同一个地方。 你回忆一下第 4 课讲的"共地"——不共地,信号就是对牛弹琴。
先想清楚:按下时读到的是几
别急着写代码。 按第 5 课的规矩,先测,再猜。
用万用表量一下 GPIO4:
- 不按的时候是多少伏?
- 按住的时候是多少伏?
记下来。 假设你量出来「不按 = 3.3V,按住 = 0V」,那代码就这么写:
void setup() {
Serial.begin(115200);
pinMode(4, INPUT_PULLUP); // 按钮:输入 + 上拉
pinMode(3, OUTPUT); // LED:输出
}
void loop() {
int btn = digitalRead(4); // 第 1 步:读
if (btn == LOW) { // 第 2 步:判断(按下时是低电平)
digitalWrite(3, HIGH); // 第 3 步:动作
} else {
digitalWrite(3, LOW);
}
}看出来了吗?这就是那三个环节:读 → 判断 → 写。
关于 else
上面出现了 else,意思很直白:
if (条件) {
// 条件成立做这个
} else {
// 条件不成立做那个
}有 else 就是"二选一",没 else 就是"成立才做,不成立啥也不做"。
这里用 else 是有必要的——不按的时候要主动把灯关掉,不然灯会一直亮着。
一个更简单的写法
上面那个 if/else 其实可以简化成一行:
void loop() {
int btn = digitalRead(4);
digitalWrite(3, !btn); // 注意那个感叹号
}! 是"取反" —— !HIGH 就是 LOW,!LOW 就是 HIGH。
因为"按下是低电平",而我们想"按下时灯亮",所以按钮读到的值取反给灯,正好。
但这个写法有个前提:你的按钮确实是"按下为低"。
如果哪天你换了块板子,或者改了接线,按下变成高电平了——这行代码就反了,灯会变成"按下灭、松开亮"。
所以我还是建议你用上面那个
if/else版本。 它多打几个字,但意图清楚:一眼就能看出"按下时该干什么"。等以后程序复杂了,你会感激自己写得明白。
四、让判断"活"起来
上面那个程序只会做一件事。但我们说过,闭环是转圈圈的——判断可以更复杂。
加一点条件
void loop() {
int btn = digitalRead(4);
if (btn == LOW) {
digitalWrite(3, HIGH);
Serial.println("灯亮了");
} else {
digitalWrite(3, LOW);
Serial.println("灯灭了");
}
}加了两句打印。 现在你能同时看见"灯的状态"和"程序的想法"。
这就是第 7 课那个习惯的延续——让你的程序透明。
多个条件:&& 和 ||
以后你会遇到"两个条件同时成立"的情况:
| 符号 | 意思 | 例子 |
|---|---|---|
&& |
而且(两个都成立) | if (天黑了 && 有人) |
|| |
或者(任一个成立) | if (按钮按了 || 定时到了) |
这两个符号你后面会天天用。 比如实战课题里的"天黑而且有人经过才亮灯",就是 &&。
现在你不用深究,先记住有这么两个东西。等第 26 课做光控小夜灯的时候,你会真的用上。
五、这一课的意义
我知道这节课看起来很简单——不就是按个按钮点个灯吗。
但你实际做成的,是你的第一个"会对外界做出反应"的东西。
对比一下:
- 第 6 课的灯:不管发生什么,它都按自己节奏闪——它跟世界没有关系
- 这节课的灯:你按它才亮——它开始响应了
这个差别,就是"灯"和"智能设备"之间的分界线。
以后你做的所有东西——追光的小雷达、自动感应门、能联网的天气站——结构上都是这节课的放大版。只不过把"按钮"换成"光敏",把"灯"换成"舵机",把那个简单的 if 换成更复杂的判断。
大纲里那 12 个实战课题,本质上都是这节课。 零件多了、判断复杂了、外壳要自己做了——但骨架没变。
你已经把它走通一遍了。
自测
答案与解析
= 是赋值(把右边给左边),== 才是比较(问是不是相等)。写成 if (x = 1) 会出大问题——那个赋值动作总是"成功",所以条件永远成立,而且程序不一定报错,逻辑却完全不对。这是初学者最难查的错误之一。
答案与解析
完整闭环必须走完 传感器 → 判断 → 执行器 三个环节。只读取不动作,用户根本不知道它在工作;只动作不判断(比如灯一直闪),那叫演示不叫作品。后面 12 个实战课题,每个都会被拿这三个环节检查。
答题要点
答题要点应该包含:这节课的"按钮 + 判断 + LED"已经走完了传感器 → 主控判断 → 执行器的完整结构。实战课题只是把零件换掉、把判断变复杂——比如"光敏 + 阈值判断 + LED"(第 26 课光控小夜灯),或者"超声波 + 距离判断 + 舵机"(第 28 课倒车雷达)。骨架完全一样,换的只是具体的零件和条件。 所以这节课走通了,后面只是不断重复这个结构。
拓展如果按钮和 LED 各自接了不同的电源(比如按钮接 3.3V、LED 接 5V),它们还能正常配合吗?为什么?
这个问题课上不讲,留给你自己找答案——**问 AI 是最好的办法**。
提示:搜"共地 为什么必须"、"不同的电源 共地"。想一想:第 4 课讲的"地是参照物",在有两个电源的时候会怎么样?
拓展现实中的智能设备,判断逻辑通常比 if 复杂得多。它们是怎么组织的?
这个问题课上不讲,留给你自己找答案——**问 AI 是最好的办法**。
提示:搜"状态机 编程"、"有限状态机 是什么"。想一想:一个电梯有"待机、上行、下行、开门、关门"这几种状态,用一堆 if 能写吗?有没有更好的办法?
本节你要动手做的事
- [ ] 接好两个模块:按钮→
GPIO4,LED→GPIO3,两个都要接VCC和GND,而且要共地 - [ ] 先用万用表量:按下和松开时,
GPIO4分别是多少伏?把结论记在笔记里 - [ ] 跑通"按住就亮",然后用
Serial.println把状态打出来 - [ ] 故意改错一次:把
if (btn == LOW)改成if (btn = LOW),看看会发生什么,记住这个现象 - [ ] 自己换个玩法:比如"按住灯灭、松开灯亮",或者"按一下换一种颜色"(如果你有 RGB 模块)
「基础入门」上完了,说几句
你刚走完了这套课的第一段路。
回头看这六节课:
| 课 | 你学会了 |
|---|---|
| 4 | 认识元件、认识三根线 |
| 5 | 万用表——能看见电 |
| 6 | 数字输出——让板子动手 |
| 7 | 串口打印——让板子说话 |
| 8 | 数字输入——让板子听话 |
| 9 | 闭环——把上面全串起来 |
这六样东西,是你后面所有内容的工具箱。 从第 10 课开始学各种传感器,本质上都是在学"怎么把外界的各种信息,变成电信号读进来";而输出类的课,都是在学"怎么把电信号,变成各种动作"。
结构没变,只是零件变多了。
最后说一件我特别想让你记住的事。
这几节课里,我反复在做同一件事:遇到问题,先测,再猜。
万用表教你这个,串口打印教你这个,
if那节课我又提了一遍。这不是重复啰嗦——这是这门课最想教给你的东西。硬件课的难点从来不是你不够聪明,而是你看不见里面发生了什么。所以你得学会给自己造工具:用万用表看电压,用串口看逻辑。
会造工具的人,永远比只会背答案的人走得远。
下一单元我们开始一个一个认识传感器。先从最简单的模拟输入开始——电位器。