1. ESP-NOW 初探:什么是ESP-NOW?它和WiFi、蓝牙有什么区别?为什么选择ESP-NOW做物联网?

大家好,我是你们的嵌入式通信讲师。今天咱们来聊聊ESP-NOW。

说实话,我第一次接触ESP-NOW的时候,心里想的是:“这又是什么新协议?不会是乐鑫搞出来的玩具吧?”

结果用了一次之后,我就真香了。

1.1 什么是ESP-NOW?

ESP-NOW,说白了,是乐鑫(Espressif)为ESP32、ESP8266等芯片量身定制的一种轻量级、无连接的无线通信协议。

它不需要你配路由器,不需要你搞TCP/IP那一套复杂的握手流程。你只需要知道对方的MAC地址,就能直接发数据过去。

我习惯把它叫做“无线对讲机模式”——按一下,数据就飞过去了,不需要拨号,不需要等待。

核心特点:

  • 无连接:不需要建立连接,直接发数据
  • 低功耗:非常适合电池供电的设备
  • 低延迟:毫秒级响应,比WiFi快得多
  • 支持点对点和广播:一对一、一对多都能玩

1.2 ESP-NOW vs WiFi vs 蓝牙:到底有什么区别?

很多同学会问:“老师,我直接用WiFi或者蓝牙不就行了?为什么还要学ESP-NOW?”

嗯,这个问题问得好。我当年也纠结过。

咱们直接上表格对比,一目了然:

特性 ESP-NOW WiFi (TCP/IP) 蓝牙 (BLE)
连接方式 无连接,直接发 需要建立连接 需要配对/连接
延迟 毫秒级(<5ms) 几十毫秒到几百毫秒 10-100ms
功耗 极低(深度睡眠可到μA级) 高(几十mA到几百mA) 低(几mA到十几mA)
传输距离 约200-300米(视距) 约100米(室内) 约10-50米
数据包大小 最大250字节 无限制(分片传输) 最大20字节(BLE)
组网复杂度 极简(几行代码) 复杂(需要IP、路由等) 中等(需要GATT服务)
是否需要路由器 不需要 需要(AP或路由器) 不需要

你看,ESP-NOW在延迟、功耗、组网复杂度上,几乎是碾压级别的。

但注意,它也有短板——数据包太小,只有250字节。你要是想传一张图片,那肯定不行。但传个传感器数据、控制指令,绰绰有余。

1.3 为什么选择ESP-NOW做物联网?

我在项目中遇到过很多场景,WiFi太耗电,蓝牙距离太短,最后都是ESP-NOW救场。

举个例子:

有一次,我要做一个大棚环境监测系统。大棚里分布了十几个传感器节点,每个节点都要把温度、湿度、光照数据发到中心节点。

如果用WiFi,每个节点都要连路由器,功耗大,而且大棚里信号不好,经常断连。

如果用蓝牙,距离只有十几米,大棚那么大,根本覆盖不了。

最后我用了ESP-NOW,每个节点只发几字节的数据,功耗极低,两节AA电池能跑半年。而且距离远,200米内随便放。

你想想看,这种场景下,ESP-NOW简直就是天选之子。

我的建议:

如果你做的是以下类型的项目,优先考虑ESP-NOW:

  • 传感器数据采集(温度、湿度、气压等)
  • 遥控器/开关控制(智能灯、窗帘、门锁)
  • 玩具/机器人之间的通信
  • 需要低功耗、长续航的电池设备
  • 没有WiFi路由器覆盖的户外场景

1.4 ESP-NOW的局限性(避坑指南)

我曾经踩过一个坑,必须跟大家说说。

ESP-NOW虽然好,但它不是万能的。

第一,数据包太小。 250字节,你传个JSON字符串都费劲。所以一般建议用二进制协议,比如Protobuf或者自己定义的结构体。

第二,没有重传机制。 数据发出去,对方收没收到,ESP-NOW不管。你需要自己在应用层做确认和重传。

第三,安全性一般。 ESP-NOW默认不加密。虽然乐鑫提供了AES加密接口,但需要你自己实现密钥管理。

第四,设备数量有限。 一个ESP32最多可以记住20个对端设备。如果你要组一个100个节点的网络,那就得用其他方案了。

注意:

ESP-NOW和WiFi不能同时工作在同一个信道?其实可以,但需要小心配置。我后面会专门讲这个坑。

另外,ESP-NOW在ESP32-S2、ESP32-C3等芯片上表现略有不同,建议统一用ESP32开发。

1.5 一个最简单的ESP-NOW示例

光说不练假把式。咱们来看一个最简单的发送端代码:

#include <esp_now.h>
#include <WiFi.h>

// 接收端的MAC地址(需要替换成你自己的)
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// 回调函数:发送完成后的通知
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.print("发送状态: ");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "成功" : "失败");
}

void setup() {
  Serial.begin(115200);
  
  // 设置WiFi为Station模式(必须)
  WiFi.mode(WIFI_STA);
  
  // 初始化ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("ESP-NOW初始化失败");
    return;
  }
  
  // 注册发送回调
  esp_now_register_send_cb(OnDataSent);
  
  // 添加对端设备(广播地址)
  esp_now_peer_info_t peerInfo;
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;
  peerInfo.encrypt = false;
  
  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    Serial.println("添加对端失败");
    return;
  }
}

void loop() {
  // 发送数据
  uint8_t data[] = "Hello ESP-NOW!";
  esp_now_send(broadcastAddress, data, sizeof(data));
  
  delay(5000); // 每5秒发一次
}

这段代码,说白了就是:初始化ESP-NOW,添加一个广播对端,然后每隔5秒发一条“Hello ESP-NOW!”。

你烧录到两个ESP32上,一个发一个收,就能看到效果了。

嗯,这里要注意:MAC地址一定要填对。我刚开始学的时候,把地址写错了,折腾了半天才发现。

1.6 小结

好了,咱们总结一下今天的内容:

  • ESP-NOW是乐鑫的轻量级无线协议,无连接、低功耗、低延迟
  • 它比WiFi省电,比蓝牙距离远,组网也简单
  • 适合传感器采集、遥控控制、电池设备等场景
  • 但数据包小、无重传、安全性一般,需要你自己处理

下一章,我会带大家深入ESP-NOW的通信模式,包括点对点、广播、以及如何实现双向通信。

咱们下节课见!


公众号:蓝海资料掘金营,微信deep3321