联网与通信

第 20 课:WiFi 联网——让板子上网

板子第一次跟外面的世界说话,以及连不上时该按什么顺序查

我是吴老师。从这一课起,事情开始不一样了。

前面十九节课你做出来的那些东西——点灯、读光敏、转舵机、显示字——我得跟你说句实话:一块几十块钱的 Arduino 也能做。 那些是"电子入门"的通用内容,不挑板子。

而这块板子真正的本事,是它身体里藏着的那根天线。 它能连上你家的 WiFi,能跑到几百公里外的服务器上取一个数回来,能自己开热点让你手机连上,能跟另一块板子隔空说话。这些,是几十块的 Arduino 做不到的。

所以从今天起,你学的不是"又一个模块",是一门新的本事。

一、6 节课,我给 15 课时

翻一下大纲你会发现:整个"模块熟悉"单元 16 节课才 10 课时,而"联网与通信"只有 6 节课,却给了 15 课时。

为什么?因为联网的坑不在代码,在网络环境。 我给你说清楚这两种故障的区别:

接线出错 联网出错
你能看到什么 灯不亮、模块发烫、屏幕全黑 "没反应"
问题可能在哪 那几根线 WiFi 名字、密码、频段、路由器设置、信号强度、对方服务器
排查难度 用万用表量三下就定位 看不见摸不着,全靠推理
有标准顺序吗 有:电 → 信号 → 代码 有,就是这一课要教你的

关键在最后一行。 接错一根线,你能看见"不亮"这个现象,还能顺着线一路量过去;连不上网,你只能看见"没反应"——板子安安静静跑着代码,什么都没发生,你连从哪开始查都不知道。

所以这节课的重点不是代码。代码只有十几行,五分钟抄完。重点是那套排查顺序——2 课时里,一大半是给它的。

二、联网到底发生了什么

这一节你必须看懂。这个原理不懂,后面全是照抄。

你在家用手机刷视频,你觉得发生了什么?你可能觉得"手机连上 WiFi 就能上网了"——这句话等于什么都没说。 咱们拆开看。

数据从 ESP32-C3 板子出发,经家里的路由器穿过互联网到达几百公里外的服务器,处理完再原路返回

第 1 步:板子和路由器,组成一个小圈子

家里那个路由器,别把它当"一个盒子",把它当成一个小区的大门。 你的手机、电脑、电视、还有这块板子,都是住在这个小区里的住户。

这个小区有个正式名字,叫局域网注意"局"这个字——局部的、小范围的,就是你自己家这一摊。 小区里的事外人管不着也看不见:你在家喊一嗓子,是隔壁邻居听见,不是马路对面的人听见。

第 2 步:进门要报名字和暗号

板子想进来,得先敲门。名字就是你在手机 WiFi 列表里看到的那些,正式叫法是 SSID,你就理解成"网络的名字"。暗号就是 WiFi 密码。

板子把这两个报给路由器,路由器核对:名字对得上吗?没这个名字,它直接不理你;密码对得上吗?错了也不理你。两个都对,它才放你进来。

记住这一步。它是后面排查顺序里的第 2、第 3 条,我们会回来说它。

第 3 步:发一个门牌号

进来了总得有个地址,不然外面寄给你的东西往哪儿送?路由器会给你分配一个 IP 地址

IP 地址就是门牌号,长这样:192.168.1.123,四个数字用点隔开。两个特点你记住:

  1. 它是路由器临时分配的——每次板子重启可能都不一样。今天 192.168.1.123,明天可能 192.168.1.108
  2. 它只在这个小区里有效——你家的门牌号拿到别的城市去问,没人知道在哪。

所以:板子能打印出自己的 IP,才算真的进了这个网。 打出来是 0.0.0.0,那就是没连上,别往下查了,先回头查名字和密码。

第 4 步:出门,穿过互联网

现在板子要访问一台几百公里外的服务器,这一段就不归你家路由器管了。

打个比方:你要给外地的亲戚寄一箱书。你不会把整箱书塞进一个包裹硬寄——太重了,路上哪个环节卡住都完蛋。你会拆成几十个小包裹,每个贴张纸条写"第几件,一共几件",它们可能走不同的路线,甚至不按顺序到,到了那边亲戚再按纸条拼回一箱书。

互联网就是这么干的。 你要发出去的数据,会被拆成一个个小包(正式叫法是数据包),各走各的路,到了对面再拼起来。这也是为什么偶尔会"卡一下"——某个小包走了远路,或者丢了一个得重发。

