实战课题

第 36 课:无线报警器

两块板子、一根线都不连,隔着一间屋子把"有情况"喊出来

这节课需要两块板子。 你只有一块的话可以跳过——它不影响最后一课。

我是吴老师。这是三个 C 档课题里的第二个,它代表的方向是"无线通信"。

先想一件事。上一节课,你人在教室、灯在家里,中间隔着互联网、隔着服务器、隔着路由器——你花了整整一节课,才把那条路走通。

这个课题反过来:什么都不用。

没有路由器、没有服务器、没有互联网、没有账号、没有密码。两块巴掌大的板子,隔着一间屋子,就这么把话说了。

而且它说得很"硬"——你把它俩拿到山里、拿到地下室、拿到任何一个手机没信号的地方,它照样能用。

一、这个课题的真正价值:不依赖

第 24 课我讲过一段话,这里再讲一遍,因为这个课题就是它的实物版

我们在教室里用 WiFi 用得太顺手了,容易产生一种错觉:觉得哪儿都有网。

但你真去干点活就会发现完全不是这样。 山里、地里、渔船上——那儿根本没有 WiFi;地下车库、老房子储藏间、电梯井——信号进不去;大棚、工地、野外监测点——拉网线不现实

这些地方,"没有网络"才是常态。这时候,"不依赖网络的通信"就不是炫技,是刚需

对比图:上网课要经过路由器和服务器绕一大圈,ESP-NOW 是两块板子靠 MAC 地址直接对话

看这张图。上面那条路,是上一节课你走的路——板 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 接按钮,所以报警器这边沿用原来的位置更清爽。)

两块板子都避开了 GPIO2GPIO8GPIO9(strapping 脚,第 4 课那张表)。

接线之前先拔 USB。 这条规矩从第 4 课讲到这儿。

五、动手:分三步,前两步是"分开测"

这个课题最容易出错的地方,是两块板子。

所以做法跟前面所有课都不一样:先把两块板子当成两个独立的东西,各自测通,再把它俩连起来。

为什么这么干? 因为一旦连起来不工作,你面对的是两个可能坏掉的东西,外加一段看不见的无线电。三个未知数,你没法解。

但如果你先确认了"探测器这边是好的"和"报警器这边是好的",那出问题时就只剩一段无线电——未知数从三个变成一个。

这就是第 23 课那个"对半砍"的思路,在这个课题里它升级了:这次你砍的不是一条链路的两半,是两个设备。

第 1 步:两块板子各读一次 MAC

这一步千万别跳。 程序就是第 24 课那个,核心还是这两行:

C++
  WiFi.mode(WIFI_STA);          // 先切到"上网模式",再读 MAC
  Serial.println(WiFi.macAddress());

板子 A 烧一遍,抄下来。换板子 B,同样的程序再烧一遍,抄下来。 拿张纸写清楚(别只存在脑子里,这个课题你要来回翻它):

MAC 地址
探测器板 __:__:__:__:__:__
报警器板 __:__:__:__:__:__

读出来是 00:00:00:00:00:00 别慌,不是板子坏了——先调用 WiFi.mode(WIFI_STA) 再读。

第 2 步:两块板子各自先测通

先不写无线。 探测器板把按钮状态打印出来,报警器板自己响两下——两块板子各测各的,谁也别管谁。

探测器板:

C++
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_PIN3)和 BUZZER_PIN5)设成 OUTPUTloop() 里就这样来回倒:

C++
  digitalWrite(LED_PIN, HIGH);
  digitalWrite(BUZZER_PIN, HIGH);
  delay(2000);
  digitalWrite(LED_PIN, LOW);
  digitalWrite(BUZZER_PIN, LOW);
  delay(2000);

灯亮两秒、蜂鸣器响两秒。 看到这个现象,说明报警器这半边的硬件全是好的——线没接错、脚号没写错、模块没坏。

现在你手里有两个各自能跑的东西了。 未知数只剩一个:中间那段无线电。

第 3 步:合起来——一个发,一个收

现在最关键的一句话,我加粗说:

两块板子要烧不同的程序。

这是新手最容易犯的错,而且错得毫无痕迹。

你很自然就会想:"两块板子嘛,程序当然一样。"——然后两块都在发,没人收。 现象是两块板子的串口都在刷"我发了",对面一点动静都没有。你会以为是无线坏了,其实是你的脑子里,这两块板子还是同一块。

探测器板(发):

C++
#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);                         // 别连着发,一次就够
  }
}

报警器板(收):

C++
#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() 里加:

