Live Tuning and Assets
Exposing sketch variables as sliders in Neuro Studio, and the asset store for data that must persist across power cycles.
The core distinguishes two kinds of value a host may set on the board. A parameter is a live knob: applied immediately, bounded, and deliberately not persisted. An asset is data the board must still have after a power cycle: a calibration, a lookup table, a frozen threshold. Live tuning handles parameters; the asset store handles assets.
Live tuning
A sketch registers a variable and Neuro Studio shows a slider for it. Dragging the slider changes the variable on the board immediately, and the sketch reads it as an ordinary variable.
static int32_t TARGET_HUE = 25;
static int32_t HUE_TOL = 18;
static float GAIN = 1.0f;
static uint8_t INVERT = 0;
void setup() {
n6_tune_hue("target hue", &TARGET_HUE); // 0 to 359; the host shows the colour
n6_tune_int("hue tol", &HUE_TOL, 0, 180);
n6_tune_float("gain", &GAIN, 0.1f, 4.0f);
n6_tune_bool("invert", &INVERT); // shown as a switch
}
void loop() {
if (hue_within(h, TARGET_HUE, HUE_TOL)) { /* ... */ }
}The board announces its registered parameters as a descriptor about once per second, and the host builds the panel from the descriptor. No change to Neuro Studio is required for a new sketch.
The panel's Copy as code function places the current values on the clipboard as C literals for pasting into the sketch. Nothing is stored on the board.
Constraints
- A fixed table of 16 parameters. Registrations beyond that are ignored.
- Names are truncated to 15 characters.
- Registration is from
setup()only, and the variable must outlive the program: a static or global, never a local. - Values written by the host are clamped to the declared range.
- Floats cross the wire as integers in thousandths.
- Registering the same variable twice adds a second entry.
Uses in the examples
The AprilTag reader registers its three detector thresholds. The blob tracker registers its hue, tolerance, saturation and value gates. The audio event detector registers its confidence threshold. In each case the values are found against a real scene and then written into the sketch.
Asset store
An asset is written to flash by the bootloader and read by the application.
#include <n6_asset.h>
uint8_t buf[64]; uint32_t len, ver;
if (n6_asset_read(buf, sizeof(buf), &len, &ver)) {
// use the stored asset
} else {
// no asset stored: use compiled-in defaults
}
// writing: stage, then apply. apply() resets the board and does not return.
n6_asset_stage(payload, n, 0); // version 0 means "newer than whatever is stored"
n6_asset_apply();The false return from n6_asset_read() is the normal state of a new board and is always handled. n6_asset_present(&ver, &len) reports the stored size before a buffer is allocated; n6_asset_read() refuses a short buffer rather than truncating.
Reads are CRC-checked and retried internally, because mapped flash reads from the application are wrong about 0.9% of the time on this part.
The application never writes flash. n6_asset_apply() resets the board and the bootloader performs the write, so the board restarts once per asset write.
Camera calibration
The AprilTag pose functions use the asset mechanism for the camera intrinsics, written from the host with tools/push_calibration.py. See AprilTags and Pose.
Face bank
The face recognition example's bank of enrolled embeddings is held in RAM. Persisting it across power cycles uses the asset store.
Rationale
A parameter that survived a reboot would make the board's behaviour depend on what was once set in a user interface. Keeping parameters volatile and assets explicit is one of the rules of the host contract.
Bench sketch
AssetStoreTest in extras/bench writes and reads back an asset across a reset.