第 5 步:服务器答完,原路跑回来

服务器收到请求、处理完,把结果发回来。走的还是这套流程,方向反过来。整个来回,通常不到一秒。

你刷一下手机、点开个视频,背后已经跑了几百上千趟这个流程了。

停下来想一件事:刚才这一整套,你的板子要在几百毫秒里干完——报名字、交密码、拿门牌号、把数据拆包、发出去、收回来、拼起来。而这一切,发生在一块指甲盖那么大的芯片上。

三、动手第一步:先让板子"看见"周围的网

别急着连。第一件事是让板子把周围能扫到的 WiFi 全列出来。 两个原因,都很实在:第一,它证明板子的 WiFi 模块是好的——能扫到网,说明天线和芯片都没问题,后面出问题就不用怀疑硬件了;第二,它能告诉你你家 WiFi 名字的"真实拼写",这个太重要了,一会儿你就知道为什么。

C++
#include <WiFi.h>

void setup() {
  Serial.begin(115200);
  delay(1500);                  // 等串口准备好,不然开头几句会丢

  WiFi.mode(WIFI_STA);          // 当"客人",去连别人的网

  int n = WiFi.scanNetworks();  // 扫一遍,看周围有谁
  Serial.print("扫到 ");
  Serial.print(n);
  Serial.println(" 个网络:");

  for (int i = 0; i < n; i++) {
    Serial.print(i + 1);
    Serial.print(". ");
    Serial.print(WiFi.SSID(i));     // 网络名字
    Serial.print("    信号 ");
    Serial.print(WiFi.RSSI(i));     // 信号强度
    Serial.println(" dBm");
  }
}

void loop() {
}

烧进去,打开串口监视器。你会看到类似这样一串:

纯文本
扫到 7 个网络:
1. ChinaNet-A3f2    信号 -52 dBm
2. TP-LINK_5F88     信号 -71 dBm
3. CMCC-8x9k        信号 -63 dBm

看到没有?你的板子第一次"看见"了外面的世界。 有两件事要留意。第一,RSSI 那个数是负的,越接近 0 越强:

RSSI 大概是什么情况
-40 ~ -60 很好,路由器就在附近
-60 ~ -75 一般,隔了一堵墙
-80 以下 很弱了,能扫到但可能连不上

第二,也是最重要的:找到你家 WiFi 的名字,把它原样抄下来。别手打——要在串口里选中、复制、粘贴。 为什么这么强调?往下看。

四、动手第二步:连上去,把该打印的都打印出来

C++
#include <WiFi.h>

const char* WIFI_NAME = "把这里换成你家 WiFi 的名字";
const char* WIFI_PASS = "把这里换成你家 WiFi 的密码";

void setup() {
  Serial.begin(115200);
  delay(1500);

  WiFi.mode(WIFI_STA);

  Serial.print("准备连的是:");
  Serial.println(WIFI_NAME);        // 打出来,确认自己没写错

  WiFi.begin(WIFI_NAME, WIFI_PASS);

  int t = 0;                        // 等它连上,最多等 20 秒
  while (WiFi.status() != WL_CONNECTED && t < 40) {
    delay(500);
    Serial.print(".");
    t++;
  }
  Serial.println();

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("连上了!");
    Serial.print("IP 地址:");
    Serial.println(WiFi.localIP());   // 板子在网里的门牌号
    Serial.print("信号强度:");
    Serial.print(WiFi.RSSI());
    Serial.println(" dBm");
  } else {
    Serial.print("没连上。状态码 = ");
    Serial.println(WiFi.status());    // 这个数字是排查的关键线索
  }
}

void loop() {
}

为什么每一句都要打印

第 7 课我讲过一句口诀:先打印,再判断。这句话在联网课里的分量,比前面任何一课都重。

因为联网是"看不见"的。接错一根线,你至少能看见灯不亮;联网失败的时候,板子外表上什么变化都没有——灯不闪,屏幕不黑,它就在那儿安安静静地跑着。你唯一的信息来源,就是它嘴里说出来的话。 所以这段代码里我把能打的都打出来了:要连的名字、连接过程的点、状态码、IP 地址、信号强度。这五个东西,就是你后面破案的全部线索。

读懂状态码

打印出来的数字 大概是什么意思
1 找不到这个名字的网——名字写错了,或者离太远扫不到
3 连上了WL_CONNECTED 就是 3)
4 连接失败——最常见的原因是密码错
6 断开了

