SX1278 Ra-02 LoRa 模块接 Arduino:3.3V 安全接线、天线与第一条消息

Cartoon of a navy-blue SX1278 Ra-02 LoRa board with silver shield and black whip antenna sending teal radio arcs across rows of houses to a tiny second board

SX1278 Ra-02 是一块只能用 3.3V 的 433MHz LoRa 无线模块:电源只接 3.3V——绝对不能接 5V——板子通电之前先把天线扣上,5V 的 Uno 送进模块的四条信号线要先降压到 3.3V,然后用 Arduino 的 LoRa 库,一块板就能在 434MHz 上给另一块板发出第一条消息。在房屋密集的 taman 住宅区里,大约能传几百米;视线无遮挡时,大约一到数公里——用的是 MCMC 以类别指配(class assignment)开放给短距离无线设备的 433–435MHz 频段,等效全向辐射功率(EIRP)上限 100mW。

SX1278 Ra-02 是什么模块?

SX1278 Ra-02 模块是安信可(Ai-Thinker)出品的 433MHz 无线模块:深蓝色转接板上盖着一块银色屏蔽罩,采用 LoRa 调制、SPI 接口,调谐范围 410–525MHz,最大发射功率 +18dBm——频段和功放(PA)数值就印在屏蔽罩上。

SX1278 Ra-02 一览
射频芯片 Semtech SX1278——支持 LoRa、FSK 和 OOK
调谐范围 410–525MHz;在马来西亚请用 433–435MHz
发射功率 最高 +18dBm;LoRa 库默认 +17dBm
供电 2.5–3.7V,典型 3.3V——绝不能接 5V
电流 接收约 12mA;发射时 90–120mA 脉冲
接口 SPI(NSS、SCK、MOSI、MISO),另加 RST 和 DIO0
包装内容 转接板、两条散装 8 针排针、U.FL 鞭状天线

为什么一条 LoRa 链路要用两种不同的板子?

要发出第一条 SX1278 消息,两端各需要一块无线模块——材料清单里有两块——但两端特意不用同一种单片机。

这样分工,是顺着模块的两种“胃口”来的。接收很省电——根据安信可的 Ra-02 规格书,大约 12mA——Uno R3 的 3.3V 引脚Arduino 官方额定 50mA,绰绰有余,所以由 Uno 负责接收。发射就不一样了:安信可规格书列出 433MHz 时为 93mA,SX1278 芯片本身在 +20dBm 上限时会升到约 120mA——差不多是那个额定值的两倍,足以在发包途中把 Uno 那颗小小的 3.3V 稳压器拉低。NodeMCU ESP-32S 板上是一颗额定约 1A 的 AMS1117 类稳压器,所以由 ESP32 负责发射。模块本身规定的供电是 2.5–3.7V,典型 3.3V——VCC 接 5V 会直接烧掉它;网上规格表里常见的 1.8V 最低电压,是 SX1278 裸芯片的数值,不是这块模块的。

可选:代焊服务、母对母杜邦线、万用表

ItemPriceQty
Soldering Service for Circuit Boards & Electronics - 10 Pins Soldering ServiceSoldering Service for Circuit Boards & Electronics - 10 Pins Soldering ServiceSOLSE10RM1.40
Soldering Service for Circuit Boards & Electronics - 1 Pin Soldering ServiceSoldering Service for Circuit Boards & Electronics - 1 Pin Soldering ServiceSOLSE01RM0.20
40pcs Dupont Wire 10cm 20cm 30cm for Breadboard DIY Experiment Jumper Wire Breadboard wire - DUPONT WIRE F-F 20CM40pcs Dupont Wire 10cm 20cm 30cm for Breadboard DIY Experiment Jumper Wire Breadboard wire - DUPONT WIRE F-F 20CMDWPFF20RM3.70
XL830L Digital Multimeter with backlight Portable Multimeter Electronics ProjectXL830L Digital Multimeter with backlight Portable Multimeter Electronics ProjectMULTIMERM25.95

代焊服务刚好覆盖 32 个针脚——两块模块的全部排针——无线模块到手就能直接插面包板。母对母杜邦线把 ESP32 节点逐针直连,不需要第二块面包板;万用表则在接上无线模块之前,确认每个分压节点都接近 3.3V。

通电之前,要先焊什么、装什么?

