LoRa(Long Range)是一种低功耗广域网(LPWAN)无线通信技术,由 Semtech 公司开发。它能在城市环境 2~5 km、郊区 10~15 km 的范围内传输数据,同时功耗极低——一节电池能让传感器节点工作数年。
SX1278 是 Semtech 的 LoRa 射频收发芯片,工作在 433 MHz 频段(中国允许的 ISM 频段),通过 SPI 接口与 ESP32 通信。你只需要两个 ESP32 + 两个 SX1278 模块,就能搭建一套点对点远距离通信系统。
应用场景:智慧农业(田间传感器→基站)、环境监测(河流/森林数据回传)、远程抄表、无人机数传、户外探险定位等。
| 物料 | 型号/参数 | 数量 | 参考价格 |
|---|---|---|---|
| ESP32 开发板 | ESP32-WROOM-32(CH340 版) | 2 | ¥18~25/个 |
| LoRa 模块 | SX1278(Ra-02),433 MHz | 2 | ¥12~18/个 |
| 弹簧天线 | 433 MHz,SMA 接口 | 2 | ¥2~4/个 |
| 杜邦线 | 母对母,20 cm | 14 条 | ¥3/组 |
| 面包板 | 830 孔 | 2 | ¥5~8/个 |
| DHT22 温湿度传感器 | 可选(用于实战场景) | 1 | ¥6~9/个 |
| OLED 显示屏 | SSD1306 0.96寸 I2C | 1 | ¥8~12/个 |
┌──────────────────────────────────────────────────────┐ │ ESP32 ←→ SX1278 (Ra-02) 引脚连接 │ ├────────────┬─────────────────────────────────────────┤ │ ESP32 │ SX1278 (Ra-02) 说明 │ ├────────────┼─────────────────────────────────────────┤ │ 3.3V │ VCC (3.3V) 供电(勿接5V!) │ │ GND │ GND 共地 │ │ GPIO5 │ SCK SPI 时钟 │ │ GPIO18 │ MISO SPI 主入从出 │ │ GPIO23 │ MOSI SPI 主出从入 │ │ GPIO14 │ NSS (CS) SPI 片选 │ │ GPIO2 │ RST (RESET) 复位引脚(可接3.3V) │ │ GPIO26 │ DIO0 中断引脚 │ ├────────────┴─────────────────────────────────────────┤ │ 注意:SX1278 是 3.3V 器件,绝对不能接 5V! │ │ 模块上的 ANT 引脚焊接 SMA 座或直接焊弹簧天线。 │ └──────────────────────────────────────────────────────┘
发送端每隔 3 秒发送一条 "Hello from ESP32 #1 — packet: N",接收端收到后打印并通过板载 LED 闪烁确认。
// ========== 发送端 (Sender) ========== #include <SPI.h> #include <LoRa.h> #define SS 14 #define RST 2 #define DIO0 26 #define FREQ 433E6 // 433 MHz int packetCounter = 0; void setup() { Serial.begin(115200); delay(1000); Serial.println("🚀 LoRa Sender 启动中..."); LoRa.setPins(SS, RST, DIO0); if (!LoRa.begin(FREQ)) { Serial.println("❌ LoRa 初始化失败!检查接线"); while (1); } LoRa.setSpreadingFactor(7); // SF7 = 最快 LoRa.setSignalBandwidth(125E3); // 125 kHz LoRa.setCodingRate4(5); // 4/5 Serial.println("✅ LoRa 初始化成功!"); } void loop() { char msg[64]; sprintf(msg, "Hello #%d | RSSI将在接收端显示", packetCounter); LoRa.beginPacket(); LoRa.print(msg); LoRa.endPacket(); Serial.printf("📤 发送 #%d: %s\n", packetCounter, msg); packetCounter++; delay(3000); }
// ========== 接收端 (Receiver) ========== #include <SPI.h> #include <LoRa.h> #define SS 14 #define RST 2 #define DIO0 26 #define FREQ 433E6 #define LED 2 // 板载 LED void setup() { Serial.begin(115200); pinMode(LED, OUTPUT); digitalWrite(LED, LOW); delay(1000); Serial.println("📡 LoRa Receiver 启动中..."); LoRa.setPins(SS, RST, DIO0); if (!LoRa.begin(FREQ)) { Serial.println("❌ LoRa 初始化失败!"); while (1); } LoRa.setSpreadingFactor(7); LoRa.setSignalBandwidth(125E3); LoRa.setCodingRate4(5); Serial.println("✅ 等待数据..."); } void loop() { int packetSize = LoRa.parsePacket(); if (packetSize == 0) return; // 读取数据 char buf[128] = {0}; int i = 0; while (LoRa.available() && i < 127) { buf[i++] = (char)LoRa.read(); } buf[i] = '\0'; // 获取信号质量 int rssi = LoRa.packetRssi(); float snr = LoRa.packetSnr(); Serial.printf("📥 收到: %s | RSSI:%d dBm | SNR:%.1f dB\n", buf, rssi, snr); // LED 闪烁确认 digitalWrite(LED, HIGH); delay(100); digitalWrite(LED, LOW); }
LoRa 模块是半双工的——同一时刻只能发或收。你可以在发送后立即切换到接收模式等待 ACK:
// 发送后等待确认 LoRa.beginPacket(); LoRa.print("DATA:26.5,65.2"); LoRa.endPacket(true); // true = 发送完后立即进入接收模式 // 等待 500ms 内的 ACK unsigned long start = millis(); while (millis() - start < 500) { if (LoRa.parsePacket()) { String ack = LoRa.readString(); if (ack == "ACK") { Serial.println("✅ 收到确认"); break; } } }
一个接收端(网关)监听多个发送端(节点)。每个节点在消息中带上自己的 ID,网关根据 ID 区分来源:
// 节点端 — 带 ID 发送 #define NODE_ID 3 char msg[64]; sprintf(msg, "NODE:%d|T:%.1f|H:%.1f", NODE_ID, temp, hum); LoRa.beginPacket(); LoRa.print(msg); LoRa.endPacket(); // 网关端 — 解析来源 String payload = LoRa.readString(); int nodeId; float temp, hum; sscanf(payload.c_str(), "NODE:%d|T:%f|H:%f", &nodeId, &temp, &hum); Serial.printf("节点%d → 温度%.1f°C 湿度%.1f%%\n", nodeId, temp, hum);
场景描述:你在楼顶放置一个 ESP32+LoRa+DHT22 的太阳能供电节点,室内放另一个 ESP32+LoRa 作为网关。网关收到数据后通过 WiFi+MQTT 推送到手机 App,足不出户就能看到楼顶的实时温湿度。
物料组合:发送端:ESP32 + SX1278 + DHT22 + 锂电池;接收端:ESP32 + SX1278 + OLED 显示屏
数据流:DHT22 → ESP32-Sender → LoRa → ESP32-Gateway → WiFi → MQTT Broker → 手机 App
联动已学模块:结合 5月22日的 MQTT 教程,在网关端的 loop() 中收到 LoRa 数据后调用 client.publish("home/rooftop", payload) 即可完成数据上云。
场景描述:徒步小队成员每人携带一个 ESP32+LoRa+GPS(NEO-6M) 口袋节点,队长的设备作为网关+显示屏。所有成员的位置每 5 秒通过 LoRa 汇集到队长屏幕,超出范围自动提醒。
物料组合:每人:ESP32 + SX1278 + NEO-6M GPS;队长额外:OLED 显示屏
LoRa 参数建议:户外空旷环境用 SF12 + 125kHz,可获得最佳通信距离(理论 > 5km)。
LoRa.begin() 返回值检查初始化是否成功;~/Arduino/libraries/ 目录中删除多余的。