This is an old revision of the document!


TailControl Release Notes

TailControl v5.4.8

Fixed

  • Removed duplicated line in console banner logo.
  • Serial console dropping characters and lines on ESP32-S3 boards (EarGear 2 v4.1, ClawGear v4.1). The Arduino-ESP32 3.3.7 HW USB CDC driver silently discards up to 64 bytes when Serial is written from a task running on the other core from its interrupt handler. Its ISR ignores a short FIFO write while HWCDC::write() commits the FIFO from the calling core. All console output now goes through a single writer task pinned to the ISR core, and application tasks are pinned to ARDUINO_RUNNING_CORE on USB CDC builds.
  • Console lines losing their beginning after brief USB link dropouts. The HW USB CDC TX buffer is increased from 256 to 2048 bytes (USB_CDC_TX_BUFFER_SIZE), which absorbs the periodic 2–6 ms host SOF dropouts instead of evicting queued output.
  • ClawGear: Tilt and Clap Mode only responded while a move was running. The accelerometer servicing condition was inverted. The fix from b093b59 was lost in revert 6d8cfb6. Detection now runs while idle and is suspended during moves, when servo motion disturbs the readings.
  • ClawGear: uninitialized clapModeIsOn and prevClapModeIsOn could cause a spurious or missed CLAP ARMED edge on startup.
  • ClawGear: the tilt classifier low-pass filter is reseeded after missed updates (a move running or modes off), so stale readings can't trigger a tilt right after a move.
  • ClawGear: the tilt state is reset when Tilt Mode is armed, so the current tilt triggers immediately, as on EarGear 2.

Added

  • Added ARMED and DISARMED console messages to Clap, Listen, and Tilt Modes that now emits correctly on the edge detection of those modes transitioning state.
  • Log module (include/Log.h, src/Log.cpp) for thread-safe console output:
    • Each message is formatted in full and queued as one item. A single writer task performs every Serial.write(), so lines from different tasks can't interleave.
    • Uses a 2 KB queue with a static ring buffer, a static writer task and no heap allocation.
    • API: logPrintf(), logPrintln(), logPuts(), and logFlush() to drain the queue before a blocking operation or power-off.
    • The LOG_DEBUG* (FDEBUG) and LOG_TERM* (FDEBUG || TERMINAL) macros replace the per-call #if defined(…) guards.
    • Output loss is now visible: a cut line ends in ~, and FDEBUG builds print ~ LOG: N message(s) dropped or truncated ~.

Changed

  • All console output in src/ is migrated from Serial.print* to Log.h. The printed text is unchanged; lines that were built from several Serial.print() calls are now sent as one message.
  • DBG_PRINTLN (and therefore SEND_MSG) uses logPrintln().
  • logFlush() is called before every PIN_HOLD power-off, and replaces Serial.flush() before blocking homing.
  • The startup banner no longer calls Serial.flush() between pieces.
  • Application tasks are created with xTaskCreatePinnedToCore(…, RTOS_APP_TASK_CORE). The pin applies to USB CDC builds only; UART builds (Flutter, Mini, MiTail) keep no core affinity.

Removed

  • ClawGear: the unused global lpf_s instance and its pre-loop seed call. Both were orphaned in 9f25f3a when the classifier got its own filter state.

Internal

  • Native test mocks: added logger stubs, since Definitions.h now includes Log.h.
  • Fixed warnings in release builds (no FDEBUG): deprecated ++ on volatile, an unused static function, and debug-only variables in initServos().

TailControl v5.4.7

New Features

  • Added ClawGear hardware platform.
    • Split move systems between servo and stepper.
  • Added RGB support.
    • Add RGB LED strip support for MiTail Mini on Servo 2 port.
    • Add RGB LED strip support for ClawGear on Servo 2 port.
    • Added RGB LED strip support on serial port RX pin for MiTail products, based on suggestion from Code-L (good idea 👍).
    • Added terminal RX status.
    • Added `remapConsoleRXtoGPIO` to NVS settings commands.
    • Added per-product RGB setting defaults (number of LEDs, current limits, etc.).
    • Added `SETRGB` to NVS settings commands to set RGB LED parameters.
    • Added `SETBRT` to NVS settings commands to set RGB LED default global brightness parameter.
    • All RGB commmands support brightness override (and can set hue, where appropriate).
  • Added servo hold on stop to NVS settings commands (`SETHOLDONSTOP` / `UNSETHOLDONSTOP`).
  • Added BLE disconnected countdown disable/enable functionality to NVS settings commands (`SETDISCONNECTEDCOUNT`).
  • Added internal move enable/disable for Listen and Tilt Mode moves to NVS settings commands (`SETLISTENMOVES` / `UNSETLISTENMOVES` and `SETTILTMOVES` / `UNSETTILTMOVES`).
  • Added `myColor` setting (request from Code-L) - device “remembers” it's set UI color to report back to app.
    • Added `SETMYCOLOR` command.
    • `MYCOLOR` returned as part of `VER` response.

Bugfixes / Refactoring

  • Refactor to move PlatformIO platform to `pioarduino-stable`.
  • Migrated to new I2S driver.
  • Implemented unit testing for `taskconsole()` function.
  • Minor shutdown code cleanup.
  • Removed unused servo speed parameter.
  • Fixed CRITICAL Conference Mode kernel panic, reported by SnowOwlX (thank you!)
    • Increased stack size margins to be closer to 50% free at worst case.
  • Refactored `platformio.ini` file.
  • Re-baselined tilt mode zero points for EarGear 2.
  • `TILTMODE` cooldown reduced to 3 seconds, down from 4.
  • Renamed `timersTask` to be consistent with other task names.
  • Fixed `WRITECONF`, `READCONF`, and `READNVS` commands.
  • Updated functionality for Python extra scripts to improve maintainability of the PlatformIO build process.
  • Adjusted `.gitignore` file.
    • Removed `extensions.json` from inclusion, as it's auto-generated.
    • Stop including `esp-web-tools/firmware/*.bin` files.
  • Change internal move references to `MOVE_HOME`, and `MOVE1` through `MOVE11` (console command naming mapping remains the same).
  • Fix `build_unify_binary.py` script not triggering reliably.
  • `patch_libdeps.py` handles already-patched files more robustly.
  • Performed code hygiene review:
    • Fixed null-check `strtok()` results before calling `startOTA()`.
    • Fixed reset OTA byte counter at the start of each OTA session.
    • Fixed null-check `malloc()/calloc()` results in `createMovingAverage()`.
    • Fixed clamp BLE RX `memcpy()` length to actual string length.
    • Replaced `xQueuePeekFromISR()` with `xQueuePeek()` in task context.
    • Guard Autonomous Mode group bit shift against out-of-range index.
    • Use `>=` instead of `==` for serial RX buffer overflow check.
    • Removed contradictory signaling and makes the OTA state machine unambiguous.
    • Robust null-handling for moving-average allocation and use is implemented in EG2 listen-mode processing.
    • Correctly map `AUTOMODE` groups and guard bitflag generation.
    • Skip zero-length BLE writes in `execOTA()` to prevent duplicate ACK.
    • Guard against re-entrant `startOTA()` while a transfer is already active.
    • Release OTA flash write handle when BLE disconnects mid-transfer.
    • Pass actual BLE connection handle to `updateConnParams()`.
    • Switch `p_characteristicRX` from `INDICATE` to `NOTIFY`.
    • Replace blocking `delay()`/`esp_restart()` in BLE callback with `esp_timer`.
    • Abort and restart on `Update.end()`/`Update.isFinished()` failures.
    • Enforce 60-second inactivity timeout during OTA transfer.
    • `ota.py` subscribe to TX characteristic for firmware status notifications.
    • Fix multifunction button LED animations.

Library Updates

  • Updated ESP32Servo library to v3.2.0.
  • Updated NimBLE-Arduino library to v2.5.1.
  • Updated ServoEasing library to v3.6.0.
  • Added NeoPixelBus#CORE3 (for RGB support).
  • Replaced JLed libary with custom class (`LedFx`) built on Core v3's native API.

Updated Documentation

  • Added new Move Reference Wiki page.
  • Bumped copyright year to 2026.
  • Added notes about flying with devices that contain LiOn batteries to documentation.
  • Added move mappings for FlutterWings.
  • Documented new commands and command changes.