C++
  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——本质是一回事:你和板子事先约好的一门暗号。

六、造物:冰棒棍外壳

这个课题跟别的课题不一样的地方:你要做两个东西,而且它俩得长得不一样。

为什么?因为你一眼就得看出来哪个是哪个。 摆在一起分不清、或者拿错了烧错程序,是两块板子项目最经典的翻车方式。

两块板子两个角色:左边是装在纸皮小盒里的探测器板,负责发送;右边是立在底座上的报警器板,装着 LED 和蜂鸣器,负责接收;中间靠 ESP-NOW 无线电直连,不用路由器、不用服务器、不用互联网

探测器:一个能揣兜里的小盒子

目标:小、轻、能拿着走。 因为它是要放在"事发现场"的。

  1. 底板:剪一块 5cm × 7cm 的纸皮。
  2. 四面墙:冰棒棍标准长度大概 11cm 出头,要剪。剪两根 5cm 的当前后墙,两根 7cm 的当左右墙。

    剪冰棒棍:用剪刀夹住要剪的位置,另一只手离远点,用力"咔嚓"一下。会崩小木屑,别对着脸剪,也别对着别人的脸。

  3. 粘墙:四面墙立着粘在底板四条边上,热熔胶沿着棍子和底板的接缝挤一条。先粘两条相对的,等胶硬了(十几秒)再粘另外两条——四条一起粘会歪。
  4. 顶盖:剪一块 5cm × 7cm 的纸皮当盖子,先别粘死,用橡皮筋箍住就行。以后换线、重烧程序还得打开。
  5. 按钮:在盖子上戳一个洞,洞要比按钮那个小帽子略小一点点,让按钮从里面顶出来卡住,四周再用热熔胶点两下。先戳小洞,不够再慢慢扩——戳大了按钮就掉进去了。
  6. 出线口:侧面留一条缝给 USB 线。
  7. 里面:板子用一小块双面胶或者一点热熔胶固定在底板上,别糊到按钮的引脚上

最后把按钮那根线理好。 记住这句话——本课那个坑就在这儿。

报警器:一个能立在桌上的牌子

目标:响、亮、看得见。 因为它是要放在你能注意到的地方的。

  1. 底座:剪一块 6cm × 9cm 的纸皮。
  2. 立板:两根 9cm 的冰棒棍,并排粘成一块小"板"(两根之间留一两毫米,不用紧贴)。
  3. 立起来:立板斜着(大约 75°,往后仰一点)粘在底座上。先别急着固定,把板子贴上去比一比角度,觉得正好了再挤胶。
  4. 加个斜撑:在立板背面粘一根短冰棒棍当支撑,一头顶住立板、一头粘在底座后沿。不然它会往后倒。
  5. 板子:热熔胶点在板子四个角,粘到立板正面。别糊到元件上,别糊住天线那一端(C3 的天线是板子边缘那段弯弯曲曲的铜箔,第 20 课讲过)。
  6. LED:粘在立板最上面,露在外面、朝前——它得能被看见。
  7. 蜂鸣器:粘在 LED 下面。

蜂鸣器那个发声孔,绝对不能糊住。

蜂鸣器顶上有个出声的地方。你要是把热熔胶挤上去,它就不响了——或者变成一声很小的"嗒"。 胶只点背面和侧面,出声的那一面朝外、留空。

这个坑非常真实:粘完发现声音不对,你会以为是程序问题、是模块坏了,查半天。其实是你亲手把它捂住了。

最后

两个都做完,插上电再测一遍。 按下探测器,看报警器响不响。

这一步别省。装壳之前是好的、装完就坏,是硬件课的日常。为什么?下一节就是答案。

