Gateway Button Panel
This example shows how a Gateway can act as a central button command processor.
A common setup is:
Left Hand Button
|
v
Gateway
|
v
Local Action or Broadcast Command
This is useful when buttons, switches or sensors on one module should control behavior across the whole ArmorLink network.
For more information about Commands, see Commands.
What This Example Does
This example uses two modules:
- A
Left Handmodule that sends button Commands - A
ChestGateway that receives those Commands and reacts to them
The Gateway can then:
- Execute local behavior
- Play a sound
- Stop audio
- Broadcast a Command to multiple modules
- Trigger synchronized behavior across the network
Hand Module
The hand module reads a local button and sends a Command to the Gateway.
#include <ArmorLink.h>
#define BUTTON_PIN 4
ArmorLinkModule module(
"Left Hand",
ArmorLinkModuleType::Hand
);
bool lastButtonState = HIGH;
void setup()
{
Serial.begin(115200);
delay(500);
pinMode(BUTTON_PIN, INPUT_PULLUP);
ArmorLinkOptions options;
options.enableGateway = false;
options.enableEspNow = true;
options.enableBle = false;
options.enableSerialLogging = true;
ArmorLink.begin(module, options);
ArmorLink.info("Left Hand module started");
}
void loop()
{
ArmorLink.loop();
bool currentButtonState = digitalRead(BUTTON_PIN);
if (lastButtonState == HIGH && currentButtonState == LOW) {
handleButtonPress();
}
lastButtonState = currentButtonState;
}
void handleButtonPress()
{
ArmorLink.info("Left hand button pressed");
ArmorLink.sendCommand(
"Chest",
"BTN_L1",
"SINGLE_CLICK"
);
}
Gateway Module
The Gateway receives the Command from the hand module and reacts to it using an Action.
#include <ArmorLink.h>
ArmorLinkModule chestModule(
"Chest",
ArmorLinkModuleType::Chest
);
void stopAudio()
{
ArmorLink.info("Stopping audio");
}
void setup()
{
Serial.begin(115200);
delay(500);
chestModule.actions()
.add("leftBtn1SingleClick")
.label("Left BTN1 Single Click")
.command("BTN_L1", "SINGLE_CLICK")
.onExecute([]{
stopAudio();
});
ArmorLinkOptions options;
options.enableGateway = true;
options.enableEspNow = true;
options.enableBle = true;
options.enableSerialMenu = true;
options.enableSerialLogging = true;
options.bleName = "ArmorLink Gateway";
ArmorLink.begin(chestModule, options);
ArmorLink.info("Chest Gateway started");
}
void loop()
{
ArmorLink.loop();
}
Command Flow
The button module sends:
ArmorLink.sendCommand(
"Chest",
"BTN_L1",
"SINGLE_CLICK"
);
This means:
| Part | Value |
|---|---|
| Target | Chest |
| Entity | BTN_L1 |
| Command | SINGLE_CLICK |
The Gateway has a matching Action:
chestModule.actions()
.add("leftBtn1SingleClick")
.label("Left BTN1 Single Click")
.command("BTN_L1", "SINGLE_CLICK")
.onExecute([]{
stopAudio();
});
When the Command arrives, ArmorLink executes the Action locally on the Gateway.
Gateway Broadcast Example
The Gateway can also react to a button Command by broadcasting another Command to all modules.
Example:
chestModule.actions()
.add("leftBtn1SingleClick")
.label("Left BTN1 Single Click")
.command("BTN_L1", "SINGLE_CLICK")
.onExecute([]{
ArmorLink.broadcastCommand(
"Flaps",
"toggle"
);
});
Any module with a matching Action can react:
module.actions()
.add("toggleFlaps")
.label("Toggle Flaps")
.command("Flaps", "toggle")
.onExecute([]{
toggleFlaps();
});
This allows one button press to trigger behavior across multiple modules.
Broadcast Flow
Left Hand Button
|
v
sendCommand("Chest", "BTN_L1", "SINGLE_CLICK")
|
v
Chest Gateway Action
|
v
broadcastCommand("Flaps", "toggle")
|
v
All modules receive Command
|
v
Matching Actions execute
Modules without a matching Action ignore the Broadcast Command.
Multiple Button Actions
The Gateway can define multiple button Actions.
chestModule.actions()
.add("leftBtn1SingleClick")
.label("Left BTN1 Single Click")
.command("BTN_L1", "SINGLE_CLICK")
.onExecute([]{
ArmorLink.broadcastCommand("Flaps", "toggle");
});
chestModule.actions()
.add("leftBtn1DoubleClick")
.label("Left BTN1 Double Click")
.command("BTN_L1", "DOUBLE_CLICK")
.onExecute([]{
ArmorLink.broadcastCommand("Lights", "toggle");
});
chestModule.actions()
.add("leftBtn1LongPress")
.label("Left BTN1 Long Press")
.command("BTN_L1", "LONG_PRESS")
.onExecute([]{
ArmorLink.broadcastCommand("System", "shutdown_effects");
});
This pattern works well for glove buttons, hidden switches, magnetic reed switches and other local inputs.
Local Behavior and Network Behavior
A button handler can perform local behavior and send a Command.
Example:
void handleButtonPress()
{
ArmorLink.info("Button pressed");
// Local behavior
flashStatusLed();
// Network behavior
ArmorLink.sendCommand(
"Chest",
"BTN_L1",
"SINGLE_CLICK"
);
}
The local behavior remains normal firmware logic.
ArmorLink handles the network communication.
When to Use This Pattern
Use this pattern when:
- A hand controller should control other modules
- A hidden button should trigger a global effect
- A Gateway should centralize button logic
- Multiple modules should react to one event
- You want to keep button mapping in one central place
Next Steps
Continue with: