Known issues
SDK 1.xWritten for core 1.53+ and gui 1.23+.
A handful of SDK behaviours need a specific rule in your app. Each entry below is the rule and what to do. The cookbook examples follow all of them.
Destroy and the main screen
Section titled “Destroy and the main screen”Rule: reset every file-scope variable at the top of create, and write destroy so that it also works with a null root.
When the firmware rebuilds its main screen while your app is open, your destroy may not run for that visit. An app that resets its state in create opens cleanly on the next visit whatever happened to the last one. Hello screen shows the pattern.
Pad callbacks and onDeactivate
Section titled “Pad callbacks and onDeactivate”Rule: keep your pad logic for the life of the program, and free nothing its callbacks use in onDeactivate.
A pad callback that started a moment before the pads changed hands can finish after onDeactivate returns. Register the handler once, keep it in a static shared_ptr, and keep its state in atomics, as Pads and LEDs does.
postToGui and pad callbacks
Section titled “postToGui and pad callbacks”Rule: call postToGui from event subscribers and your own tasks; from a pad callback, write an atomic that an lv_timer reads.
postToGui waits while its queue is full, and a pad callback must never wait for the LVGL task. Threads has both patterns.
The shared PadAnimator
Section titled “The shared PadAnimator”Rule: start a frame only while isActive() is false, and call stop() only for a frame your app started.
There is one PadAnimator for the whole board. isActive() says that an animation is showing, not whose it is, and stop() ends whichever one is showing. Keep a flag of your own for the frame you started, as s_rainbow does in Pads and LEDs.
Pad pan values
Section titled “Pad pan values”Rule: scale onPadPan from −64 (left) to 63 (right).
The board sends the finger’s left/right position in that range, with 0 in the middle. MIDI out maps it onto the full pitch bend range.
Capability flags
Section titled “Capability flags”Rule: check each service, not hasCapability().
The flags describe the platform in general. Ask the service itself: isAvailable() on an optional part such as the haptic motor, and a null check on pointers such as getKitManager() and the members of getPlatformServices() (Hardware for apps).
Tempo commits
Section titled “Tempo commits”Rule: set the tempo with transportSetTempo as often as you like, and call transportCommitTempo once, when the edit is over.
A commit re-measures and saves the open song, and the song takes one commit at a time. Tempo and transport commits once per series of taps.
The transport after your app
Section titled “The transport after your app”Rule: to play the pattern again after your app released the transport, open the Sequencer.
When your app releases the transport in destroy, PLAY and STOP drive nothing until another target claims it. The Sequencer claims it when it opens.