Ra-02 的包装里有转接板、两条散装 8 针公排针,以及一根 IPEX 转接线天线——细细的黑色同轴线,一端是小小的金色 U.FL 插头,另一端是弹簧鞭状天线。16 个通孔出厂时是空的,所以先焊排针——两块模块一共 32 个焊点,技巧见我们的排针焊接教程——不想碰烙铁的话,可以交给 10 针和 1 针代焊服务。

天线不需要焊接:把金色 U.FL 插头平放对准屏蔽罩角落的插座,垂直往下压,直到“咔”一声扣上——不要扭,也不要斜着压——而且一定要在板子通电之前完成。天线是发射能量离开模块的出口。插座空着的时候,库默认的 +17dBm 脉冲会在馈线开路的一端反射回来,以热量和电压应力的形式,回到刚刚产生它的功率放大器里;只要一次没接天线的 LoRa.endPacket()——真正让发射机发射的就是这个调用——就可能是这块模块的最后一次。

卡通特写:一个金色 U.FL 天线插头正被压进深蓝色 SX1278 Ra-02 板上的金色插座,旁边一块没接天线的模块被打上叉,表示禁止这样做
把金色 U.FL 插头垂直压下,直到“咔”一声扣上——插座空着时千万别给模块通电:无处可去的发射能量,会直接反弹回功放。

怎样把 Ra-02 安全地接到 5V 的 Uno 上?

Uno 的 ATmega328P 用的是 5V 逻辑电平,Ra-02 却只认 3.3V。不过需要处理的只有四条线:由 Uno 输出到模块的信号——NSS、SCK、MOSI 和 RST。每条线在面包板上加一组分压电路:一颗 10k 从 Uno 引脚接到一条节点排,再用两颗 10k 串联(20k)从节点接地,全部取自电阻包里的二十颗 10k。模块引脚接在节点上:5V 的信号摆幅落在 30k 的电阻链上,模块拿到的是下面那三分之二:5V × 20k/30k = 3.3V。四组分压一共用十二颗电阻。

接上模块之前,先用万用表逐组检查:把分压电路的上端用跳线接到 Uno 的 5V 引脚,节点应该读到约 3.3V——读到 1.7V,表示 10k 和 20k 接反了;读到 5V,表示下半段根本没接到地。

反方向的两条线不需要任何处理。MISO 和 DIO0 是模块以 3.3V 向外输出的信号,而根据 Microchip 的 ATmega328P 规格书,只要高于 0.6 × VCC = 3.0V,ATmega328P 就判定为高电平——3.3V 直接过关。公对母杜邦线的母头先套在模块新焊好的针脚上,公对公杜邦线则从 Uno 的排母接到分压电路所在的排(公母怎么分,见我们的杜邦线教程)。电源取自 Uno 的 3.3V 引脚——接收时只要约 12mA,完全没问题。

Ra-02 引脚 Uno 引脚 接法
3.3V 3.3V 直连——接收只需约 12mA
GND GND 直连,与分压电路的地线共用
NSS D10 分压:D10 接 10k,20k(2×10k)接 GND
SCK D13 分压,同样是 10k : 20k
MOSI D11 分压,接法同上
RST D9 分压,接法同上
MISO D12 直连——模块输出 3.3V,高于 Uno 的 3.0V 门槛
DIO0 D2 直连——模块输出

分压电路有一个副作用,解决办法写在程序里。从模块引脚看过去,每组分压电路相当于一个 6.7k 的信号源(10k 和 20k 并联),要给大约 10–20pF 的引脚和跳线电容充电,时间常数约 70–130ns。库默认的 SPI 时钟是 8MHz,每半个周期只有 62ns,还不到一个时间常数,于是模块采样到的是还没成形的边沿,读出来全是乱码。LoRa.setSPIFrequency(1E6) 把每半个周期拉长到 500ns,相当于好几个时间常数,边沿就变得方方正正——下面的接收程序已经加上了这一行。

ESP32 发射端怎么接?

有了 NodeMCU ESP-32S,第二个节点几乎不费功夫:它的 GPIO 本来就是 3.3V,每条线都能直连,SPI 照样全速跑;3V3 引脚背后是那颗对发射脉冲毫不在意的 AMS1117 类稳压器。这个节点必须和 Uno 节点分开,因为测距时两者之间要隔好几条街:用可选的母对母杜邦线把模块针脚直接套在 ESP32 的公针上,或者给 ESP32 单独配一块面包板——第一块已经放了 Uno 的分压电路——再用公对母杜邦线从每根针旁边的空孔接出。

Ra-02 引脚 ESP-32S 引脚 接法
3.3V 3V3 直连——稳压器扛得住约 120mA 的发射脉冲
GND GND 直连
NSS GPIO5 直连
SCK GPIO18 直连
MOSI GPIO23 直连
MISO GPIO19 直连
RST GPIO14 直连
DIO0 GPIO26 直连
卡通图:一块 Arduino Uno 通过布满电阻分压电路的面包板连接一块深蓝色 LoRa 模块,一块黑色 ESP32 开发板则直接连着第二块模块,青绿色弧线在两根天线之间来回
两个节点,两种性格:Uno 躲在电阻梯后面负责听,ESP32 直接连线,承担耗电的发射工作。

用哪两个程序发出第一条消息?

两个 SX1278 节点都用 Sandeep Mistry 写的 LoRa 库来驱动:打开库管理器(Library Manager),搜索“LoRa”,安装即可。用一根 micro-USB 数据线把发送程序上传到 ESP-32S(开发板选 ESP32 Dev Module;如果端口一直不出现,我们的 ESP32 无法识别、上传失败排查教程讲了只能充电的线和驱动程序的问题),接收程序则上传到 Uno。两个程序都用 434MHz(为什么是这个数字,合法性那一节会解释)和 setSyncWord(0x4D),这样接收端会跳过带有其他同步字的数据包,包括附近其他爱好者程序常用的库默认值 0x12。两个程序也都调用了 enableCrc():这个库默认不发送校验码,所以在通信距离的边缘,损坏的数据包照样会被打印出来——一串看起来像是收到了、其实是乱码的文字。

// LoRa 发送端 - ESP32 节点(NodeMCU-32S + SX1278 Ra-02)
// 这块板通电之前,一定要先装好天线。
#include <SPI.h>
#include <LoRa.h>

const long FREQ = 434E6;   // 让 125 kHz 信道居中,完整落在马来西亚的 433-435 MHz 频段内
const int PIN_NSS  = 5;
const int PIN_RST  = 14;
const int PIN_DIO0 = 26;

int counter = 0;

void setup() {
  Serial.begin(115200);
  LoRa.setPins(PIN_NSS, PIN_RST, PIN_DIO0);
  if (!LoRa.begin(FREQ)) {
    Serial.println("SX1278 not found - check 3.3V, GND and the SPI wires");
    while (true) {}
  }
  LoRa.setSyncWord(0x4D);  // 两个程序必须用同一个值
  LoRa.enableCrc();        // 给每个数据包附上校验码
  Serial.println("LoRa sender ready");
}

void loop() {
  LoRa.beginPacket();
  LoRa.print("MakerHub #");
  LoRa.print(counter);
  LoRa.endPacket();        // 一直等到数据包完全发出才返回
  Serial.print("Sent packet ");
  Serial.println(counter);
  counter++;
  delay(5000);
}
// LoRa 接收端 - Uno 节点(SX1278 Ra-02 经 10k:20k 分压连接)
// 这块板通电之前,一定要先装好天线。
#include <SPI.h>
#include <LoRa.h>

const long FREQ = 434E6;   // 必须与发送端一致
const int PIN_NSS  = 10;
const int PIN_RST  = 9;
const int PIN_DIO0 = 2;

void setup() {
  Serial.begin(9600);
  LoRa.setPins(PIN_NSS, PIN_RST, PIN_DIO0);
  LoRa.setSPIFrequency(1E6);  // 电阻分压会把 8 MHz 的边沿磨圆 - 把总线放慢
  if (!LoRa.begin(FREQ)) {
    Serial.println("SX1278 not found - check 3.3V, GND and the divider wiring");
    while (true) {}
  }
  LoRa.setSyncWord(0x4D);  // 与发送端用同一个值
  LoRa.enableCrc();        // 丢弃校验失败的数据包
  Serial.println("LoRa receiver ready");
}

void loop() {
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    Serial.print("Received: ");
    while (LoRa.available()) {
      Serial.print((char)LoRa.read());
    }
    Serial.print("  RSSI ");
    Serial.print(LoRa.packetRssi());
    Serial.print(" dBm, SNR ");
    Serial.print(LoRa.packetSnr());
    Serial.println(" dB");
  }
}

以 9600 波特率打开接收端的串口监视器,每五秒就会出现一行:消息内容、一个应该连续递增、不会跳号的计数,以及下一节要讲的两个数字。如果 LoRa.begin() 打印的是那行失败提示,说明无线模块根本没有通过 SPI 回应——在 Uno 上,几乎都是某组分压的 10k 和 20k 接反了(节点只剩 1.7V,低到认不出是高电平),或者漏接了共地。

RSSI 和 SNR 到底说明了什么?

SX1278 收到的每个数据包都附带两个读数。RSSI——接收信号强度——是到达天线的无线功率,单位 dBm:0dBm 等于 1 毫瓦,每 −10dB 就除以十,所以 −30dBm 是 1 微瓦,−120dBm 又是它的十亿分之一。两块板放在同一张桌上,预计读到 −30 到 −50dBm,随着两个节点拉开距离而下降。SNR 是信号比周围无线噪声高出多少,单位 dB——而且 LoRa 在 SNR 低于零时仍能解码:在默认扩频因子下,解调器一直到约 −7.5dB 都还能工作,也就是信号比周围的噪声还弱,依据是 Semtech SX1278 产品页上的 SX1276/77/78/79 规格书(表 13)。

原理在于 LoRa 的线性调频(chirp)调制。每个符号都会扫过整个 125kHz 信道;接收端把收到的信号乘上反向的扫频,每个 chirp 就会收拢成一个干净的单音。随机噪声在整段扫频里不会同相叠加——chirp 会。这种相关增益,就是这块模块能跨越好几公里,而 nRF24L01 的高速 2.4GHz 数据包只能覆盖一栋房子的原因。代价是速度:每秒几百字节——适合传感器读数和控制指令,永远传不了视频。

两个读数要一起看:库给出的 RSSI 量的是整个信道里的所有能量,SNR 只看你的数据包。−110dBm、SNR +5dB,是弱但干净,比 −7.5dB 的底线高出 12.5dB;−100dBm、SNR −6dB,则大半是噪声,离悬崖只剩 1.5dB,马上就要开始丢包。在马来西亚的住家附近,这些噪声往往来自其他 433MHz 设备——很多 autogate 自动门遥控器和汽车钥匙遥控器都在这个频段。

在马来西亚,合法又实在的通信距离是多少?

MCMC 的 Class Assignment No. 2 of 2025(2025 年第 2 号类别指配)把 433–435MHz 以类别指配开放给短距离设备,上限 100mW EIRP,不需要申请个人执照——这是 Ra-02 调谐范围里唯一出现在该表中的一段。EIRP 是发射机输出功率加上天线增益,所以这个上限连天线也一起管住了。类别指配的一般条件同样适用:不得造成有害干扰,必须接受来自他人的干扰,并且使用经 MCMC 或其注册认证机构认证的设备;用于研究、试验和培训可以申请特别批准——要拿任何无线模块做成产品之前,先把这件事处理好。同一份文件把 919–923MHz 开放到 500mW EIRP(923–924MHz 另需符合占空比或先听后发的条件),AS923 LoRaWAN 设备就在这一段——但 Ra-02 的调谐范围是 410–525MHz,物理上到不了那个频段;做 AS923 需要 SX1276 类模块。

程序里有两个细节,确保你留在规定之内。频率:用 LoRa.begin(434E6),而不是常见的 433E6,因为默认信道宽 125kHz,中心放在 433.0MHz,就有一半落在频段下限之外;中心放在 434MHz,整个信道都在里面。功率:库默认 +17dBm——天线插座处 50mW——随附的鞭状天线大约再加 2dBi,合计约 79mW EIRP,在 100mW 上限内还留有余量。别去调用 setTxPower(20):100mW 传导功率再加上任何天线增益,都会超标,何况屏蔽罩上印的 PA 本来就只是 +18dBm。

用随附的鞭状天线、默认设置,在马来西亚实在的数字是:房屋密集的住宅区里几百米,视线无遮挡时一到数公里,比如从草场(padang)到对面的公寓楼。包装上写的“10km”,是靠高塔、高增益天线和空旷野外得来的。决定性的因素是高度:一条链路的能量,是在两点连线周围一个雪茄形的区域里传播的——在 434MHz、1km 的距离上,中点处半径约 13m——这个区域里的每一片屋顶、每一道墙和每一块地面,都会吃掉信号。在住宅区里拿在腰的高度,这个区域塞满了砖墙;从三楼窗口发射,大半区域就畅通了。

测距时,把 ESP32 发送端留在家里,用充电宝供电,你带着 Uno 和笔记本电脑出门走,看着 RSSI 一路下降、SNR 变成负数——链路通常走不出几条街就断了,到了空旷地又会恢复。边走边留意计数:跳号,是数据包在空中丢了;如果计数从零重新开始,或者 RSSI 还很健康却突然没了消息,问题就出在发送端的供电——很多充电宝在 ESP32 只有几十毫安的轻负载下会自动断电,所以请用带低电流模式的充电宝,或者 USB 充电头。亲眼看着 RSSI 实时往下掉,是一个毕业专题(FYP)IoT 项目能上到的最好的一堂无线电课。

