Skip to main content

First Module

A module is an ESP32-based subsystem that participates in an ArmorLink network.

Before a module can communicate with other modules, it must be paired with a Gateway.

For more information, see Modules.

What You Will Build

In this guide, you will create a minimal ArmorLink module.

The module will:

  • Run ArmorLink
  • Connect through ESP-NOW
  • Expose one Action
  • Be pairable with a Gateway

Create a New Sketch

Start with a new Arduino sketch.

#include <ArmorLink.h>

ArmorLinkModule module(
"Helmet",
ArmorLinkModuleType::Helmet
);

void toggleFaceplate()
{
ArmorLink.info("Toggle faceplate");
}

void setup()
{
Serial.begin(115200);

module.actions()
.add("toggleFaceplate")
.label("Toggle Faceplate")
.command("Facemask", "toggle")
.onExecute([]{
toggleFaceplate();
});

ArmorLinkOptions options;
options.enableGateway = false;
options.enableEspNow = true;
options.enableBle = false;

ArmorLink.begin(module, options);

ArmorLink.info("Helmet module started");
}

void loop()
{
ArmorLink.loop();
}

Upload the sketch to your ESP32.

Understanding the Module

Module Name

ArmorLinkModule module(
"Helmet",
ArmorLinkModuleType::Helmet
);

The module name identifies this module inside the ArmorLink network.

Module names should be unique.

Commands use this name as the target.

Module Type

ArmorLinkModuleType::Helmet

The module type is descriptive.

It helps the ArmorLink App organize and identify modules.

It does not affect routing or behavior.

Regular Module Mode

This module is not the Gateway.

options.enableGateway = false;

A regular module communicates through the Gateway.

It can:

  • Receive Commands
  • Execute Actions
  • Send Commands
  • Expose Configuration
  • Publish Telemetry
  • Send Remote Logs when requested

ESP-NOW

options.enableEspNow = true;

ESP-NOW is required for communication between modules and the Gateway.

BLE

options.enableBle = false;

Regular modules usually do not need BLE.

The ArmorLink App connects to the Gateway, not directly to each individual module.

Define an Action

Actions expose functionality through ArmorLink.

module.actions()
.add("toggleFaceplate")
.label("Toggle Faceplate")
.command("Facemask", "toggle")
.onExecute([]{
toggleFaceplate();
});

This Action reacts to:

  • Entity: Facemask
  • Command: toggle

When the module receives a matching Command, ArmorLink calls onExecute().

For more information, see Actions.

Pair the Module

Before the module can participate in the network, it must be paired with a Gateway.

  1. Upload and start the Gateway sketch
  2. Upload and start this module sketch
  3. Start pairing on the Gateway
  4. Accept the module

Pairing Through Serial

On the Gateway Serial Monitor:

start

Then list candidates:

candidates

You should see the module:

1) Helmet | Helmet | 34:85:18:12:34:56

Accept it:

pair 1

Check paired modules:

modules

For more information, see Pairing.

Send a Command to the Module

Once paired, another module can send a Command to the Helmet module:

ArmorLink.sendCommand(
"Helmet",
"Facemask",
"toggle"
);

The Command is routed through the Gateway.

The Helmet module receives it and executes the matching Action.

For more information, see Commands.

Sending Commands from Local Logic

A module can also send Commands from local firmware logic.

Example:

void btn1_handleClick()
{
ArmorLink.info("Button clicked");

ArmorLink.sendCommand(
"Helmet",
"Facemask",
"toggle"
);
}

The button handler is normal firmware logic.

The Command is the ArmorLink message sent through the network.

Add Configuration

Modules can expose persistent settings.

Example:

int brightness = 100;

module.config()
.addInt("brightness", &brightness, 100)
.label("Brightness")
.section("LEDs")
.range(0, 255)
.step(1);

Configuration values are stored locally on the module and can be changed through the ArmorLink App.

No reboot is required when values are changed.

For more information, see Configuration.

Add Telemetry

Modules can publish live runtime data when requested by the ArmorLink App.

Example:

void sendBatteryTelemetry()
{
float voltage = 4.12f;

ArmorLink.sendTelemetry(
"battery",
"voltage",
voltage,
"V"
);
}

Telemetry is only transmitted when requested by the App.

For more information, see Telemetry.

Complete Example with Configuration

#include <ArmorLink.h>

ArmorLinkModule module(
"Helmet",
ArmorLinkModuleType::Helmet
);

int brightness = 100;

void toggleFaceplate()
{
ArmorLink.info("Toggle faceplate");
}

void setup()
{
Serial.begin(115200);

module.actions()
.add("toggleFaceplate")
.label("Toggle Faceplate")
.command("Facemask", "toggle")
.onExecute([]{
toggleFaceplate();
});

module.config()
.addInt("brightness", &brightness, 100)
.label("Brightness")
.section("LEDs")
.range(0, 255)
.step(1);

ArmorLinkOptions options;
options.enableGateway = false;
options.enableEspNow = true;
options.enableBle = false;

ArmorLink.begin(module, options);

ArmorLink.info("Helmet module started");
}

void loop()
{
ArmorLink.loop();
}

Next Steps

You now have a basic ArmorLink module.

Continue with: