用 LoRa + W5500 做一个无线呼叫器

用 LoRa + W5500 做一个无线呼叫器:从按键到上位机的一条链路

无线呼叫器这种东西看起来简单:按一下按钮,另一端响一下、亮一下,最好还能把"哪个按钮触发的"显示在电脑上,方便做记录、联动更多逻辑(弹窗、语音播报、统计报表等)。

我这套方案的核心思路是把链路拆成两段:

  • 空口段 :按键端用 LoRa(LLCC68) 把"按键事件"发出去,距离远、穿透强、功耗可控。
  • 局域网段 :接收端把事件通过 以太网(W5500) 丢到局域网里,上位机用 TCP 接收并展示。

下面按"整体架构 → 关键选型 → 通信与协议 → 软件与实现要点 → 可扩展方向"把方案讲清楚。


1. 目标与约束

我希望这个呼叫器具备这些特性:

  1. 多按钮:一个发射端可以有多个按键,每个按键对应不同事件(例如不同房间、不同服务类型)。
  2. 一发一收:先做最小可用系统(一个发射器 + 一个接收器),但后续能扩展到多个发射器。
  3. 上位机可视化:接收端不仅本地指示(灯/蜂鸣器),还能把事件发给电脑显示/记录。
  4. 部署简单:更换电脑、改 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 客户端,那它必须"主动去连上位机"。这会带来两个现实问题:

  1. 接收器固件必须写死上位机 IP/端口
    电脑一换、IP 一变,就要改固件、重新烧录。
  2. 电脑端要保证随时在线
    不在线时接收器还要处理重连、超时、异常状态,逻辑复杂度上升。

反过来,让接收器作为 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 按键端要解决两件事

  1. 去抖动 :避免一次按下触发多次。
    可用定时器采样或简单延时确认(更推荐定时器方式)。
  2. 事件编码:至少要包含"谁发的 + 按了哪个键 + 什么时候"。

一个实用的 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:帧封装/解析、CRC
  • ui_led.c:按键反馈灯

流程(简化):

  1. 扫描到按键事件
  2. 生成帧(带 seq
  3. LoRa 发射
  4. 反馈灯闪烁(可选:发送成功/失败不同提示)

7.2 接收器固件(STM32)

模块划分建议:

  • lora_radio.c:收包、中断回调、RSSI/SNR 读取
  • net_w5500.c:W5500 初始化、TCP Server、发送队列
  • protocol.c:解析 LoRa 帧,生成 JSON
  • status_led.c:网络/数据指示

流程(简化):

  1. LoRa 中断提示收到数据
  2. 读包 → 校验 → 去重
  3. 组织 JSON 文本
  4. 若 TCP 已连接,发送;否则缓存或丢弃(看需求)

8. 可靠性:最小成本把"体验"做扎实

无线呼叫器真正让人崩溃的不是写不出来,而是"偶尔丢一下、偶尔重复一下"。

建议你至少做三件事:

  1. 序号去重 :接收端按 dev_id + seq 去重,避免按键抖动或重发导致重复弹窗。
  2. 重发策略 :发送端发一次后隔 50~150ms 再发 1~2 次(简单粗暴但有效)。
    如果要更严谨,可做 ACK(接收端回包确认),但复杂度会提高。
  3. 事件与状态分离 :按键"事件包"和设备"心跳包"分开。
    心跳包可以每隔几秒发一次,用于上位机显示"设备在线"。

9. 可扩展方向(后面想加功能就沿着这几条走)

  1. 多发射器 :给每个发射端分配 dev_id,上位机按设备分组显示。
  2. 更友好的上位机:从命令行打印升级到 GUI(PyQt/WinForms/Electron 都可)。
  3. 联动外设:接收端加蜂鸣器/继电器,按不同 key 触发不同动作。
  4. 数据落库与统计:上位机把 JSON 写入 SQLite/MySQL,做呼叫频率统计、响应时间统计。
  5. 安全性:需要的话可在协议层做简单加密/签名(例如 AES + rolling counter),防止被同频干扰伪造。

10. 小结

这套"LoRa 空口 + W5500 局域网"的无线呼叫器方案,本质上是做了一个轻量网关:

  • 发送端专注"按键事件可靠发出"
  • 接收端专注"无线转网络,并提供稳定的 TCP 服务"
  • 上位机则可以不断迭代,从简单显示到复杂联动都不影响底层链路

最重要的设计点是:让接收器做 TCP Server。这样系统部署和维护成本会低很多,也更符合"设备长期跑、电脑随时换"的现实场景。

相关推荐
YoungHong19922 小时前
C++ 硬核基础:为什么函数重载不能只看返回值?
开发语言·c++
我不会插花弄玉2 小时前
vector【由浅入深-C++】
c++
兵哥工控2 小时前
mfc静态文本控件背景及字体颜色设置实例
c++·mfc
hqzing2 小时前
C语言程序调用syscall的几种方式
linux·c++
疑惑的杰瑞2 小时前
【C】函数与数组
c语言·开发语言·算法·可变参数
迟熙2 小时前
你的return,真的return对了吗?
c++
superman超哥2 小时前
仓颉内存分配优化深度解析
c语言·开发语言·c++·python·仓颉
2401_841495642 小时前
并行程序设计与实现
c++·python·算法·cuda·mpi·并行计算·openmp
chenyuhao20242 小时前
Linux系统编程:多线程同步与单例模式
linux·服务器·c++·后端·单例模式