阳台浇花、重启路由器、门锁提醒:Meshtastic 的远程 GPIO 玩法

教程

很多人最开始接触 Meshtastic,都是把它当成一个离线通讯工具:没有手机信号、没有 WiFi,也能用 LoRa 在设备之间发消息。

但如果你继续往下玩,就会发现 Meshtastic 其实还藏着一些很有意思的硬件联动能力。比如这篇要讲的 Remote Hardware 模块。

它做的事情很直接:允许你通过 Mesh 网络去读、写、监听另一台 Meshtastic 节点上的 GPIO 引脚。

换句话说,它不是让节点告诉你发生了什么而已,而是让节点真的能去碰一下外部世界:打开一个继电器、读取一个开关状态,或者在某个引脚变化时自动通过 LoRa 发出提醒。

Meshtastic Remote Hardware 的三个典型场景:阳台浇花、路由器电源重启、门锁状态提醒

这类功能听起来很像传统物联网,但有一个关键区别:它不依赖家里的宽带、蜂窝网络或者公网服务器。只要两台 Meshtastic 节点之间还能通过 LoRa 互通,你就仍然有一条低速但独立的控制链路。

Remote Hardware 到底能做什么

Remote Hardware 模块支持三类操作:

  1. 写 GPIO:把某个 GPIO 设置为高电平或低电平。
  2. 读 GPIO:读取某个 GPIO 当前是高电平还是低电平。
  3. 监听 GPIO 变化:当某个 GPIO 状态变化时,通过 Mesh 网络收到通知。

这三个能力组合起来,就可以覆盖很多小型远程控制场景。

例如,把 GPIO 接到继电器或 MOSFET 控制板,就可以远程开关水泵、电磁阀、灯、插座等设备。把 GPIO 接到门磁、干簧管、限位开关、浮球开关,就可以读取门窗、水位、设备状态。

它和普通发一条消息给某个节点不一样。普通消息只能提醒人,Remote Hardware 则能让远端节点按照命令去改变一个真实引脚的电平。

GPIO 操作有真实硬件风险

GPIO 不是一个可以随便试试也没事的软件开关。错误的引脚、错误的电压、错误的接法,都可能损坏 Meshtastic 设备,甚至损坏外接设备。

不要用 GPIO 直接驱动电机、水泵、插座、电磁阀这类负载。GPIO 只能提供很小的电流,通常应通过继电器模块、MOSFET 驱动板、光耦隔离模块等电路去控制外部设备。

如果涉及 220V 市电插座,请使用合规成品智能插座、继电器模组和安全外壳。没有电工经验时,不建议自行改造市电线路。

先说一个限制:新固件可能需要自己编译

根据 Meshtastic 官方文档,从固件版本 2.5.3 之后,Remote Hardware 模块默认可能被构建参数排除。如果你使用的是较新的官方固件,可能会发现客户端里能看到配置项,但实际读写 GPIO 并不可用。

这种情况下,需要自行编译固件,并在 platformio.ini 中移除:

-DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1

另外,官方文档也提醒:虽然 Android、Apple、CLI 等客户端可能能配置这个模块,但目前真正执行 GPIO 读写与监听操作,主要还是通过 Meshtastic Python CLI 完成。Web 客户端暂未实现这个模块。

所以这篇文章会重点用 CLI 作为示例。

最小测试需要准备什么

如果你只是想验证 Remote Hardware,可以先准备两台 Meshtastic 设备:

  • 一台作为本地控制端,连接电脑 USB,用来运行 meshtastic 命令。
  • 一台作为远程执行端,放在阳台、弱电箱、门口等位置,负责接外部电路。

本地电脑连接一台 Meshtastic 节点,远程节点通过 LoRa 控制继电器与外部开关

还需要安装 Meshtastic Python CLI:

pip3 install --upgrade meshtastic

测试前建议先用 LED 和 220 欧姆电阻做实验,不要一上来就接水泵或插座。LED 亮灭能证明 GPIO 写入成功,风险也低得多。

启用 Remote Hardware 并创建 gpio 频道

为了防止不可信用户随便控制你的 GPIO,官方要求先创建一个专门的 gpio 频道,并把本地控制端和远程执行端都加入这个频道。

第一步,先把本地控制端通过 USB 接到电脑,启用模块:

meshtastic --set remote_hardware.enabled true

然后创建 gpio 频道:

meshtastic --ch-add gpio

