实战课题
第 36 课:无线报警器
两块板子、一根线都不连,隔着一间屋子把"有情况"喊出来
这节课需要两块板子。 你只有一块的话可以跳过——它不影响最后一课。
我是吴老师。这是三个 C 档课题里的第二个,它代表的方向是"无线通信"。
先想一件事。上一节课,你人在教室、灯在家里,中间隔着互联网、隔着服务器、隔着路由器——你花了整整一节课,才把那条路走通。
这个课题反过来:什么都不用。
没有路由器、没有服务器、没有互联网、没有账号、没有密码。两块巴掌大的板子,隔着一间屋子,就这么把话说了。
而且它说得很"硬"——你把它俩拿到山里、拿到地下室、拿到任何一个手机没信号的地方,它照样能用。
一、这个课题的真正价值:不依赖
第 24 课我讲过一段话,这里再讲一遍,因为这个课题就是它的实物版。
我们在教室里用 WiFi 用得太顺手了,容易产生一种错觉:觉得哪儿都有网。
但你真去干点活就会发现完全不是这样。 山里、地里、渔船上——那儿根本没有 WiFi;地下车库、老房子储藏间、电梯井——信号进不去;大棚、工地、野外监测点——拉网线不现实。
这些地方,"没有网络"才是常态。这时候,"不依赖网络的通信"就不是炫技,是刚需。
看这张图。上面那条路,是上一节课你走的路——板 A → 路由器 → 服务器 → 板 B。好用,但前提是:路由器得有、网得通、服务器不能挂、信号得覆盖到、板 B 也得连上同一个网。五样,少一样就全完蛋。
下面那条路,就是你这个课题要走的路。板 A 直接跟板 B 说。
打个比方:上一节课像你托一个快递公司寄东西——得填单子、得有网点、得路上不出岔子。这个课题像两个同学在操场上喊话——不用办卡,直接喊。
(正式叫法是"点对点"或者"对等网络",你以后查资料看到 peer-to-peer、P2P,就是这个意思。)
二、闭环:这个课题的三个环节
第 9 课讲的闭环还记得吧:传感器(看)→ 主控(想)→ 执行器(做)。
这个课题有意思的地方在这儿——闭环被切成两半了,中间那一刀是"空气"。
| 环节 | 在哪块板子上 | 是什么 |
|---|---|---|
| 传感器(看) | 探测器板 | 按钮(也可以换成光敏、红外、超声波——这个你自己定) |
| 判断(想) | 两块板子各有一次 | 探测器判断"按下了没";报警器判断"收到的是什么" |
| 执行器(做) | 报警器板 | 蜂鸣器响 + LED 闪 |
看出来了吗?三环节分散在两块板子上,中间那一段是无线电。
前面所有课题,这三环都挤在一块板子上,一步就能走完。这个课题你得跑两趟——而且大部分麻烦都出在"两趟之间那一段"。
顺便说一件重要的事:判断这一环,在这个课题里出现了两次。探测器要判断"按钮是不是真按下了"(不能手一抖就报一次);报警器要判断"这条消息是什么含义"(是真有情况,还是只是一次心跳)。
两块板子都在"想事情",只是想的不是同一件事。 这个结构,你以后做任何分布式的东西都会一直用到。
三、材料清单
套件里:ESP32-C3 开发板 ×2(没有第二块的话本课可以跳过)、蜂鸣器模块 ×1(丝印 VCC I/O GND,有源、高电平触发、只能一个音调)、LED 灯模块 ×1、按钮模块 ×1(VCC OUT GND,触发方式你可以换)、杜邦线 ×6(每块板子 3 根)、USB 数据线 ×1。
身边要准备的:
| 东西 | 干嘛用 |
|---|---|
| 冰棒棍 | 两个外壳的骨架。吃剩的洗干净晾干,十来根就够 |
| 快递盒纸皮 | 做底板和顶盖 |
| 热熔胶枪 + 胶棒 | 粘冰棒棍,主力工具 |
| 剪刀、尺子、铅笔 | 剪冰棒棍用剪刀就行,咔嚓一下会崩屑,别对着脸剪 |
| 充电宝 + 手机充电头 | 探测器板最后要脱离电脑,它得自己有个电源 |
两块板子哪儿来的? 第 24 课说过:再买一块一样的 ESP32-C3,几十块钱;或者跟同学合买,你俩一人一块——顺便还能互相检查接线,比一个人闷头搞好得多。
四、接线
这个课题的接线,我要你分成两个独立的系统来做。 这一点非常重要,一会儿讲为什么。
探测器板(负责"看"和"发"):
| 按钮模块 | 接到 |
|---|---|
| VCC | 3.3V |
| GND | GND |
OUT |
GPIO4 ← 记住这个脚号,一会儿有大用 |
报警器板(负责"做"):
| 模块 | 针脚 | 接到 |
|---|---|---|
| LED 模块 | VCC / GND / Signal |
3.3V / GND / GPIO3 |
| 蜂鸣器 | VCC / GND / I/O |
3.3V / GND / GPIO5 |
关于引脚:
GPIO3是灯、GPIO5是蜂鸣器,这是第 6 课和第 17 课定下来的老位置。接哪个数字脚其实无所谓,只要代码里的数字跟着改。(第 24 课的例子里蜂鸣器接的是GPIO4,那是因为那块板子上没接按钮。本课探测器板要用GPIO4接按钮,所以报警器这边沿用原来的位置更清爽。)两块板子都避开了
GPIO2、GPIO8、GPIO9(strapping 脚,第 4 课那张表)。
接线之前先拔 USB。 这条规矩从第 4 课讲到这儿。
五、动手:分三步,前两步是"分开测"
这个课题最容易出错的地方,是两块板子。
所以做法跟前面所有课都不一样:先把两块板子当成两个独立的东西,各自测通,再把它俩连起来。
为什么这么干? 因为一旦连起来不工作,你面对的是两个可能坏掉的东西,外加一段看不见的无线电。三个未知数,你没法解。
但如果你先确认了"探测器这边是好的"和"报警器这边是好的",那出问题时就只剩一段无线电——未知数从三个变成一个。
这就是第 23 课那个"对半砍"的思路,在这个课题里它升级了:这次你砍的不是一条链路的两半,是两个设备。
第 1 步:两块板子各读一次 MAC
这一步千万别跳。 程序就是第 24 课那个,核心还是这两行:
WiFi.mode(WIFI_STA); // 先切到"上网模式",再读 MAC
Serial.println(WiFi.macAddress());板子 A 烧一遍,抄下来。换板子 B,同样的程序再烧一遍,抄下来。 拿张纸写清楚(别只存在脑子里,这个课题你要来回翻它):
| MAC 地址 | |
|---|---|
| 探测器板 | __:__:__:__:__:__ |
| 报警器板 | __:__:__:__:__:__ |
读出来是
00:00:00:00:00:00? 别慌,不是板子坏了——先调用WiFi.mode(WIFI_STA)再读。
第 2 步:两块板子各自先测通
先不写无线。 探测器板把按钮状态打印出来,报警器板自己响两下——两块板子各测各的,谁也别管谁。
探测器板:
const int BTN_PIN = 4;
void setup() {
Serial.begin(115200);
pinMode(BTN_PIN, INPUT);
Serial.println("探测器:按钮测试");
}
void loop() {
Serial.print("GPIO4 = ");
Serial.println(digitalRead(BTN_PIN));
delay(300);
}烧进去,打开串口,按按钮、松开、再按下。你要看到那个数字在变。
变就对了。顺便记下"按下时是 0 还是 1"——这个方向你得自己测,别背(第 5 课那句"先测,再猜")。
第 8 课说过按钮模块一般按下是
LOW,但我不让你直接信这个。万一你手上这块不一样呢?跑一遍,十秒钟的事。
报警器板: 也不写无线,直接让它自己响两秒、停两秒。setup() 里把 LED_PIN(3)和 BUZZER_PIN(5)设成 OUTPUT,loop() 里就这样来回倒:
digitalWrite(LED_PIN, HIGH);
digitalWrite(BUZZER_PIN, HIGH);
delay(2000);
digitalWrite(LED_PIN, LOW);
digitalWrite(BUZZER_PIN, LOW);
delay(2000);灯亮两秒、蜂鸣器响两秒。 看到这个现象,说明报警器这半边的硬件全是好的——线没接错、脚号没写错、模块没坏。
现在你手里有两个各自能跑的东西了。 未知数只剩一个:中间那段无线电。
第 3 步:合起来——一个发,一个收
现在最关键的一句话,我加粗说:
两块板子要烧不同的程序。
这是新手最容易犯的错,而且错得毫无痕迹。
你很自然就会想:"两块板子嘛,程序当然一样。"——然后两块都在发,没人收。 现象是两块板子的串口都在刷"我发了",对面一点动静都没有。你会以为是无线坏了,其实是你的脑子里,这两块板子还是同一块。
探测器板(发):
#include <WiFi.h>
#include <esp_now.h>
// ⚠ 换成你抄下来的"报警器板"的 MAC 地址
uint8_t receiverMAC[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
const int BTN_PIN = 4;
void setup() {
Serial.begin(115200);
pinMode(BTN_PIN, INPUT);
WiFi.mode(WIFI_STA);
Serial.print("我是探测器,我的 MAC:");
Serial.println(WiFi.macAddress()); // 串口里有这一句 = 这块烧的是探测器程序
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW 初始化失败");
return;
}
esp_now_peer_info_t peer = {};
memcpy(peer.peer_addr, receiverMAC, 6);
peer.channel = 0;
peer.encrypt = false;
esp_now_add_peer(&peer); // 把对方"存成联系人"
Serial.println("探测器就绪");
}
void loop() {
if (digitalRead(BTN_PIN) == LOW) { // 按钮按下(方向以你第 2 步测的为准)
uint8_t data = 1;
esp_now_send(receiverMAC, &data, sizeof(data));
Serial.println("→ 已发出:1");
delay(2000); // 别连着发,一次就够
}
}报警器板(收):
#include <WiFi.h>
#include <esp_now.h>
const int LED_PIN = 3;
const int BUZZER_PIN = 5;
unsigned long lastAlarm = 0;
// 收到消息就会自动跑这个函数
void onReceive(const uint8_t *mac, const uint8_t *data, int len) {
Serial.print("收到来自:");
for (int i = 0; i < 6; i++) {
Serial.printf("%02X", mac[i]);
if (i < 5) Serial.print(":");
}
Serial.println();
if (len > 0 && data[0] == 1) {
digitalWrite(LED_PIN, HIGH);
digitalWrite(BUZZER_PIN, HIGH);
lastAlarm = millis();
Serial.println("→ 报警!");
}
}
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
WiFi.mode(WIFI_STA);
Serial.print("我是报警器,我的 MAC:");
Serial.println(WiFi.macAddress()); // 串口里有这一句 = 这块烧的是报警器程序
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW 初始化失败");
return;
}
esp_now_register_recv_cb(onReceive); // 挂号:收到了就叫我
Serial.println("报警器就绪");
}
void loop() {
if (millis() - lastAlarm > 1000) { // 响一秒就停,免得吵死人
digitalWrite(LED_PIN, LOW);
digitalWrite(BUZZER_PIN, LOW);
}
}两块板子都插上电。 按下探测器上的按钮——报警器那边的灯亮一秒、蜂鸣器响一秒。
成了。这就是两块板子隔空说话,不用任何网络。
走两步试试。 拿着探测器板走到隔壁房间,看看还响不响。空旷处厂家标称能到几十甚至上百米,但你家有墙——能穿一两道墙就不错了。到底多远,你自己实测一遍,这个数字是你自己测出来的,比任何参数表都靠谱。
第 4 步(选做):加一条"心跳"
这一步留给你自己决定要不要做。 我讲讲思路。
现在的问题是:报警器只知道"有情况",不知道探测器还在不在。万一探测器板没电了、被撞掉了、掉线了——报警器这边一片安静,而"安静"跟"一切正常"长得一模一样。
解决思路很朴素:让探测器每隔十秒发一条"我还活着"。 在 loop() 里加:
if (millis() - lastBeat > 10000) { // 每 10 秒一次
lastBeat = millis();
uint8_t data = 0; // 0 = 心跳,我还在
esp_now_send(receiverMAC, &data, sizeof(data));
}报警器那边,onReceive 里多一个分支:收到 0 就只闪一下灯、不响蜂鸣器;收到 1 才报警。顺便记住最后一次心跳的时间,超过 30 秒没心跳就说明探测器掉线了——这个"掉线提醒"怎么提示,也留给你想。
看到没有,
data这个字节开始承载"含义"了。 第 23 课我们用字符串on/off,这里用数字1/0——本质是一回事:你和板子事先约好的一门暗号。
六、造物:冰棒棍外壳
这个课题跟别的课题不一样的地方:你要做两个东西,而且它俩得长得不一样。
为什么?因为你一眼就得看出来哪个是哪个。 摆在一起分不清、或者拿错了烧错程序,是两块板子项目最经典的翻车方式。
探测器:一个能揣兜里的小盒子
目标:小、轻、能拿着走。 因为它是要放在"事发现场"的。
- 底板:剪一块 5cm × 7cm 的纸皮。
- 四面墙:冰棒棍标准长度大概 11cm 出头,要剪。剪两根 5cm 的当前后墙,两根 7cm 的当左右墙。
剪冰棒棍:用剪刀夹住要剪的位置,另一只手离远点,用力"咔嚓"一下。会崩小木屑,别对着脸剪,也别对着别人的脸。
- 粘墙:四面墙立着粘在底板四条边上,热熔胶沿着棍子和底板的接缝挤一条。先粘两条相对的,等胶硬了(十几秒)再粘另外两条——四条一起粘会歪。
- 顶盖:剪一块 5cm × 7cm 的纸皮当盖子,先别粘死,用橡皮筋箍住就行。以后换线、重烧程序还得打开。
- 按钮:在盖子上戳一个洞,洞要比按钮那个小帽子略小一点点,让按钮从里面顶出来卡住,四周再用热熔胶点两下。先戳小洞,不够再慢慢扩——戳大了按钮就掉进去了。
- 出线口:侧面留一条缝给 USB 线。
- 里面:板子用一小块双面胶或者一点热熔胶固定在底板上,别糊到按钮的引脚上。
最后把按钮那根线理好。 记住这句话——本课那个坑就在这儿。
报警器:一个能立在桌上的牌子
目标:响、亮、看得见。 因为它是要放在你能注意到的地方的。
- 底座:剪一块 6cm × 9cm 的纸皮。
- 立板:两根 9cm 的冰棒棍,并排粘成一块小"板"(两根之间留一两毫米,不用紧贴)。
- 立起来:立板斜着(大约 75°,往后仰一点)粘在底座上。先别急着固定,把板子贴上去比一比角度,觉得正好了再挤胶。
- 加个斜撑:在立板背面粘一根短冰棒棍当支撑,一头顶住立板、一头粘在底座后沿。不然它会往后倒。
- 板子:热熔胶点在板子四个角,粘到立板正面。别糊到元件上,别糊住天线那一端(C3 的天线是板子边缘那段弯弯曲曲的铜箔,第 20 课讲过)。
- LED:粘在立板最上面,露在外面、朝前——它得能被看见。
- 蜂鸣器:粘在 LED 下面。
⚠ 蜂鸣器那个发声孔,绝对不能糊住。
蜂鸣器顶上有个出声的地方。你要是把热熔胶挤上去,它就不响了——或者变成一声很小的"嗒"。 胶只点背面和侧面,出声的那一面朝外、留空。
这个坑非常真实:粘完发现声音不对,你会以为是程序问题、是模块坏了,查半天。其实是你亲手把它捂住了。
最后
两个都做完,插上电再测一遍。 按下探测器,看报警器响不响。
这一步别省。装壳之前是好的、装完就坏,是硬件课的日常。为什么?下一节就是答案。
七、不响?按这个顺序查(本课的坑在这节)
这个课题我埋了两个坑,一个在硬件上,一个在软件上。都是两块板子项目里的经典翻车方式。
第一步:先"对半砍"——看探测器板的串口
按下按钮,盯着探测器板的串口。 有没有打印 → 已发出:1?
这一句话就把问题砍成两半了:一半是"探测器没发",一半是"报警器没收到"。这两半的修法完全不同,别混着查。
岔路 A:探测器串口毫无反应 ← 本课埋的坑在这
先把无线、把报警器板、把 MAC 地址全部从脑子里删掉。 现在的问题百分之百在探测器这一块板子上:按钮、三根线、一行代码。
① 先排除代码和按钮的"方向"。
你的代码写的是 if (digitalRead(BTN_PIN) == LOW)。万一你手上这块模块是"按下为 HIGH"呢? 那不是坏了,是你猜的方向错了。
改代码试一下:把 == LOW 改成 == HIGH,烧一遍,再按。变了 → 就是方向问题,不是故障。
② 方向没错,那就上万用表。直流电压档(标着 V 后面一条直线那个)。黑表笔搭在板子的 GND 排针上,红表笔搭在按钮模块的 OUT 针脚上。
然后按下去、松开、再按下去,盯着表看。
| 你看到什么 | 说明什么 |
|---|---|
| 松开 3.3V、按下 0V(或者反过来) | 按钮模块是好的——它已经把"按下了"变成电压变化了。往下走 ③ |
| 一直不动,就是个死数 | 按钮模块本身的问题(或者它的 VCC/GND 没接好)。先量一下模块 VCC 对 GND 是不是 3.3V |
| 数字乱跳、不稳定 | 接触不良,检查插头插到底没有 |
这一步很关键,因为它告诉你一件事:按钮没坏。
③ 现在做这个课题里最重要的一次测量——把表笔从"模块的脚"挪到"板子的脚"上。
红表笔从按钮模块的 OUT 针脚,挪到板子的 GPIO4 排针上。黑表笔还搭 GND。同样的动作:松开、按下。
| 你看到什么 | 说明什么 |
|---|---|
| 电压跟着变 | 信号进了板子。那问题在代码(BTN_PIN 写的还是不是 4?) |
| 一点不变,一直是个死数 | 信号到了线的一头,没到另一头。 问题就在这根线,或者它插的地方。往下走 ④ |
④ 顺着那根线,从模块的 OUT 脚一路捋到板子上,看看它另一头到底插在哪儿。
如果你看到它插在 GPIO3 上——恭喜,你抓到了。
根因
装盒的时候,那根线被拽了一下,插头从 GPIO4 滑到了隔壁一格,插在了 GPIO3 上。
它插着,不掉、不晃,肉眼看完全正常。 你量它,它也不短路不断路——它只是插错了地方。
这就是我在这个课题里故意留的坑。 我为什么挑它?因为它演的是两块板子项目里最典型的那种故障:你什么都对,就是差一格。
而且它把万用表真正的用法演给你看了:
"按钮的
OUT脚有电压变化"和"板子的GPIO4脚没有电压变化"——这两个事实单独看,都没什么用。只有分别在两个点上量一次、放在一起对比,你才知道"信号是在这一段路上丢的"。
光看现象(按了没反应),你只能猜:可能是按钮坏了、可能是线断了、可能是代码错了、可能是无线不通……四个方向,你总得挑一个下注。
万用表不是用来"测有没有电"的,它是用来把一段路切成几小段、然后一段一段排掉的。
⑤ 拔下来,插回 GPIO4。 串口立刻开始刷 → 已发出:1。
顺手做件事:拿一小段胶带,把那三个插头在板子上轻轻贴一下(别贴到排针上,贴在塑料壳上),防止它再滑。装壳之后的线,比你想的更容易被拉走位。
岔路 B:探测器在刷"已发出",报警器没动静
这一半是软件和无线电的事了。(注意:这里已经不是万用表能解决的范围了,别拿表去量无线电。)
① 先看报警器板的串口。它开机时打印的是哪一句?
- 打印
我是报警器,我的 MAC:...→ 对的,这块烧的是接收程序 - 打印
我是探测器,我的 MAC:...→ 你烧混了。 两块板子烧成了同一个程序——这就是本课的第二个坑 - 打印
ESP-NOW 初始化失败→ 是初始化的问题,跟 MAC 无关
为什么"烧混了"这么难发现?
因为两块板子的串口看上去都很正常——都在打印、都在"就绪",一点报错都没有。你不知道"正常"长什么样,所以"都正常"和"都正常但没人收"在你眼里一模一样。
所以我在两份程序里都加了一句开机打印。这就是你的"身份牌"——一眼看出这块板子现在是谁。这个技巧你以后做任何多设备项目都用得上。
② 报警器烧对了,那一个字符一个字符核对 MAC 地址。
探测器代码里那个数组,写的是报警器板的 MAC:
uint8_t receiverMAC[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};照着你纸上抄的顺序,一位一位对。 少一位、错一位、0x 漏了——都不报错,就是不通。
这是 ESP-NOW 最常见的失败原因,没有之一。 这一步花你三分钟,比后面瞎试半小时值。
③ 两块板子都没连路由器吧?
第 24 课讲过:ESP-NOW 和 WiFi 用同一个无线电,得在同一个信道上。一块连了路由器、另一块没连,它俩可能根本不在一个频道上。刚才的代码里我们只 WiFi.mode(WIFI_STA)、没调 WiFi.begin(),就是故意的。
④ 断电量来一次。 两块板子同时拔掉、等五秒、插回去。听起来很蠢,但"板子没复位"这种问题真的存在。⑤ 最后才怀疑代码,改一个地方测一次——别一口气改五处。
自测
答案与解析
两块板子的项目,第一步永远是"对半砍"——先确定问题在"发"这一半还是"收"这一半。探测器串口有 → 已发出,说明发这半边是好的,往报警器和无线查;没有,说明问题在探测器这块板子上。要是一上来就去拆报警器的线,你就是在同时怀疑两个设备加一段无线电——三个未知数,没法解。
OUT 脚,按下时电压能从 3.3V 变到 0V;再量板子的 GPIO4 排针,电压一点不变。这说明什么?答案与解析
这两次测量的价值就在于"对比"。 OUT 脚会变,说明模块把"按下了"成功地变成了电压变化;GPIO4 不变,说明信号没走到板子上。两次测量合起来,范围就从"整块板子"缩小到"两个点之间的那一小段"。 接下来顺着线捋一眼,多半是插头没插到底、或者插到隔壁针脚上了。注意:单看任何一次测量都得不到这个结论——这就是万用表真正的用法。
答案与解析
发送方要做的是 esp_now_add_peer(把对方存成联系人),接收方要做的是 esp_now_register_recv_cb(收到了就叫我)——这是两段不同的代码,一份程序干不了两件事。 两块都烧成发送方,现象是两块串口都在刷"我发了"、没人收,而且看起来一切正常,特别容易卡住。至于 MAC 地址,那是发送方要填的,跟"要不要烧同一份程序"没关系。
答题要点
答题要点应该包含:① 第 35 课依赖一整套外部设施——路由器、互联网、巴法云服务器、账号和私钥,任何一环挂了就全完蛋;② 本课什么都不依赖——两块板子直接对话,断电重来一遍照样能用;③ 代价:ESP-NOW 距离短(隔着墙更短)、只能点对点、不能跨城市;④ 场景对应:要"人在外地控制家里的东西"必须走第 35 课那条路(你需要一条能通到世界任何角落的路);而"山里、地下车库、大棚"这种没有网络的常态环境里,本课才是唯一可行的方案;⑤ 能说出"很多实际场景里没有网络才是常态"这个判断就更好了。
拓展附近要是有别人的 ESP-NOW 设备也在发消息,我的板子会收到吗?
这个问题课上不讲,留给你自己找答案——**问 AI 是最好的办法**。
提示:搜"ESP-NOW 加密 peer-to-peer"、"ESP-NOW 数据帧 抓包"。想一想:今天我们的代码里写了 peer.encrypt = false——为什么不加密也能跑? 如果把 encrypt 打开,是不是别人就收不到了?
拓展探测器放在野外,用电池供电,能撑几天?
这个问题课上不讲,留给你自己找答案——**问 AI 是最好的办法**。
提示:搜"ESP32 deep sleep 功耗"、"ESP-NOW 唤醒 低功耗"。想一想:一直醒着听和睡一会儿醒一下,耗电能差多少倍?如果改成"每 10 秒醒一次、发完就睡",同样的电池能多用多久?
本节你要动手做的事
- [ ] 先确认你有两块板子。没有的话,这节课可以跳过(真的不影响最后一课)
- [ ] 两块板子各烧一遍"读 MAC"的程序,把两个 MAC 都抄在纸上——这一步不能跳
- [ ] 探测器板先自己测通:只连按钮,串口里那个数字会跟着按动变化
- [ ] 报警器板先自己响一次:不写无线,直接让它亮两秒、响两秒
- [ ] 把报警器板的 MAC 填进探测器板的代码里,一个字符一个字符核对
- [ ] 烧两份不同的程序,两块板子的串口里能看到各自的"身份牌"
- [ ] 做两个外壳:探测器是小盒子(按钮从盖子上顶出来),报警器是立牌(蜂鸣器的出声孔千万别糊住)
- [ ] 装完再测一遍:按下按钮,看还响不响
- [ ] 故意把
OUT那根线拔下来、插到隔壁的GPIO3上,跑一遍——亲手经历一次"按了没反应",然后用万用表把它抓出来 - [ ] (选做)加上心跳:让探测器每 10 秒报一次"我还活着"
这个课题做完,你手里有两个东西:一个揣兜里的探测器,一个立在桌上的报警器。
中间什么都没有。 没有路由器、没有服务器、没有账号、没有密码。拔掉一切,它们照样说话。
这件事的意义,比它看起来大。
你前面学的所有联网的东西——WiFi、HTTP、MQTT——全都有一个前提:得有个"基础设施"在那儿。 有网、有服务器、有别人替你维护的机器。这些东西平时当然都有,但它们不是永远都有。
而你现在会做一种"没有基础设施也能用"的设备了。 世界上很多真正在野外、在地下、在海上干活的设备,就是这么工作的。
说句实话,这个课题比上一个容易踩坑。 两块板子、两份程序、一串 MAC 地址,任何一处差一点点,现象都是"没反应"。你要是今天卡了两个小时,那太正常了——我见过的每一个人都卡过。
但你最后把它弄响了。而且你知道它为什么响。
下一节是最后一课,也是整门课的结课作品:我们要盖一座纸皮房子,把温湿度、光线、距离、屏幕、舵机全塞进去,让它自己看、自己想、自己做。
前面三十六节课学的每一个零件,那一课都要用上。我们把它攒成一个完整的东西。