用 LoRa + W5500 做一个无线呼叫器:从按键到上位机的一条链路
无线呼叫器这种东西看起来简单:按一下按钮,另一端响一下、亮一下,最好还能把"哪个按钮触发的"显示在电脑上,方便做记录、联动更多逻辑(弹窗、语音播报、统计报表等)。
我这套方案的核心思路是把链路拆成两段:
- 空口段 :按键端用 LoRa(LLCC68) 把"按键事件"发出去,距离远、穿透强、功耗可控。
- 局域网段 :接收端把事件通过 以太网(W5500) 丢到局域网里,上位机用 TCP 接收并展示。
下面按"整体架构 → 关键选型 → 通信与协议 → 软件与实现要点 → 可扩展方向"把方案讲清楚。
1. 目标与约束
我希望这个呼叫器具备这些特性:
- 多按钮:一个发射端可以有多个按键,每个按键对应不同事件(例如不同房间、不同服务类型)。
- 一发一收:先做最小可用系统(一个发射器 + 一个接收器),但后续能扩展到多个发射器。
- 上位机可视化:接收端不仅本地指示(灯/蜂鸣器),还能把事件发给电脑显示/记录。
- 部署简单:更换电脑、改 IP、换网络环境时,不希望每次都要改固件。
2. 整体架构(对应你的方案图)
系统分为三个角色:
2.1 信号发送器(按键端)
- MCU:STM32
- 外设:多按键 + 按键反馈灯
- 无线:LoRa 模块(LLCC68),通过 SPI 或 UART(常见是 SPI)与 STM32 通信
- 功能:检测按键 → 组帧 → LoRa 发射(可加重发/确认机制)
2.2 信号接收器(网关端)
- MCU:STM32
- 无线:LoRa 模块(LLCC68),负责收包
- 有线网:W5500 以太网模块,通过 SPI 与 STM32 通信
- 指示:网络信号灯等
- 功能:LoRa 收包 → 校验/解析 → 通过 TCP 发给上位机(同时可本地亮灯/响铃)
2.3 上位机(电脑)
- 与接收器在同一局域网内(接交换机有线或连 Wi-Fi 但在同网段)
- 运行一个简单程序:接收 TCP 数据 → 显示/记录/联动
3. 为什么让"接收器做 TCP 服务端"
这点很关键,也是你图里专门标注的那段说明。
如果让接收器作为 TCP 客户端,那它必须"主动去连上位机"。这会带来两个现实问题:
- 接收器固件必须写死上位机 IP/端口
电脑一换、IP 一变,就要改固件、重新烧录。 - 电脑端要保证随时在线
不在线时接收器还要处理重连、超时、异常状态,逻辑复杂度上升。
反过来,让接收器作为 TCP 服务端(监听者),优势非常明显:
- 接收器只需要固定自己的 IP(静态或 DHCP 绑定都行),上位机作为客户端去连接它。
- 电脑换了、IP 变了,甚至多个电脑轮流接入,都不会影响接收器固件。
- 部署时只要记住"接收器的 IP + 端口",成本最低。
结论:接收器做 TCP Server,上位机做 TCP Client,是更适合"设备端长期部署"的结构。
4. 硬件连接要点(不画原理图也能落地)
4.1 LoRa(LLCC68)接 STM32
常见连接(以 SPI 为例):
- SCK / MISO / MOSI → STM32 SPIx
- NSS(CS)→ 任意 GPIO
- BUSY / DIO1 / RESET → GPIO(其中 DIO1 常用作中断)
建议:
- DIO1 一定要接,用于接收完成/发送完成中断,不然轮询会很难写得优雅。
- 频段选型要符合你所在地区允许的频段(常见 433/470/868/915 MHz)。
4.2 W5500 接 STM32
W5500 基本也是 SPI:
- SCK / MISO / MOSI → STM32 SPIy(可与 LoRa 共享同一 SPI 总线)
- CS → GPIO(独立片选)
- INT / RST → GPIO(可选但强烈建议接 RST)
建议:
- LoRa 和 W5500 可以共用 SPI,但务必保证每次操作前后正确控制 CS,避免总线冲突。
- 网络指示灯(Link/Act)用 W5500 模块自带的即可,另外也可以用 MCU 再做一颗"网络状态灯"。
4.3 一个容易忽略的点:电源与地
- LoRa 发射瞬间电流会上升,W5500 网络活动也会有波动。
- 电源要留足余量,并在模块附近加足够的去耦电容(例如 0.1uF + 10uF 组合)。
- 地线要可靠,避免"能收包但一联网就不稳定"的诡异问题。
5. 通信设计:按键事件如何变成"可用的数据"
5.1 按键端要解决两件事
- 去抖动 :避免一次按下触发多次。
可用定时器采样或简单延时确认(更推荐定时器方式)。 - 事件编码:至少要包含"谁发的 + 按了哪个键 + 什么时候"。
一个实用的 LoRa 数据帧可以这样设计(示例):
header:0xA5(帧头)dev_id:设备 ID(1 字节或 2 字节)key_id:按键编号type:按下/抬起/长按等seq:序号(用于去重/丢包统计)crc8:校验
不要一上来就追求复杂,先做到"可靠识别、可扩展"。
5.2 接收端要做的事
- 校验(帧头/CRC)
- 去重(根据
dev_id + seq) - 解析成上位机能理解的格式(文本或 JSON 都行)
举个上位机友好的输出(JSON 行协议):
json
{"dev":1,"key":3,"type":"press","seq":57,"rssi":-72,"snr":9.5,"ts":1734940000}
这样做的好处是:
- 上位机语言随便选(Python/Java/C#/Node.js 都容易解析)
- 后续要接数据库、做 Web 界面也顺滑
6. TCP 传输:推荐"接收端 TCP Server + 上位机 TCP Client"
6.1 网络部署方式
-
接收器以太网接交换机(最稳)
-
上位机:
- 也接交换机(有线)
- 或者连路由器 Wi-Fi,但要保证在同一局域网网段,且能访问到接收器 IP
6.2 接收端 TCP Server 的行为建议
- 固定监听端口(例如 5000)
- 允许单连接或多连接(先做单连接最简单)
- 若客户端断开,继续监听等待下一次连接
- 收到 LoRa 事件就
send()一行 JSON(或自定义协议)
如果你担心 TCP
send()阻塞影响 LoRa 接收,可以用队列 + 发送线程/任务(裸机可用环形缓冲区,RTOS 就更舒服)。
7. 软件实现分工(建议的工程结构)
7.1 发送器固件(STM32)
模块划分建议:
key_scan.c:按键扫描、去抖、事件生成lora_radio.c:LLCC68 驱动、发包、重发策略protocol.c:帧封装/解析、CRCui_led.c:按键反馈灯
流程(简化):
- 扫描到按键事件
- 生成帧(带
seq) - LoRa 发射
- 反馈灯闪烁(可选:发送成功/失败不同提示)
7.2 接收器固件(STM32)
模块划分建议:
lora_radio.c:收包、中断回调、RSSI/SNR 读取net_w5500.c:W5500 初始化、TCP Server、发送队列protocol.c:解析 LoRa 帧,生成 JSONstatus_led.c:网络/数据指示
流程(简化):
- LoRa 中断提示收到数据
- 读包 → 校验 → 去重
- 组织 JSON 文本
- 若 TCP 已连接,发送;否则缓存或丢弃(看需求)
8. 可靠性:最小成本把"体验"做扎实
无线呼叫器真正让人崩溃的不是写不出来,而是"偶尔丢一下、偶尔重复一下"。
建议你至少做三件事:
- 序号去重 :接收端按
dev_id + seq去重,避免按键抖动或重发导致重复弹窗。 - 重发策略 :发送端发一次后隔 50~150ms 再发 1~2 次(简单粗暴但有效)。
如果要更严谨,可做 ACK(接收端回包确认),但复杂度会提高。 - 事件与状态分离 :按键"事件包"和设备"心跳包"分开。
心跳包可以每隔几秒发一次,用于上位机显示"设备在线"。
9. 可扩展方向(后面想加功能就沿着这几条走)
- 多发射器 :给每个发射端分配
dev_id,上位机按设备分组显示。 - 更友好的上位机:从命令行打印升级到 GUI(PyQt/WinForms/Electron 都可)。
- 联动外设:接收端加蜂鸣器/继电器,按不同 key 触发不同动作。
- 数据落库与统计:上位机把 JSON 写入 SQLite/MySQL,做呼叫频率统计、响应时间统计。
- 安全性:需要的话可在协议层做简单加密/签名(例如 AES + rolling counter),防止被同频干扰伪造。
10. 小结
这套"LoRa 空口 + W5500 局域网"的无线呼叫器方案,本质上是做了一个轻量网关:
- 发送端专注"按键事件可靠发出"
- 接收端专注"无线转网络,并提供稳定的 TCP 服务"
- 上位机则可以不断迭代,从简单显示到复杂联动都不影响底层链路
最重要的设计点是:让接收器做 TCP Server。这样系统部署和维护成本会低很多,也更符合"设备长期跑、电脑随时换"的现实场景。