Engine
A control structure that acts like the conductor of an orchestra, managing an ensemble of units. It handles their initialization, updates, and timing, ensuring that all components remain synchronized.
By default, all units are automatically added to the primary engine which can be accessed using the
global object Plaquette
. By using secondary engines you can organize and optimize your code,
allowing for multi-tasking, grouping units, switching between ensembles of units, and save power by
running engines at lower frequency.
Usage
To create and use an engine, simply declare it:
Engine myEngine;
To assign units to a specific engine, add it as the last parameter at construction:
Wave wave(1.0, 0.2, myEngine); // Use myEngine instead of the default
Each engine provides its own time measurements:
float sec = myEngine.seconds(); // Time since engine started, in seconds
uint32_t ms = myEngine.milliSeconds(); // Time in milliseconds
uint64_t us = myEngine.microSeconds(); // Time in microseconds
You will need to call the engine’s begin()
function at initialization, and then its step()
function
at a regular pace.
Sample Rate
The Engine step()
function computes timings and peforms background update operations on units.
It is possible to set a specific (target) sample rate using sampleRate(rate)
to reduce computation load
for operations that do not need to be performed as fast as possible.
The engine’s step()
function returns:
true
if the step has been fully performed
false
if it is still waiting for the next “tick”
As an example, if one sets a 100 Hz sample rate on engine myEngine
by calling
myEngine.sampleRate(100)
, the myEngine.step()
function should return true
about 100 times
per second and false
otherwise.
To fully support custom sample rates and avoid performing unnecessary operations on units, the
step()
function should be used as a guard condition
in the main stepping loop.
void begin() {
myEngine.sampleRate(100); // Target sample rate: 100 Hz.
}
void loop() {
if (!myEngine.step()) // Guard condition.
return; // Exit the loop.
// The operations below will be performed at ~100 Hz.
if (button)
wave >> led;
...
}
For more in-depth explanations and examples please read Synchronizing Groups of Units with Secondary Engines.
Example
This example demonstrates the use of a secondary engine on an Arduino Uno or Nano using timer2 interrupt.
#include <Plaquette.h>
Engine timerEngine; // The secondary timer engine.
Metronome serialMetro(1.0); // Metronome (primary engine).
Metronome toggleMetro(0.25, timerEngine); // Metronome (timer engine).
DigitalOut led(LED_BUILTIN, timerEngine); // Built-in LED (timer engine).
// Primary engine begin().
void begin() {
timerEngine.begin(); // Begin timer engine.
timerSetup(); // Initialize timer interrupt timer2.
}
// Primary engine step().
void step() {
if (serialMetro)
println("step");
}
// Timer2 interrupt: will be called at 1kHz frequency.
ISR(TIMER2_COMPA_vect) {
timerEngine.step(); // Step engine.
if (toggleMetro) // Toggle LED on metro bang.
led.toggle();
}
// Timer2 setup for 1kHz on AVR.
void timerSetup() {
// Stop Timer2
TCCR2A = 0;
TCCR2B = 0;
TCNT2 = 0;
// Set compare match register for 1 kHz increments.
// 16 MHz / (prescaler * 1000) - 1 = OCR2A
// Try prescaler = 128 => OCR2A = (16e6 / (128 * 1000)) - 1 = ~124
OCR2A = 124;
TCCR2A |= (1 << WGM21); // CTC mode (Clear Timer on Compare Match).
TCCR2B |= (1 << CS22) | (1 << CS20); // Set prescaler to 128.
TIMSK2 |= (1 << OCIE2A); // Enable Timer2 compare interrupt.
sei(); // Enable global interrupts.
}
Reference
-
class Engine
The main Plaquette static class containing all the units.
Public Functions
-
void preBegin(unsigned long baudrate = PLAQUETTE_SERIAL_BAUD_RATE)
Initializes all components (calls begin() on all of them).
-
void postBegin()
Performs additional tasks after the class to begin().
-
inline bool timeStep()
Performs additional tasks after the class to step().
- Returns
true if the program should
-
inline void begin(unsigned long baudrate = PLAQUETTE_SERIAL_BAUD_RATE)
Function to be used within the PlaquetteLib context (needs to be called at top of setup() method).
-
inline bool step()
Function to be used within the PlaquetteLib context (needs to be called at top of loop() method).
-
inline void end()
Optional function to be used within the PlaquetteLib context.
No need to call it if the program is looping indefinitely. Call if the program stops at some point.
-
inline size_t nUnits()
Returns the current number of units.
-
float seconds(bool referenceTime = true) const
Returns time in seconds.
Optional parameter allows to ask for reference time (default) which will yield the same value through one iteration of step(), or “real” time which will return the current total running time.
- Parameters
referenceTime – determines whether the function returns the reference time or the real time
- Returns
the time in seconds
-
uint32_t milliSeconds(bool referenceTime = true) const
Returns time in milliseconds.
Optional parameter allows to ask for reference time (default) which will yield the same value through one iteration of step(), or “real” time which will return the current total running time.
- Parameters
referenceTime – determines whether the function returns the reference time or the real time
- Returns
the time in milliseconds
-
uint64_t microSeconds(bool referenceTime = true) const
Returns time in microseconds.
Optional parameter allows to ask for reference time (default) which will yield the same value through one iteration of step(), or “real” time which will return the current total running time.
- Parameters
referenceTime – determines whether the function returns the reference time or the real time
- Returns
the time in microseconds
-
inline unsigned long nSteps() const
Returns number of steps.
-
inline bool hasAutoSampleRate() const
Returns true iff the auto sample rate mode is enabled (default).
-
void autoSampleRate()
Enables auto sample rate mode (default).
-
void sampleRate(float sampleRate)
Sets sample rate to a fixed value, thus disabling auto sampling rate.
-
void samplePeriod(float samplePeriod)
Sets sample period to a fixed value, thus disabling auto sampling rate.
-
inline float sampleRate() const
Returns sample rate.
-
inline float samplePeriod() const
Returns sample period.
-
inline uint32_t deltaTimeMicroSeconds() const
Returns time between steps (in microseconds).
-
inline float deltaTimeSecondsTimesFixed32Max() const
Returns time between steps, expressed in fixed point propotion.
-
bool randomTrigger(float timeWindow)
Randomly triggers an event about once per time window, on average.
Call this function once in each step(). It will occasionally return true, with the frequency adjusted so that you get roughly one event for each
timeWindow
period, no matter how fast your loop is running.- Parameters
timeWindow – duration of the window (in seconds)
- Returns
true when an event occurs during this sample
-
void preBegin(unsigned long baudrate = PLAQUETTE_SERIAL_BAUD_RATE)