Chapter 11 · Arduino 入门

WiFi 与蓝牙(ESP 版)

换上 ESP32 让作品联网:连 WiFi、上报数据到云、自己当 Web 服务器、用蓝牙遥控。

课程进度92%

关键概念

为什么要用 ESP32/ESP8266
经典 Uno 没有联网能力。ESP8266、ESP32 是乐鑫的 WiFi/蓝牙芯片,自带无线电、主频更高、内存更大,却兼容 Arduino 编程(装对应开发板核心后照样 setup/loop)。想让作品上网、做物联网,直接换 ESP32 最省心。ESP32 还带蓝牙(经典+BLE)。
STA 模式(连入路由器)
Station 模式:ESP 作为一个普通设备,像手机一样连入你家 WiFi 路由器,由路由器分配 IP,从而能上外网、访问云服务。用 WiFi.begin(ssid, pass) 连接,WiFi.status()==WL_CONNECTED 判断是否连上。这是最常用的联网方式。
AP 模式(自建热点)
Access Point 模式:ESP 自己变成一个 WiFi 热点,手机/电脑直接连它(没有路由器也行)。常用于设备初次配网(手机连上后填 WiFi 密码)或做局域网直连控制。用 WiFi.softAP(名, 密码) 开启。也可 STA+AP 双模式并存。
HTTP 客户端 (Client)
ESP 作为"客户端",主动向服务器发请求(如把传感器数据 POST 到云平台、GET 天气 API)。ESP32 用 HTTPClient 库,几行就能发 GET/POST 并拿到响应。这是"设备→云"上报数据的标准方式。
Web 服务器 (Server)
反过来,ESP 也能自己当"服务器",在局域网里开个网页,手机浏览器一访问就能看数据、点按钮控硬件。ESP32 用 WebServer 库注册路由(server.on("/led", handler)),简单的智能家居本地控制无需云即可实现。
API 与 JSON
云平台/网页间传数据多用 JSON 格式(键值对文本,如 {"temp":25.3})。发数据时把读数拼成 JSON 字符串,收数据时用 ArduinoJson 库解析。REST API 靠 URL + HTTP 方法(GET 取、POST 传)约定接口,是物联网上报/下发指令的通用语言。
MQTT(物联网轻量协议)
比 HTTP 更适合物联网的"发布/订阅"协议:设备连到一个 Broker(如 EMQX、Mosquitto),往主题(topic)发消息,订阅了该主题的其他端就收到。省流量、支持海量设备、能双向实时通信。用 PubSubClient 库。上报+远程控制的主流选择。
蓝牙串口 (BluetoothSerial)
ESP32 的经典蓝牙可模拟成串口,手机蓝牙串口 App 连上后像有线串口一样收发文本,常用于近距离遥控(如蓝牙小车)。用 BluetoothSerial 库,SerialBT.begin("名字") 后跟普通 Serial 用法一样。低功耗场景用 BLE(BLEDevice)。
阻塞与看门狗 (Watchdog)
ESP32 后台跑着 WiFi 协议栈,若你的 loop 长时间阻塞(死循环、长 delay),会触发看门狗复位重启。所以联网代码更要用非阻塞写法(第 9 章的 millis),必要时调 yield()delay(1) 把时间片让给系统任务。

连接 WiFi(STA 模式)

联网第一步:连入路由器。连上后串口会打印分配到的 IP:

#include <WiFi.h>   // ESP32;ESP8266 用 <ESP8266WiFi.h>

const char* ssid = "你的WiFi名";
const char* pass = "你的WiFi密码";

void setup() {
  Serial.begin(115200);        // ESP32 常用 115200
  WiFi.begin(ssid, pass);         // 发起连接

  Serial.print("连接中");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");      // 每半秒打个点表示还在连
  }
  Serial.println("\n已连接!");
  Serial.print("IP 地址: ");
  Serial.println(WiFi.localIP());  // 打印分到的 IP
}

void loop() {}
物联网数据流向:设备 → 云 → 手机 ┌─────────┐ WiFi ┌────────┐ Internet ┌────────┐ │ ESP32 │ ────────▶ │ 路由器 │ ─────────▶ │ 云端 │ │ +传感器 │ └────────┘ │ 平台 │ └─────────┘ └───┬────┘ 采集温湿度 │ HTTP/MQTT 上报 手机 App ◀┘ 查看/控制 反向:云下发指令 → ESP32 收到 → 控制继电器/舵机

发 HTTP 请求上报数据

连上 WiFi 后,把传感器读数 POST 到云平台(此处以通用 REST 接口示意):

#include <WiFi.h>
#include <HTTPClient.h>

void uploadData(float temp) {
  if (WiFi.status() != WL_CONNECTED) return;

  HTTPClient http;
  http.begin("http://example.com/api/data");  // 目标 URL
  http.addHeader("Content-Type", "application/json");

  // 拼一个 JSON 请求体
  String body = "{\"temp\":" + String(temp) + "}";
  int code = http.POST(body);          // 发送,返回状态码

  if (code > 0) {
    Serial.print("响应码: ");
    Serial.println(code);           // 200 表示成功
    Serial.println(http.getString()); // 服务器返回内容
  } else {
    Serial.println("上报失败");
  }
  http.end();                          // 释放资源
}
用现成的物联网平台

不想自己搭服务器?可用 Blynk(手机 App 拖拽面板)、ThingSpeak(数据可视化)、巴法云/贝壳物联(国内、支持 MQTT+小爱同学)等平台,提供现成 API 和库,几分钟就能把数据画成曲线或接入语音助手。HTTPS 上报时 ESP32 用 WiFiClientSecure,注意证书或用 setInsecure() 跳过验证(仅测试)。

ESP32 当 Web 服务器:网页控灯

让 ESP 自己开个网页,手机浏览器访问它的 IP 就能开关 LED:

#include <WiFi.h>
#include <WebServer.h>

WebServer server(80);   // 监听 80 端口
const int ledPin = 2;   // ESP32 板载 LED 常在 GPIO2

void handleRoot() {
  // 返回一个带两个按钮的简单网页
  String html = "<h1>ESP32 控制台</h1>"
                "<a href='/on'>开灯</a> | <a href='/off'>关灯</a>";
  server.send(200, "text/html", html);
}

void setup() {
  pinMode(ledPin, OUTPUT);
  WiFi.begin("你的WiFi名", "你的WiFi密码");
  while (WiFi.status() != WL_CONNECTED) delay(500);

  // 注册路由:不同 URL 对应不同处理函数
  server.on("/", handleRoot);
  server.on("/on",  []() { digitalWrite(ledPin, HIGH); handleRoot(); });
  server.on("/off", []() { digitalWrite(ledPin, LOW);  handleRoot(); });
  server.begin();   // 启动服务器
}

void loop() {
  server.handleClient();   // 必须持续调用,处理进来的请求
}

ESP32 蓝牙串口遥控

用手机蓝牙串口 App 发 '1'/'0' 控灯,像有线串口一样简单:

#include <BluetoothSerial.h>

BluetoothSerial SerialBT;
const int ledPin = 2;

void setup() {
  pinMode(ledPin, OUTPUT);
  SerialBT.begin("ESP32-Car");   // 蓝牙名,手机搜这个连
}

void loop() {
  if (SerialBT.available()) {
    char c = SerialBT.read();
    if (c == '1') digitalWrite(ledPin, HIGH);
    if (c == '0') digitalWrite(ledPin, LOW);
    SerialBT.print("收到: ");
    SerialBT.println(c);   // 回发给手机确认
  }
}
WiFi 与蓝牙的取舍

ESP32 的 WiFi 和经典蓝牙共用一根天线,同时全开会互相抢资源、变卡。若只需近距离遥控用蓝牙(省事、无需路由器);要上云、远程访问用 WiFi。经典蓝牙(BluetoothSerial)耗电较高且 iOS 支持差,低功耗/苹果场景优先 BLE。ESP8266 没有蓝牙,只有 WiFi。

WiFi vs 蓝牙 vs MQTT 场景

方式距离需路由器能上云典型用途
WiFi + HTTP局域网/互联网数据上报、远程访问
WiFi + Web 服务器局域网否(本地)网页控硬件
WiFi + MQTT互联网实时双向、海量设备
蓝牙串口/BLE近距离(约10m)手机遥控、配网
本章小结

经典 Uno 不能联网,想做物联网直接换 ESP32/ESP8266——它们兼容 Arduino 编程却自带 WiFi(ESP32 还有蓝牙)。WiFi 两种模式:STA 连入路由器上外网(WiFi.begin(ssid,pass)+等 WL_CONNECTED),AP 自建热点用于配网/直连(WiFi.softAP)。设备当客户端HTTPClient 发 GET/POST 把数据(常拼成 JSON)上报云平台(Blynk/ThingSpeak/巴法云等有现成库);设备当服务器WebServer 注册路由,手机浏览器访问 IP 即可网页控硬件,loop 里要持续 handleClient()。物联网更主流的是 MQTT(发布/订阅、省流量、双向实时,用 PubSubClient)。近距离遥控用 蓝牙串口(BluetoothSerial,像普通 Serial;低功耗/苹果用 BLE)。关键提醒:ESP32 后台跑协议栈,loop 长阻塞会触发看门狗复位,联网代码务必用 millis 非阻塞、必要时 yield() 让出时间片;WiFi 与经典蓝牙共天线,别同时全开。

⚒️ 配套开发者工具箱 · 17 款免费在线工具