不同版本的库数字可能有点出入,以你实际打印出来的为准。但 3 是连上、1 是找不到网、4 是密码不对,这几个基本通行。

看到 1 和看到 4,是完全不同的两个方向:看到 1 去查名字和信号,看到 4 去查密码。这就是"先打印再判断"的价值——它直接告诉你该往哪个方向查。

五、连不上?按这个顺序查

这一节是本节课的重头戏,我建议你抄在笔记本上。 顺序不是我随便排的,是从"最容易查、最常见"排到"最难查、最少见"。按这个走,你每一步都在排除一种可能——这就是第 5 课那套"电 → 信号 → 代码"的思路,换到网络上来。

第 1 步:先看板子说了什么

什么都别改,先打开串口监视器看。 一个字都不打印 → 那不是网络问题,是程序没跑起来(或者串口没打开),回第 7 课。打印了一堆点然后没连上 → 好,往下走。

第 2 步:WiFi 名字对不对

这是所有问题里最常见的一个。 名字这东西看着简单,坑特别多:大小写ChinaNetchinanet 是两个完全不同的网络,差一个字母都不行)、空格(名字里有个空格,你手打时漏了就连不上)、中文和表情(有的路由器名字是中文的,甚至是表情符号,你手打几乎不可能打对)、全角半角HomeHome 看着差不多,其实是两串完全不同的字符)。

所以正确做法只有一个:从串口扫描的结果里复制粘贴,别手打。 如果名字里有中文、空格、奇怪符号,我建议去路由器后台把它改成纯英文的短名字——这不是偷懒,是省掉以后无数次的麻烦。

第 3 步:是 2.4G 还是 5G

这一条特别重要,而且很多教程都不提:ESP32-C3 只支持 2.4GHz 的 WiFi,不支持 5GHz。 现在很多路由器会同时开两个网络,名字往往是这样:MyHome(2.4GHz,板子能连)和 MyHome_5G(5GHz,板子连不上)。

最坑的地方在于:5G 那个网你的手机能连、电脑能连,只有板子连不上。所以你很容易觉得"网没问题啊,我手机好好的"——问题恰恰在这儿。

怎么知道哪个是 2.4G 的?看第 1 步的扫描结果。板子扫不到的那个名字,就是 5G 的——它的天线根本收不到 5GHz 的信号。扫得到,才连得上。

第 4 步:密码对不对

状态码是 4,八成是密码。坑跟名字差不多:大小写、空格、特殊符号。还有两个经典错误:数字 0 和字母 O数字 1 和小写字母 l——这俩在某些字体下几乎长得一模一样,从路由器贴纸上抄密码特别容易中招。最保险的办法:先把密码填到手机里连一次,能连上,说明你抄的是对的,再填进代码。

第 5 步:板子在不在信号范围内

看打印出来的 RSSI-50 左右就在路由器旁边,没问题;-80 以下就太弱了。做一次最简单的实验:把板子拿到路由器旁边(一米以内),再跑一遍。挪近了就连上,那问题就是信号,不是代码。 这时候你要考虑:中间隔了几堵墙(承重墙的杀伤力很大)、板子是不是放在金属盒子里或贴在金属桌面上(金属会挡住天线)、附近有没有微波炉这类干扰源。

顺便说个真实的事:C3 的天线是印在板子上的,就在板子边缘那一小段弯弯曲曲的铜箔。你手捏着那个位置,或者拿东西盖住它,信号都会明显变差。调试的时候别用手按着板子。

第 6 步:路由器有没有限制新设备

前面都排除了,就该怀疑路由器了。登录路由器后台(地址一般写在路由器背面,常见的是 192.168.1.1tplogin.cn),看看有没有:MAC 地址白名单(只有名单里的设备能连)、黑名单(板子被当成陌生设备拦了)、连接数满了(便宜的路由器一般只能带十几台,家里手机电脑电视加起来可能真满了)。还有一个容易忽略的:访客网络——有些访客网络开了"设备隔离",能连上但互相看不见,后面 ping 的测试会失败。

如果你家的网是学校的、公司的、别人家的——那你可能没有后台权限。这种情况直接跳到下一步。

第 7 步:到底拿到了什么 IP

最后看 WiFi.localIP() 打印出来的东西:192.168.x.x10.x.x.x → 正常,拿到门牌号了;0.0.0.0没连上,回头从第 2 步重来。为什么把它放最后?因为前面六步是"原因",这一步是"结果"。IP 拿到没有,是你判断成没成的最终标准。