查看设备信息,并复制输出里的完整频道 URL:

meshtastic --info

第二步,把远程执行端通过 USB 接到电脑,也启用模块:

meshtastic --set remote_hardware.enabled true

再把刚才复制的频道 URL 写入远程执行端:

meshtastic --seturl 你刚才复制的完整URL

完成后,两台设备应该都在同一个 gpio 频道里。可以先互发文本消息,或者运行下面命令确认节点列表里能看到对方:

meshtastic --nodes

如果远程节点完全不在节点列表里,先不要急着查 GPIO,应该先解决 LoRa 连通性问题。

GPIO mask 怎么理解

Remote Hardware 读取和监听 GPIO 时,会用到一个叫 mask 的值。

简单理解就是:mask 用一个十六进制数表示你要操作哪个 GPIO。

Remote Hardware 通过 mask 指定要读取或监听的 GPIO 引脚

下面这张表可以直接查。比如你要读取 GPIO 4,就用 0x10;要读取 GPIO 21,就用 0x200000

GPIO mask GPIO mask GPIO mask
GPIO 0 0x1 GPIO 15 0x8000 GPIO 30 0x40000000
GPIO 1 0x2 GPIO 16 0x10000 GPIO 31 0x80000000
GPIO 2 0x4 GPIO 17 0x20000 GPIO 32 0x100000000
GPIO 3 0x8 GPIO 18 0x40000 GPIO 33 0x200000000
GPIO 4 0x10 GPIO 19 0x80000 GPIO 34 0x400000000
GPIO 5 0x20 GPIO 20 0x100000 GPIO 35 0x800000000
GPIO 6 0x40 GPIO 21 0x200000 GPIO 36 0x1000000000
GPIO 7 0x80 GPIO 22 0x400000 GPIO 37 0x2000000000
GPIO 8 0x100 GPIO 23 0x800000 GPIO 38 0x4000000000
GPIO 9 0x200 GPIO 24 0x1000000 GPIO 39 0x8000000000
GPIO 10 0x400 GPIO 25 0x2000000 GPIO 40 0x10000000000
GPIO 11 0x800 GPIO 26 0x4000000 GPIO 41 0x20000000000
GPIO 12 0x1000 GPIO 27 0x8000000 GPIO 42 0x40000000000
GPIO 13 0x2000 GPIO 28 0x10000000 GPIO 43 0x80000000000
GPIO 14 0x4000 GPIO 29 0x20000000 GPIO 44 0x100000000000

注意,这张表只说明 mask 怎么写,不代表这些 GPIO 都适合使用。比如有些开发板的 GPIO 已经被 LoRa、屏幕、按键、GPS 或电池检测占用;ESP32 上的 GPIO 34 到 39 通常还是输入专用。正式接线前仍然要查你手上那块板子的原理图。

如果你想知道它背后的计算规则,其实就是:

GPIO N 的 mask = 2 的 N 次方

如果你不想心算,可以用 Python 快速生成:

for i in range(1, 45):
    print(f"GPIO:{i} mask:{hex(2**i)}")

写 GPIO 的时候,CLI 可以直接写 GPIO 编号。例如把远程节点的 GPIO 4 拉高:

meshtastic --port /dev/ttyUSB0 --gpio-wrb 4 1 --dest !远程节点ID

把 GPIO 4 拉低:

meshtastic --port /dev/ttyUSB0 --gpio-wrb 4 0 --dest !远程节点ID

读取 GPIO 4 时,则使用 mask:

meshtastic --port /dev/ttyUSB0 --gpio-rd 0x10 --dest !远程节点ID

如果返回的 gpio_value 和 mask 一致,表示这个 GPIO 当前为高电平;如果 gpio_value=0,表示为低电平。

监听 GPIO 4 的变化:

meshtastic --port /dev/ttyUSB0 --gpio-watch 0x10 --dest !远程节点ID

当远程节点上的 GPIO 4 状态变化时,CLI 会收到类似这样的消息:

Received RemoteHardware typ=GPIOS_CHANGED, gpio_value=16
Received RemoteHardware typ=GPIOS_CHANGED, gpio_value=0

下面用三个生活场景来理解这个功能。

场景一:远程给阳台花盆浇水

这是最容易理解的 Remote Hardware 控制场景。

假设你家阳台放了一台 Meshtastic 节点,旁边有一个小水箱、一只低压小水泵,或者一个电磁阀。Meshtastic 节点的某个 GPIO 不直接接水泵,而是接到 MOSFET 驱动板或继电器模块上。

