Skip to content

TotemApp

Totem App connect discover RoboBoard

TotemApp. object allows to interact with Totem App, TotemLibrary and get connection events or value changes when button is pressed. Combination of app button editor and RoboBoard programming creates ability to make custom remote controls for particular robot or embedded application.
Available for Android and iOS.

See guide Custom functions for more detail instructions on executing custom actions on app button press.

Related configuration functions: Board.setStatusRGB() and Board.setStatusSound().

Enabled automatically if TotemApp is used inside the code.
Enabling this feature increases compiled binary size by 800KB.


Code snippets

// Got Totem App specific event
void appEvent(int evt, int value) {
  if (evt == TotemApp.evtFunctionA) {
    Serial.print("Got '/0/functionA': "); Serial.println(value);
  }
  if (evt == TotemApp.evtConnect) {
    Serial.println("Totem App connected");
  }
  if (evt == TotemApp.evtDisconnect) {
    Serial.println("Totem App disconnected");
  }
}
// Override function called on app button click
// Allows to modify value before RoboBoard processes it
bool appOverride(int cmd, int value) {
  if (cmd == TotemApp.cmdPosA) { // Invert "/0/serv/posA" direction
    Servo.A.spinPos(-value); // Set servo position
    return false; // Block app command (override)
  }
  if (cmd == TotemApp.cmdPowerA) { // Limit "/0/dc/powerA" to [-50:50]
    if (value >= -50 && value <= 50) return true; // Allow app command
    // value is above limit. Constrain it
    DC.A.spin(constrain(value, -50, 50)); // Write motor power
    return false; // Block app command (override)
  }
  // Allow other app commands to be processed by RoboBoard
  return true;
}
void setup() {
  Serial.begin(115200);
  // Register TotemApp event function
  TotemApp.addEvent(appEvent);
  // Register Totem App override function
  TotemApp.addOverride(appOverride);
}
// Loop program
void loop() {
  // Empty
}

Runtime control

TotemApp.begin()

TotemApp.begin(name)

Start Totem App service. Board will be discoverable in connect menu.
Note: call to any other TotemApp function will enable this service internally, so TotemApp.begin() is not mandatory.
Parameter: name - (optional) change board name displayed in Totem App.

TotemApp.disconnect()

Force to disconnect Totem App.

state TotemApp.wait()

state TotemApp.wait(time)

Wait for Totem App to connect (block code until).
Parameter: time - maximum time to wait (ms) for app connection. 0 - disabled.
Returns: state - true if connected, false if timeout.

Receive events

Warning

At the moment evtFunction is only available with Android version of Totem App.
Use Override commands as an alternative for iOS.

TotemApp.addEvent(function)

Register function to receive data sent from Totem App. Available event types:
evtFunctionA - topic /0/functionA data received.
evtFunctionB - topic /0/functionB data received.
evtFunctionC - topic /0/functionC data received.
evtFunctionD - topic /0/functionD data received.
evtConnect - Totem App connected.
evtDisconnect - Totem App disconnected.
Parameter:
function - function name [appEvent].

void appEvent(int evt, int value) {
  if (evt == TotemApp.evtFunctionA) {
    Serial.print("Function A: "); Serial.println(value);
  }
  if (evt == TotemApp.evtFunctionB) {
    Serial.print("Function B: "); Serial.println(value);
  }
  if (evt == TotemApp.evtFunctionC) {
    Serial.print("Function C: "); Serial.println(value);
  }
  if (evt == TotemApp.evtFunctionD) {
    Serial.print("Function D: "); Serial.println(value);
  }
  if (evt == TotemApp.evtConnect) {
    Serial.println("Totem App connected");
  }
  if (evt == TotemApp.evtDisconnect) {
    Serial.println("Totem App disconnected");
  }
}
void setup() {
  Serial.begin(115200);
  TotemApp.addEvent(appEvent); // Register TotemApp event function
}
void loop() {

}

Override commands

Functionality allowing to intercept commands sent by Totem App. Typically button press will apply motor power directly (e.g. /0/dc/powerADC.A.spin()). Any action will be presented in bool appOverride(int cmd, int value) function, providing value and ability to choose either block or allow RoboBoard to process this command.

Can be used to intercept standard "Model" controls and make your own drive logic or actions.

List of app commands:

TotemApp.cmdPosA - topic /0/serv/posA.
TotemApp.cmdPosB - topic /0/serv/posB.
TotemApp.cmdPosC - topic /0/serv/posC.
TotemApp.cmdPowerA - topic /0/dc/powerA.
TotemApp.cmdPowerB - topic /0/dc/powerB.
TotemApp.cmdPowerC - topic /0/dc/powerC.
TotemApp.cmdPowerD - topic /0/dc/powerD.
TotemApp.cmdFunctionA - topic /0/functionA.
TotemApp.cmdFunctionB - topic /0/functionB.
TotemApp.cmdFunctionC - topic /0/functionC.
TotemApp.cmdFunctionD - topic /0/functionD.