TailControl v5.2.8

  • Rebranded “TailCoNTROL” to “TailControl” (under duress).
  • Add full EarGear 2 support:
    • Add dedicated firmware moves for EarGear 2.
    • Set EarGear 2 to maintain servo holding at all times to facilitate assembly (as per staff request).
    • New I2S support added.
    • Set configuration item for Listen Mode to send responses only.
    • Set configuration item for Tilt Mode to send responses only.
    • Add I2S debug task for Ear Gear.
    • Add configuration parameter for Listen and Tilt mode to send triggers only (allows application to manage movements).
    • Add configuration parameter for Listen move group selection.
    • Support EG2 Tilt and Listen Mode in No-phone Mode.
  • Move TailCoNTROL to new BLE UUIDs.
  • Reorganized code units and functions to improve organization and readability.
  • Add Device Information Service (DIS) BLE characteristics.
  • Add SETHOLDONSTOP and RELEASEHOLDONSTOP commands.
  • Fixed BATT characteristic response truncation (thank you Code-L).
  • Implement simple message queue for ISR debug tracing.
  • Fixed unsigned long int sprintf format strings.
  • Improved commenting for hardware/platform variants.
  • Fixed JLed invocation to address timer conflict.
  • Clean up debug logging to make format consistent.
  • Added Conference Mode and associated configuration settings.
  • Fix move group selection logic.
  • Fix LIS2DW12 library to support non-hardcoded SPI bus wiring.
  • Rework button press servicing and visual indicators.
  • Add new function to perform factory reset on extended button hold.
  • Rename some variables and functions to better reflect their purpose.
  • Reverted undesirable MiTail easing function settings for some moves.
  • Refactored NVS options and compilation units.
  • Added persistent setting for automatic power off when BLE is disconnected (default is OFF).
  • Added persistent setting for home on POWEROFF command (default is ON).
  • CONFRD command removed, replaced by READCONF and READNVS.
  • CONFWR command replaced with WRITECONF.
  • Added SETHOME command (and persistent setting) for FlutterWings, and EarGear 2 [feature requested by @AleinaTravyre].
  • Added REBOOT command.
  • Improved BLE MTU settings for iOS.
  • Split RTOS tasks into separate unit files.
  • Fix race condition between updateMoves() and setMove() / setDSSPMove() that caused stuttering/short moves (thank you Mrs. Tailer for spotting this).
  • Improved debug messages.
  • Update ESP32Servo library to 1.2.1.
  • Updated JLed library to v4.15.0.
  • Updated NimBLE-Arduino library to v2.1.2 (made transitions for breaking changes).
  • Updated ServoEasing library to v3.4.0 (made transitions for breaking changes).
  • Updated BLE_OTA_Python scripts and documentation.
  • Added script to build unified binary for EarGear 2 firmware.
  • Added ESP Web Tools configuration for writing EarGear 2 firmware.
  • Fix PlatformIO $extra_scripts to be cumulative.
  • Update Tail Control Protocol to reflect as-built.
  • Add additional details to Service Notes about the Glow Tip.

TailControl v5.0.9

  • Reverted changes to easing modes in MiTail moves.

TailControl v5.0.8

Initial release of TailControl unified firmware.

  • Added #DEBUG compile-time flag to disable serial output.
  • Added firmware support for new product: FlutterWings.
  • Added firmware support for new product: MiTail Mini.
  • Tune MiTail Mini moves 1, 2, and 3.
  • Added firmware support for v3.6 tail board. Split out PD handling to support non-PD hardware.
  • Restructured moves so that independent strings of moves (with easing type, position, and duration triplets for each move) for each servo, and can be of different length.
  • Improved support for DSSP commands.
  • Fixed HWCDC blocking bug for EarGear 2 serial console.
  • Fixed uncommanded servo movement occurring at the end of a move when the servos detach from the PWM channel.
  • Fixed bug in move state machine.
  • Removed hazards created by unbracketed nested statements by adding explicit curly braces to single-line statements. (Findings 1 and 8.)
  • Pin support libraries to exact versions to eliminate hazard of unintended support library changes introducing faults unexpectedly. (Finding 6.)
  • Split setup() function into smaller logical calls to other functions. (Partial implementation for Finding 7.)
  • Identified variables impacted by ISR calls (because I can't even read my own notes in the ISR function descriptions!) and moved them to Mailboxes (queues) or Critical Sections. (Thread safety.)
  • Tagged globals touched in ISR context with g_ prefix for identification.
  • Reduced task priorities.
  • Add initial EG2 support for move system Proof of Concept.
  • Split functions/reorganize code to facilitate hardware differentiation.
  • Created new PlatformIO build env profiles for each product target.
  • Version number control moved to platformio.ini, instead of Definitions.h file.
  • Created build script to automatically name output binaries during build process (automatic firmware filename versioning).
  • Added additional code commenting for variables.
  • Fixed -Wformat-truncation warnings in PD_Micro library.
  • Fixed -Wunused-variable warnings in LIS2DW12-Arduino-Lib library.
  • Improved banner message.
  • Improved servo debug output.
  • Updated JLed library to 4.13.1.
  • Updated ESP32Servo library to v1.2.0.
  • Updated documentation.
Edit this page