Driver Lifecycle
The firmware offers the following four overall lifecycle events, for you to add your own logic to.
onThisControllerStarted
Section titled “onThisControllerStarted”void onThisControllerStarted(){}This callback is called after a successful handshake with the desktop app, but before effectors are registered. If you have effector specific startup needs, you should use the specific effector registered callback described below.
onThisControllerStopped
Section titled “onThisControllerStopped”void onThisControllerStopped(){}This callback is called after the driver receives a stop command and shuts down. The driver will stop all movement, deregister all effectors, and then call this callback.
onEarlyLoop and onLateLoop
Section titled “onEarlyLoop and onLateLoop”void onEarlyLoop(){}
void onLateLoop(){}These two loop callbacks provide easy access into the overall Arduino loop. Early loop happens before all effectors process their movement for this loop cycle, and late happens after. These are useful for if you have your own timing code you’d like to implement, independent of the Bottango animation timeline.
Example Usage
Section titled “Example Usage”These callbacks are used in the example code for custom exported animation playback logic and controlling the desktop app. You could also use them for your own unrelated logic. Here’s an example that logs to serial when the firmware starts, stops, and every 1 second in animation time:
#include "BottangoArduinoCallbacks.h"#include "src/AbstractEffector.h"#include "src/Outgoing.h"#include "src/BottangoCore.h"#include "src/Time.h" // added to get firmware animation time
namespace Callbacks{ unsigned long lastLogTime = 0;
void onThisControllerStarted() { Outgoing::printOutputStringFlash(F("I started!")); Outgoing::printLine(); }
void onThisControllerStopped() { Outgoing::printOutputStringFlash(F("I stopped!")); Outgoing::printLine(); }
void onEarlyLoop() { unsigned long now = Time::getCurrentTimeInMs(); if (now - lastLogTime >= 1000) { Outgoing::printOutputStringFlash(F("Current Animation Time: ")); Outgoing::printOutputStringMem(now); Outgoing::printLine();
lastLogTime = now; } }
// Rest of Callbacks File, etc.}#include “src/Time.h” was included to get access to the current firmware animation time.
The Outgoing namespace functions are used because it’s not always guaranteed that the firmware is communicating over serial. In this case, Serial.print() would be functionally identical, but the Outgoing namespace wraps the different communication strategies into a single call if you want the portability.