Known behavior

Totem App always sends cmdPowerA, cmdPowerB, cmdPowerC, cmdPowerD as a single message. Even if /0/dc/powerA is the only one set - others will trigger event with value 0.

TotemApp.addOverride(function)

Register function to override commands sent from Totem App.
Function declaration: bool appOverride(int cmd, int value)
cmd - command identifier. value - integer sent from app.
Use return false to block command and return true to allow it.
Parameter:
function - function name [appOverride].
Note: this function is called from Bluetooth environment, running on Core 0. It is not recommended to use heavy operations (like print or delay) inside function body.

// Override function called on app button click
bool appOverride(int cmd, int value) {
  if (cmd == TotemApp.cmdPosA) {
    Serial.print("/0/serv/posA -> "); Serial.println(value);
  }
  if (cmd == TotemApp.cmdPosB) {
    Serial.print("/0/serv/posB -> "); Serial.println(value);
  }
  if (cmd == TotemApp.cmdPosC) {
    Serial.print("/0/serv/posC -> "); Serial.println(value);
  }
  if (cmd == TotemApp.cmdPowerA) {
    Serial.print("/0/dc/powerA -> "); Serial.println(value);
  }
  if (cmd == TotemApp.cmdPowerB) {
    Serial.print("/0/dc/powerB -> "); Serial.println(value);
  }
  if (cmd == TotemApp.cmdPowerC) {
    Serial.print("/0/dc/powerC -> "); Serial.println(value);
  }
  if (cmd == TotemApp.cmdPowerD) {
    Serial.print("/0/dc/powerD -> "); Serial.println(value);
  }
  // This function requires return!
  // `true` - pass received command back to RoboBoard
  // `false` - RoboBoard won't get this command (override)
  return false;
}
// Initialize program
void setup() {
  Serial.begin(115200);
  // Register Totem App override function
  TotemApp.addOverride(appOverride);
}
// Loop program
void loop() {
  // Empty
}

Totem Library

Exchange user defined data between RoboBoard and Totem Arduino library.
It can be used to simulate Totem iOS/Android app and remotely control the board from any other ESP32 Arduino development board.

TotemApp.addOnSend(function)

Register receive functions for remote sendValue, sendString in TotemArduino library.
It accepts value and string functions. Both can be added at the same time.
Note: will be renamed to TotemApp.addOnReceive().
Parameter:
function - void onReceiveValue(int id, int value)
function - void onReceiveString(int id, String str)

// Intercept value sent by sendValue() (from Totem Library)
void onReceiveValue(int id, int value) {

}
// Intercept string sent by sendString() (from Totem Library)
void onReceiveString(int id, String string) {

}
void setup() {
  // Start Totem App service
  TotemApp.begin();
  // Register receive value handlers
  TotemApp.addOnSend(onReceiveValue);
  TotemApp.addOnSend(onReceiveString);
}

TotemApp.addOnRead(function)

Register read handlers for remote readValue, readString in TotemArduino library.
It accepts value and string functions. Both can be added at the same time.
Parameter:
function - int onReadValue(int id)
function - String onReadString(int id)

// Return value requested by readValue() (from Totem Library)
int onReadValue(int id) {
  return 0;
}
// Return string requested by readString() (from Totem Library)
String onReadString(int id) {
  return "";
}
void setup() {
  // Start Totem App service
  TotemApp.begin();
  // Register read value handlers
  TotemApp.addOnRead(onReadValue);
  TotemApp.addOnRead(onReadString);
}

state TotemApp.sendValue(id, value)

Send 32-bit value to TotemArduino library. Receive using addOnReceive().
Parameter:
id - 32-bit identifier
value - 32-bit value
Returns:
state - send [true]-success, [false]-error

Function sendString bug

Calling TotemApp.sendString(10, "Message") will send empty message. Temporary fix:

  • Wrap message into String() object TotemApp.sendString(10, String("Message"))

state TotemApp.sendString(id, string)

Send string (text) to TotemArduino library. Receive using addOnReceive().
Parameter:
id - 32-bit identifier
string - String object
Returns:
state - send [true]-success, [false]-error

state TotemApp.sendString(id, data, len)

Send data array to TotemArduino library. Receive using addOnReceive().
Parameter:
id - 32-bit identifier
data - pointer to string or data array
len - data length
Returns:
state - send [true]-success, [false]-error