阳台上的 Meshtastic 节点通过继电器和水泵控制花盆浇水

当你在外面想给花浇水时,只需要通过本地 Meshtastic 节点发出 GPIO 写入命令,远程节点就把对应 GPIO 拉高,驱动水泵启动。

例如使用 GPIO 4 控制水泵启动:

meshtastic --port /dev/ttyUSB0 --gpio-wrb 4 1 --dest !阳台节点ID

浇水 10 秒后关闭:

meshtastic --port /dev/ttyUSB0 --gpio-wrb 4 0 --dest !阳台节点ID

如果担心命令发出后不知道水泵是否真的被打开,可以再读一次 GPIO 4:

meshtastic --port /dev/ttyUSB0 --gpio-rd 0x10 --dest !阳台节点ID

这种方案的优点是结构简单:不需要阳台有 WiFi,不需要把水泵接入云平台,只要 LoRa 链路能到,命令就能送过去。

但真正落地时,建议至少加上几个保护:

  • 水泵使用低压直流电源,不要把市电直接引到潮湿环境里。
  • 用 MOSFET 或继电器模块隔离 GPIO 和负载。
  • 机械上保证水管脱落时不会喷到电路板。
  • 最好加一个最长运行时间保护,避免误操作导致水泵一直工作。

Remote Hardware 本身只是写 GPIO,它并不知道水箱有没有水,也不知道花盆是否已经浇够。所以如果你要做成长期可靠的自动浇水系统,后续可以再加土壤湿度、水位、漏水检测等传感器。

场景二:家里断网时,用 LoRa 重启路由器电源

这个场景非常适合 Meshtastic。

很多人家里都有远程访问需求:NAS、家庭服务器、摄像头、Home Assistant、OpenWrt、旁路由,平时都能通过互联网连回家里。问题是,一旦光猫、路由器或交换机卡死,最需要远程处理的时候,反而最处理不了。

因为你失去的正是那条互联网链路。

这时如果家里有一台常供电的 Meshtastic 节点,旁边再接一个能控制路由器电源的继电器或插座,就可以保留一条和互联网无关的最后控制通道。

基本结构可以是:

  • 路由器电源接在一个受控插座或低压继电器电源模块后面。
  • Meshtastic 节点常供电,最好由独立电源或电池供电。
  • GPIO 控制继电器断开和闭合。
  • 外出时用另一台 Meshtastic 节点发命令,让家里的节点切断路由器电源几秒钟,再重新合上。

家中弱电架上的 Meshtastic 节点通过 LoRa 作为路由器电源重启的备用控制通道

例如用 GPIO 4 控制路由器电源继电器:

meshtastic --port /dev/ttyUSB0 --gpio-wrb 4 0 --dest !家里节点ID

等待 5 到 10 秒后恢复供电:

meshtastic --port /dev/ttyUSB0 --gpio-wrb 4 1 --dest !家里节点ID

具体高电平代表开还是关,取决于你使用的继电器模块是高电平触发还是低电平触发。正式接路由器前,务必先用 LED 或万用表测试清楚。

不要让控制节点和路由器共用同一个被控电源

如果 Meshtastic 节点和路由器插在同一个被你切断的插座上,那么你发出断电命令后,Meshtastic 节点也会一起断电,后面的恢复供电命令就发不进去了。

这个场景里,Meshtastic 控制节点最好使用独立电源,或者至少不经过同一个受控插座。

这个方案看起来有点笨,但在真实维护里很实用。互联网远程管理失败时,LoRa 仍然可能覆盖到小区附近、楼下、屋顶节点,甚至通过 mesh 中继绕回来。它不适合传大量数据,却很适合发一条重启电源的小命令。

场景三:读取门锁状态,有人开门就发 LoRa 提醒

Remote Hardware 不只能控制输出,也能读取输入。

如果你在门锁、门框、柜门或设备外壳上安装门磁、干簧管、微动开关,就可以把开关状态接到 Meshtastic 节点的 GPIO 上。门打开时 GPIO 状态变化,门关上时状态再变化。

你可以在本地电脑上监听远程门锁节点的 GPIO:

meshtastic --port /dev/ttyUSB0 --gpio-watch 0x10 --dest !门口节点ID

当门被打开或关闭时,你会收到状态变化通知。假设 GPIO 4 的 mask 是 0x10,那么:

