Skip to content

Driver Lifecycle

Advanced Topic Skip if you’re new, explore when you’re ready.

The firmware offers the following four overall lifecycle events, for you to add your own logic to.

BottangoArduinoCallbacks.cpp
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.

BottangoArduinoCallbacks.cpp
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.

BottangoArduinoCallbacks.cpp
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.

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:

BottangoArduinoCallbacks.cpp
#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.