卡通风景图:深蓝色 LoRa 板发出的青绿色无线电弧线越过排屋屋顶时逐渐减弱,接着在空旷的草地上一路畅通,远远到达立在杆子上的第二块板
同样的 50mW,表现却像两台不同的无线电:穿过一排水泥排屋时弧线支离破碎,越过空地时又长又干净——实在的距离就是“住宅区里几百米,草场上几公里”。

我们常见的错误

习惯性地把 VCC 接到 5V。大多数爱好者模块都受得了,所以手会自动伸向 5V 电源轨——而 Ra-02 只能承受 2.5–3.7V 的射频芯片,就这样报废了。接过一次 5V 之后,如果模块照样耗电,却怎么也不回应 LoRa.begin(),通常已经没救了。

“只是测一下程序”,就不接天线通电。程序开机几秒内就开始发射,空着的插座把脉冲反射回功放,损坏悄无声息地发生——模块可能还能正常接收好几个星期,发射功率却只剩一小部分。每一次,都先把鞭状天线扣上。

原封不动地跑库里的范例。LoRaSender 和 LoRaReceiver 调用的是 LoRa.begin(915E6)——410–525MHz 的 Ra-02 根本到不了这个频率,它也不是马来西亚的短距离频段——但 begin() 照样会成功,因为它只检查芯片有没有通过 SPI 回应。两个节点都要改成 434E6。

在桌上判断通信距离。两根相隔一个巴掌宽的天线,读数是 −30dBm、SNR 完美;于是第一道真正的墙一挡,看起来就像硬件故障。只有隔了一条街,距离才有意义——而且两根鞭状天线都要竖直,因为平放的天线发出的是水平极化信号,竖着的另一端几乎收不到。

常见问题

在马来西亚,不申请执照用 LoRa 合法吗?

在类别指配的频段内不需要个人执照:MCMC 的 Class Assignment No. 2 of 2025 允许 433–435MHz 的短距离设备以最高 100mW EIRP 运作,条件是不造成有害干扰、设备经过 MCMC 认证;用于研究、试验和培训可以申请特别批准。Ra-02 在库默认的 +17dBm 下配随附的鞭状天线,约为 79mW EIRP——在功率上限内还有余量。完全不要用 setTxPower(20):100mW 传导功率加上哪怕只是原装鞭状天线的增益,都会超标。

为什么程序里设 434MHz,而不是 433MHz?

LoRa 默认信道宽 125kHz,以你传给 LoRa.begin() 的频率为中心。设 433.0MHz 时,信道大约覆盖 432.94–433.06MHz——有一半落在频段下限之外。设 434MHz 时覆盖 433.94–434.06MHz,完全在 433–435MHz 之内。一个数字,就决定了你在不在指配频段里。

两块 Ra-02 实际能传多远?

用随附的鞭状天线和默认设置:在马来西亚房屋密集的住宅区里几百米,真正视线无遮挡时一到数公里。那些 10km 的数字,来自高处架设、高增益天线和空旷地形。最有帮助的是高度:天线放在三楼窗口,路径大半会从屋顶上方越过,而不是穿过房子。

Ra-02 能接入马来西亚的 LoRaWAN 网络吗?

不能。马来西亚的 LoRaWAN 用的是 919–924MHz 的 AS923,而 Ra-02 的调谐范围是 410–525MHz——物理上到不了那个频段。而且这两个程序是点对点的原始 LoRa,不是 LoRaWAN 协议。AS923 需要 SX1276 类模块;如果只是做私人的两节点链路,一对 Ra-02 正合适。

可以用两块 Arduino Uno,不用 ESP32 吗?

可以,只是要多一个零件。每个 Uno 节点都需要四组分压和 setSPIFrequency(1E6),而负责发射的那块 Uno,它的 Ra-02 需要一颗独立的、能输出 250mA 的 3.3V 稳压器,从 Uno 的 5V 引脚取电并共地——50mA 的 3.3V 引脚在 90–120mA 的发射脉冲下会掉压。ESP32 两样都不需要,这正是本教程选用它的原因。

最后更新:2026 年 11 月。有问题?WhatsApp 联系我们。

Leave a Reply

Your email address will not be published. Required fields are marked *