卡住的时候,我最后给你一个万能备用方案:用手机开热点。

家里路由器的密码你可能拿不到、后台你可能进不去、5G/2.4G 你可能分不清——手机热点这些麻烦全都没有。 安卓在"个人热点"设置里一般能选频段,选 2.4GHz;iPhone 在"个人热点"里打开**"最大兼容性"**。热点名字也设成纯英文的。

这一步能把"路由器问题"整个排除掉:如果连手机热点能连上,说明你的代码是对的,问题在路由器那边。

六、动手第三步:从别的设备 ping 一下板子

连上之后,验证一下板子是不是真的"在网里"。ping 是个特别朴素的命令,意思是:"喂,你在吗?" 板子打印出来的 IP 假设是 192.168.1.123,你在同一 WiFi 下的电脑上敲:

Shell
ping 192.168.1.123

有回应,说明这台设备能直接找到你的板子。

但我提前告诉你:ping 不通,不一定是你错了。

很多家用路由器默认开了"AP 隔离"(也叫客户端隔离)——同一个 WiFi 下的设备互相看不见,只能各自上网。这个功能在咖啡厅、学校的公共 WiFi 里是标配(不然你就能访问别人的电脑了),但有些家用路由器也默认开着。

所以 ping 不通的时候别急着怀疑板子。 先看串口——它还好好的连着、打印正常,那就说明它没问题,是路由器不让你们互相看见。

这个思路你要适应:网络里很多"失败",不是你的设备错了,是中间的规则不允许。 分辨这两者,是联网调试的基本功。

自测

单选题代码里 WiFi.begin() 之后马上打印 WiFi.localIP(),出来是 0.0.0.0。最可能的原因是什么?
单选题板子连不上,第一步应该做什么?
单选题你家 WiFi 有两个名字:MyHomeMyHome_5G。板子连 MyHome_5G 一直失败,状态码是 1。最可能的原因是什么?
问答题板子连不上 WiFi,你会按什么顺序排查?说清楚每一步在排除什么可能。
拓展数据在那么多路由器之间转来转去,怎么就能找到正确的那台服务器?

这个问题课上不讲,留给你自己找答案——**问 AI 是最好的办法**。

提示:搜"DNS 域名解析"、"路由表 下一跳"、"traceroute 原理"。想一想:你输入的是一个网址,可路由器只认 IP 地址——中间是谁做了翻译?

拓展手机和板子连着同一个 WiFi,为什么经常会 ping 不通?

这个问题课上不讲,留给你自己找答案——**问 AI 是最好的办法**。

提示:搜"AP 隔离 客户端隔离"、"路由器 访客网络 隔离"。想一想:如果同一个 WiFi 下所有设备都能互相看见,那咖啡厅的免费 WiFi 会出什么问题?

本节你要动手做的事

  • [ ] 扫一遍周围的网:跑第一段代码,看板子能扫到几个,找你家的那个名字
  • [ ] 复制而不是手打:把你家 WiFi 的名字从串口里复制出来,记住它的准确拼写
  • [ ] 连上去并把该打的都打出来:名字、状态码、IP 地址、RSSI——四个都打出来
  • [ ] 故意写错一次密码:改错一个字符,看状态码变成几。记住这个数,以后能一眼认出来
  • [ ] 挪远一点再试:把板子拿到离路由器远的地方,看 RSSI 掉到多少、还连不连得上
  • [ ] 用电脑 ping 一次板子:通不通都记下来。不通也别慌,看看是不是路由器开了 AP 隔离
  • [ ] 试一次手机热点:手机开个 2.4GHz 热点,让板子连上去。这是你以后的万能备用网络

这节课你一行硬件都没接。

没有线、没有模块、没有要用万用表量的地方——你全靠看打印出来的文字,和一整套推理。

这其实是件很难的事。因为人习惯了"看得见才信",而联网调试要求你相信一些看不见的东西:电波、地址、数据包。你能把这些看不见的东西在脑子里画出来,你就跨过了一道很大的坎。

下一节,我们把方向反过来。这一节是板子去连别人的网,下一节是板子自己开一个网——你的手机会连上它,浏览器里会跳出板子自己吐出来的网页,点一下按钮,灯就亮了。

那一节不需要路由器、不需要服务器、不需要第二块板子、不需要注册任何账号。只有板子和你。