很多人最开始接触 Meshtastic,都是把它当成一个离线通讯工具:没有手机信号、没有 WiFi,也能用 LoRa 在设备之间发消息。
但如果你继续往下玩,就会发现 Meshtastic 其实还藏着一些很有意思的硬件联动能力。比如这篇要讲的 Remote Hardware 模块。
它做的事情很直接:允许你通过 Mesh 网络去读、写、监听另一台 Meshtastic 节点上的 GPIO 引脚。
换句话说,它不是让节点告诉你发生了什么而已,而是让节点真的能去碰一下外部世界:打开一个继电器、读取一个开关状态,或者在某个引脚变化时自动通过 LoRa 发出提醒。

这类功能听起来很像传统物联网,但有一个关键区别:它不依赖家里的宽带、蜂窝网络或者公网服务器。只要两台 Meshtastic 节点之间还能通过 LoRa 互通,你就仍然有一条低速但独立的控制链路。
Remote Hardware 到底能做什么
Remote Hardware 模块支持三类操作:
- 写 GPIO:把某个 GPIO 设置为高电平或低电平。
- 读 GPIO:读取某个 GPIO 当前是高电平还是低电平。
- 监听 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 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。

下面这张表可以直接查。比如你要读取 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 节点发出 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 节点发命令,让家里的节点切断路由器电源几秒钟,再重新合上。

例如用 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/