Received RemoteHardware typ=GPIOS_CHANGED, gpio_value=16
Received RemoteHardware typ=GPIOS_CHANGED, gpio_value=0

你可以根据接线方式判断 16 是开门还是关门。

这个功能适合做一些低频状态提醒,比如:

  • 家门是否被打开。
  • 院门、车库门是否关好。
  • 户外设备箱是否被打开。
  • 某个机械限位是否到位。

但它不适合捕捉非常快的瞬间动作。官方文档也特别提醒,Remote Hardware 的 GPIO 监听不能可靠检测很快的变化,例如一闪而过的按钮按下。如果你的目标是检测按钮、震动、短脉冲,应该优先研究 Meshtastic 的 Detection Sensor 模块,或者在外部 MCU 上先做消抖和状态保持。

门锁状态这种场景相对合适,因为门的开关通常不会只持续几毫秒。

和 Remote Admin、Serial、Telemetry 有什么区别

Meshtastic 里有好几个看起来都像远程控制或硬件扩展的功能,很容易混在一起。

Remote Admin 是远程管理 Meshtastic 节点本身的配置,比如改频道、改角色、改模块设置。

Serial Module 是通过串口让 Meshtastic 和外部 MCU 或上位机交换消息。

Telemetry 更偏向上报传感器数据,比如温湿度、电压、电流、空气质量。

Remote Hardware 则更直接:它面对的是 GPIO 引脚本身。你让某个引脚高,它就高;你读某个引脚,它就返回当前状态;你监听某个引脚,它变了就通知你。

所以它适合小规模、明确、低频的硬件动作。比如开关一个继电器、读一个门磁、确认一个设备状态。

如果你要做复杂逻辑,比如根据多个传感器自动判断、定时浇水、失败重试、状态机控制,那就应该让外部 MCU 或 Home Assistant 承担主要逻辑,Meshtastic 只负责传命令和传状态。

实际部署最容易踩的坑

第一个坑,是选错 GPIO。

很多开发板上的 GPIO 已经被 LoRa 模块、屏幕、按键、GPS、电池检测占用。有些 GPIO 还是输入专用,不能作为输出。正式接线前一定要查你手上那块板子的原理图和引脚定义,不要照搬别人文章里的编号。

第二个坑,是让 GPIO 直接带负载。

GPIO 不是电源输出口。它可以给控制电路一个信号,但不应该直接驱动水泵、电机、继电器线圈或插座。涉及感性负载时,还要考虑续流二极管、隔离、浪涌和供电能力。

第三个坑,是忽略安全频道。

Remote Hardware 需要 gpio 频道,是为了限制谁能发 GPIO 控制命令。不要把控制家里电源、水泵、门锁状态的频道 URL 随便发给别人,也不要用默认公开频道承载这类控制能力。

第四个坑,是把它当成实时控制总线。

LoRa Mesh 的优势是远距离、低功耗、弱基础设施依赖,不是低延迟和高吞吐。Remote Hardware 适合开一下、关一下、读一次、状态变化提醒一次,不适合高速 PWM、连续电机控制、毫秒级反馈。

第五个坑,是没有设计失败状态。

远程控制最怕命令发了一半。例如你发了打开水泵的命令,但关闭命令没发到;或者你断开了路由器电源,却因为控制节点也断电导致无法恢复。凡是会造成真实后果的动作,都应该优先设计默认安全状态。

总结

Remote Hardware 是 Meshtastic 里一个非常实用的功能。

它没有漂亮的图形界面,也不像聊天和地图那样一眼就能看到效果,但它把 LoRa Mesh 从远程通信往远程动作推进了一步。

阳台浇花、断网重启路由器、门锁状态提醒,这三个例子其实代表了三类典型能力:

  • 远程输出控制:让某个设备启动或停止。
  • 独立应急通道:在互联网不可用时保留一条低速控制链路。
  • 远程状态感知:让门磁、开关、限位状态进入 Mesh 网络。

如果你只是想玩一玩,先从 LED 开始。如果你要接水泵、插座、门锁这类真实设备,就把电气安全、默认状态、权限隔离和失败恢复设计好。

Meshtastic 的魅力不只是没有网络也能说话,有时候还可以是:没有网络,也能让远处的一根引脚动一下。

参考资料

本文作者: Hays Chan | 陈希

本文链接: https://meshcn.net/meshtastic-remote-hardware-gpio-control/