七、不响?按这个顺序查(本课的坑在这节

这个课题我埋了两个坑,一个在硬件上,一个在软件上。都是两块板子项目里的经典翻车方式。

第一步:先"对半砍"——看探测器板的串口

按下按钮,盯着探测器板的串口。 有没有打印 → 已发出:1

这一句话就把问题砍成两半了:一半是"探测器没发",一半是"报警器没收到"。这两半的修法完全不同,别混着查。

岔路 A:探测器串口毫无反应 ← 本课埋的坑在这

先把无线、把报警器板、把 MAC 地址全部从脑子里删掉。 现在的问题百分之百在探测器这一块板子上:按钮、三根线、一行代码。

① 先排除代码和按钮的"方向"。

你的代码写的是 if (digitalRead(BTN_PIN) == LOW)万一你手上这块模块是"按下为 HIGH"呢? 那不是坏了,是你猜的方向错了。

改代码试一下:把 == LOW 改成 == HIGH,烧一遍,再按。变了 → 就是方向问题,不是故障。

② 方向没错,那就上万用表。直流电压档(标着 V 后面一条直线那个)。黑表笔搭在板子的 GND 排针上,红表笔搭在按钮模块的 OUT 针脚上。

然后按下去、松开、再按下去,盯着表看。

你看到什么 说明什么
松开 3.3V、按下 0V(或者反过来) 按钮模块是好的——它已经把"按下了"变成电压变化了。往下走 ③
一直不动,就是个死数 按钮模块本身的问题(或者它的 VCC/GND 没接好)。先量一下模块 VCCGND 是不是 3.3V
数字乱跳、不稳定 接触不良,检查插头插到底没有

这一步很关键,因为它告诉你一件事:按钮没坏。

③ 现在做这个课题里最重要的一次测量——把表笔从"模块的脚"挪到"板子的脚"上。

红表笔从按钮模块的 OUT 针脚,挪到板子的 GPIO4 排针上。黑表笔还搭 GND同样的动作:松开、按下。

你看到什么 说明什么
电压跟着变 信号进了板子。那问题在代码(BTN_PIN 写的还是不是 4?)
一点不变,一直是个死数 信号到了线的一头,没到另一头。 问题就在这根线,或者它插的地方。往下走 ④

④ 顺着那根线,从模块的 OUT 脚一路捋到板子上,看看它另一头到底插在哪儿。

如果你看到它插在 GPIO3 上——恭喜,你抓到了。

根因

装盒的时候,那根线被拽了一下,插头从 GPIO4 滑到了隔壁一格,插在了 GPIO3 上。

它插着,不掉、不晃,肉眼看完全正常。 你量它,它也不短路不断路——它只是插错了地方。

这就是我在这个课题里故意留的坑。 我为什么挑它?因为它演的是两块板子项目里最典型的那种故障:你什么都对,就是差一格。

而且它把万用表真正的用法演给你看了:

"按钮的 OUT 脚有电压变化"和"板子的 GPIO4 脚没有电压变化"——这两个事实单独看,都没什么用。

只有分别在两个点上量一次、放在一起对比,你才知道"信号是在这一段路上丢的"。

光看现象(按了没反应),你只能猜:可能是按钮坏了、可能是线断了、可能是代码错了、可能是无线不通……四个方向,你总得挑一个下注。

万用表不是用来"测有没有电"的,它是用来把一段路切成几小段、然后一段一段排掉的。

⑤ 拔下来,插回 GPIO4 串口立刻开始刷 → 已发出:1

顺手做件事:拿一小段胶带,把那三个插头在板子上轻轻贴一下(别贴到排针上,贴在塑料壳上),防止它再滑。装壳之后的线,比你想的更容易被拉走位。

岔路 B:探测器在刷"已发出",报警器没动静

这一半是软件和无线电的事了。注意:这里已经不是万用表能解决的范围了,别拿表去量无线电。

① 先看报警器板的串口。它开机时打印的是哪一句?

  • 打印 我是报警器,我的 MAC:...对的,这块烧的是接收程序
  • 打印 我是探测器,我的 MAC:...你烧混了。 两块板子烧成了同一个程序——这就是本课的第二个坑
  • 打印 ESP-NOW 初始化失败 → 是初始化的问题,跟 MAC 无关

为什么"烧混了"这么难发现?

因为两块板子的串口看上去都很正常——都在打印、都在"就绪",一点报错都没有。你不知道"正常"长什么样,所以"都正常"和"都正常但没人收"在你眼里一模一样。

所以我在两份程序里都加了一句开机打印。这就是你的"身份牌"——一眼看出这块板子现在是谁。这个技巧你以后做任何多设备项目都用得上。

② 报警器烧对了,那一个字符一个字符核对 MAC 地址。

探测器代码里那个数组,写的是报警器板的 MAC:

C++
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 排针,电压一点不变。这说明什么?
单选题为什么两块板子必须烧不同的程序?
问答题第 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 地址,任何一处差一点点,现象都是"没反应"。你要是今天卡了两个小时,那太正常了——我见过的每一个人都卡过。

但你最后把它弄响了。而且你知道它为什么响。

下一节是最后一课,也是整门课的结课作品:我们要盖一座纸皮房子,把温湿度、光线、距离、屏幕、舵机全塞进去,让它自己看、自己想、自己做。

前面三十六节课学的每一个零件,那一课都要用上。我们把它攒成一个完整的东西。