Zum Hauptinhalt springen

Gateway Button Panel

Dieses Beispiel zeigt, wie ein Gateway als zentrale Verarbeitungsinstanz für Button-Commands fungieren kann.

Ein häufiges Setup sieht folgendermaßen aus:

Left Hand Button
|
v
Gateway
|
v
Local Action or Broadcast Command

Dies ist besonders nützlich, wenn Buttons, Schalter oder Sensoren auf einem Module Verhalten im gesamten ArmorLink-Netzwerk steuern sollen.

Weitere Informationen zu Commands findest du unter Commands.

Was dieses Beispiel macht

Dieses Beispiel verwendet zwei Modules:

  • Ein Left Hand Module, das Button-Commands sendet
  • Ein Chest Gateway, das diese Commands empfängt und darauf reagiert

Das Gateway kann anschließend:

  • Lokales Verhalten ausführen
  • Sounds abspielen
  • Audio stoppen
  • Commands an mehrere Modules broadcasten
  • Synchronisierte Aktionen im gesamten Netzwerk auslösen

Hand-Module

Das Hand-Module liest einen lokalen Button aus und sendet einen Command an das 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

Das Gateway empfängt den Command vom Hand-Module und reagiert darauf über eine 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-Ablauf

Das Button-Module sendet:

ArmorLink.sendCommand(
"Chest",
"BTN_L1",
"SINGLE_CLICK"
);

Das bedeutet:

TeilWert
TargetChest
EntityBTN_L1
CommandSINGLE_CLICK

Das Gateway besitzt eine passende Action:

chestModule.actions()
.add("leftBtn1SingleClick")
.label("Left BTN1 Single Click")
.command("BTN_L1", "SINGLE_CLICK")
.onExecute([]{
stopAudio();
});

Sobald der Command eintrifft, führt ArmorLink die Action lokal auf dem Gateway aus.

Gateway-Broadcast-Beispiel

Das Gateway kann auf einen Button-Command reagieren, indem es einen weiteren Command an alle Modules broadcastet.

Beispiel:

chestModule.actions()
.add("leftBtn1SingleClick")
.label("Left BTN1 Single Click")
.command("BTN_L1", "SINGLE_CLICK")
.onExecute([]{
ArmorLink.broadcastCommand(
"Flaps",
"toggle"
);
});

Jedes Module mit einer passenden Action kann darauf reagieren:

module.actions()
.add("toggleFlaps")
.label("Toggle Flaps")
.command("Flaps", "toggle")
.onExecute([]{
toggleFlaps();
});

Dadurch kann ein einzelner Tastendruck Verhalten auf mehreren Modules gleichzeitig auslösen.

Broadcast-Ablauf

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 ohne passende Action ignorieren den Broadcast-Command.

Mehrere Button-Actions

Das Gateway kann mehrere Button-Actions definieren.

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");
});
``>

Dieses Muster eignet sich hervorragend für Handschuh-Buttons, versteckte Schalter, Reed-Schalter und andere lokale Eingaben.

## Lokales Verhalten und Netzwerkverhalten

Ein Button-Handler kann lokales Verhalten ausführen und gleichzeitig einen Command senden.

Beispiel:

```cpp
void handleButtonPress()
{
ArmorLink.info("Button pressed");

// Local behavior
flashStatusLed();

// Network behavior
ArmorLink.sendCommand(
"Chest",
"BTN_L1",
"SINGLE_CLICK"
);
}

Das lokale Verhalten bleibt normale Firmware-Logik.

ArmorLink übernimmt die Netzwerkkommunikation.

Wann dieses Pattern sinnvoll ist

Verwende dieses Pattern, wenn:

  • Ein Hand-Controller andere Modules steuern soll
  • Ein versteckter Button einen globalen Effekt auslösen soll
  • Ein Gateway die Button-Logik zentralisieren soll
  • Mehrere Modules auf dasselbe Ereignis reagieren sollen
  • Du das Button-Mapping zentral verwalten möchtest

Nächste Schritte

Weiter mit: