From a381ce9664bed4aeae3ca494eabf2cc69226e568 Mon Sep 17 00:00:00 2001 From: Glenn Pringle Date: Fri, 17 Jul 2026 11:44:54 +1000 Subject: [PATCH] feat: broadcast VRx-initiated channel changes over ESP-NOW When the goggles send MSP_ELRS_BACKPACK_SET_CHANNEL_INDEX (0x0301) up the UART (HDZero "Send VTX" / channel follow), the VRX backpack previously dropped it - the UART dispatch only handled SET_MODE, GET_VERSION, GET_STATUS and SET_PTR. Forward it via ESP-NOW as MSP_SET_VTX_CONFIG (89), the opcode peers act on over the air: VRX backpacks in the bind group retune their goggles, and TX backpacks already pass it to the handset (ProcessMSPPacketFromPeer), enabling VTX admin to follow the goggle channel. Guarded to command packets with a valid 48-entry table index. No echo risk: the goggles send no response to 0x0301, the sender does not receive its own ESP-NOW broadcast, and receivers dedup an unchanged channel. --- src/module_base.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/module_base.cpp b/src/module_base.cpp index 989eb4e3..68558d5e 100644 --- a/src/module_base.cpp +++ b/src/module_base.cpp @@ -159,6 +159,21 @@ MSPModuleBase::Loop(uint32_t now) ptrChannelData[2] = packet->payload[4] + (packet->payload[5] << 8); sendMSPViaEspnow(packet); } + else if (packet->function == MSP_ELRS_BACKPACK_SET_CHANNEL_INDEX && + packet->type == MSP_PACKET_COMMAND && + packet->payloadSize >= 1 && packet->payload[0] < 48) + { + // VRx-initiated channel change (e.g. HDZero goggles "Send VTX"): + // rebroadcast over ESP-NOW as MSP_SET_VTX_CONFIG, the opcode + // peers act on over the air; 0x0301 is only a UART opcode and + // is dropped as unknown by ESP-NOW receivers. + mspPacket_t out; + out.reset(); + out.makeCommand(); + out.function = MSP_SET_VTX_CONFIG; + out.addByte(packet->payload[0]); + sendMSPViaEspnow(&out); + } msp.markPacketReceived(); } }