Command list for the Tail Company TailControl firmware. TailControl is the unified firmware platform (version 5.x.x and higher) for the MiTail, MiTail Mini, FlutterWings, and EarGear 2, and covers the shared features that exist across all those devices.
All commands are case-sensitive. Trailing whitespace (e.g., `NULL`, `CR`, etc.) are ignored. The space between a command keyword and the parameters is mandatory.
IMPORTANT NOTICE: TailControl and the TailControl Protocol is still under development. Some commands and features described here relate to a future release and are subject to change.
The hardware platform uses the “Just Works” Bluetooth Low Energy (BLE) pairing method to connect. If Conference Mode (see below) is used, “Passkey” pairing is used.
Device name is one of the following:
mitail for MiTail,minitail for MiTail Mini,flutter for FlutterWings, andEG2 for EarGear 2.
The BLE Device Service for the MiTail, MiTail Mini, and FlutterWings is 3af2108b-d066-42da-a7d4-55648fa0a9b6:
5bfd6484-ddee-4723-bfe6-b653372bbfd6,c6612b64-0087-4974-939e-68968ef294b0, and theb08fed02-0584-40ef-b006-aff7e0d24e13.
The BLE Device Service for the EarGear 2 is 927dee04-ddd4-4582-8e42-69dc9fbfae66:
05e026d8-b395-4416-9f8a-c00d6c3781b9,0b646a19-371e-4327-b169-9632d56c0e84, and the54fa919d-e8a8-4841-b280-c5461161304f.TailControl will use a new Service and Characteristics UUIDs going forward, to distinguish it from previous firmwares (and to further enforce the “forklift upgrade” required).
The BLE Device Service for TailControl is 19F8ADE2-D0C6-4C0A-912A-30601D9B3060:
5E4D86AC-EF2F-466F-A857-8776D45FFBC2.567A99D6-A442-4AC0-B676-4993BF95F805, and theE818BDA3-88A7-43C0-8509-6E0BBB6F55D9.For tail-series (MiTail, MiTail Mini, and FlutterWings) v3.6 controller hardware, the battery charging characteristic is unset (charging state is not available).
The Blue LED (D4) has five states:
For v3.2 through v3.5 tail-series controller hardware, the Red LED (D5) has four states:
For v3.6 tail-series controller hardware, the Red LED (D5) has two states:
For the EarGear 2, the Red LED has two states:
Note: Unlike the DIGITAiL, MiTail, MiTail Mini, and FlutterWings devices can be used while charging.
The Green LED (D8) is only present on v3.2 through v3.5 tail-series controller hardware, and is not visible from outside the device case. The LED is a visual indicator for the STAT pin of the battery charger:
The EarGear 2 does not have a Green LED.
TailControl will automatically shut down the device if there is no BLE connection for currConfig.minsToSleep (default 0, see below) minutes. This behavior is suspended if a PD-capable adapter is attached (to allow for charging and/or operating from a external battery) OR if the firmware is compiled with a compile-time option to disable the timer (to facilitate wired serial console control where BLE connectivity is not used).
Additional automatic actions are described in No-phone Mode, below.
Move commands return <movename> BEGIN upon start, and <movename> END upon completion. If the move is set to return home after completion (all firmware moves are), then it will be immediately followed by a TAILHM BEGIN and a TAILHM END as well.
A command will return LOWBATT and reject the command if the battery is less than 10%. ERR will be returned if the command can't be parsed or otherwise executed.
A new command that is received before the currently executing command is finished will immediately end the current command and start the new one.
Easing functions are as per the ServoEasing libary EaseTypes. However, those functions are presented in Hexidecimal and must be converted to a Decimal number before being used in command syntax. The Easing Functions Cheat Sheet is useful to help visualize what easing functions do.
| TAILHM | HoMe position |
| TAILS1 | Slow wag 1 |
| TAILS2 | Slow wag 2 |
| TAILS3 | Slow wag 3 |
| TAILFA | FAst wag |
| TAILSH | SHort wag |
| TAILHA | HAppy wag |
| TAILER | ERect |
| TAILEP | Erect Pulse |
| TAILT1 | Tremble 1 |
| TAILT2 | Tremble 2 |
| TAILET | Erect Trem |
| TAILU1 | User defined 1 |
| TAILU2 | User defined 2 |
| TAILU3 | User defined 3 |
| TAILU4 | User defined 4 |
LED pattern commands return <movename> BEGIN upon start, and <movename> END upon completion.
A command will return LOWBATT and reject the command if the battery is less than 10%. ERR will be returned if the command can't be parsed or otherwise executed.
A new command that is received before the currently executing command is finished will immediately end the current command and start the new one.
| LEDOFF | LEDs OFF |
| LEDREC | RECtangle wave pattern (blink 1 second on, 1 second off) |
| LEDTRI | TRIangle wave pattern (fade in 1 second, fade out 1 second) |
| LEDSAW | SAWtooth wave pattern (fade in 2 seconds, off) |
| LEDSOS | Morse SOS pattern |
| LEDBEA | BEAcon (100ms on every 2 seconds) |
| LEDFLA | FLAme |
| LEDSTR | STRobe |
| LEDUS1 | USer defined 1 |
| LEDUS2 | USer defined 2 |
| LEDUS3 | USer defined 3 |
| LEDUS4 | USer defined 4 |
| RGBOFF | RGB LEDs OFF, returns OK |
| RGBRBO | RGB RainBow pattern, returns OK |
| RGBRB2 | RGB RainBow pattern with random sparkly glitter, returns OK |
| RGBCON | RGB CONfetti; random-colored speckles that blink in and fade smoothly, returns OK |
| RGBSIN | RGB SINe; a colored dot sweeping back and forth, with fading trails, returns OK |
| RGBJUG | RGB JUGgle; eight colored dots, weaving in and out of sync with each other, returns OK |
| RGBBPM | RGB BPM; colored stripes pulsing at a defined Beats-Per-Minute, returns OK |
| RGBDMO | RGB DEmO; cycle through all the preceding patterns, changing every 10 seconds, returns OK |
| RGBTST | RGB TEsT; color cycle the first and last pixel of the RGB string (endpoints test), returns OK |
| SETRGB | SET RGB configuration; returns OK and restarts after 3 seconds; (e.g., SETRGB 325 12 2900) [numRGBLEDs maxRGBVolt maxRGBmAmp] |
| AUTOMODE | AUTOnomous MOde (see below), returns OK |
| DSSP | Directly Set Servo Position (see below), returns OK |
| HWVER | Returns HardWare VERsion; returns HWVER LEGACY MITAIL or HWVER MITAIL x.x for tail-series controller hardware, HWVER EG2 x.x for EarGear 2 controller hardware |
| PING | Keepalive heartbeat (from application), returns PONG |
| SETPUSSKEY | SET PaSSKEY; enable Conference Mode, returns OK, and restarts after 3 seconds (see below) |
| SHUTDOWN | SHUT DOWN the unit (will lose the BLE connection), returns OK followed by SHUTDOWN BEGIN, or ERR if charger is attached |
| STOPAUTO | STOP AUTOnomous Mode, returns OK, followed by AUTO END |
| STOPNPM | STOP No-Phone Mode and disables it in NVS configuration; returns OK, followed by AUTO END |
| USERMOVE | Set user-defined move (see below), returns OK |
| STOPPUSSKEY | STOP PaSSKEY; disable Conference Mode, returns OK, and restarts after 3 seconds (see below) |
| USERLEDS | Set user-defined Glow Tip pattern (see below), returns OK |
| VER | Returns the firmware VERsion number; (e.g., VER 5.0.0); followed by a line that is either GLOWTIP TRUE if a Glow Tip is connected, or GLOWTIP FALSE if one is not; and a final line that is either RGB TRUE if a RGB LED strip is connected, or RGB FALSE if it is not |
| BATT | BATTery percentage, returns the integer value of estimated battery capacity remaining (e.g., 61) |
| READCONF | READ running CONFiguration; returns space-delimited running configuration parameters (e.g., READCONF 1 5 0 15 40 3 8 0 0 1 3 0 1 0 1 1 495974 325 12 2900) [ver minsToSleep minsToNPM minNPMPauseSec maxNPMPauseSec groupsNPM servo1home servo2home listenModeNPMEnabled listenModeResponseOnly groupsLM tiltModeNPMEnabled tiltModeResponseOnly disconnectedCountdownEnabled homeOnAppPoweroff conferenceModeEnabled securityPasskey numRGBLEDs maxRGBVolt maxRGBmAmp] |
| WRITECONF | WRITE CONFiguration to NVS and set running configuration to match (e.g., WRITECONF 1 5 0 15 40 3 8 0 0 1 3 0 1 0 1 1 495974 325 12 2900) [ver minsToSleep minsToNPM minNPMPauseSec maxNPMPauseSec groupsNPM servo1home servo2home listenModeNPMEnabled listenModeResponseOnly groupsLM tiltModeNPMEnabled tiltModeResponseOnly disconnectedCountdownEnabled homeOnAppPoweroff conferenceModeEnabled securityPasskey numRGBLEDs maxRGBVolt maxRGBmAmp], returns OK |
| SETDISCONNECTEDCOUNT | SET BLE DISCONNECTED power off COUNTdown parameter in NVS and running configuration (in minutes, SETDISCONNECTEDCOUNT 0 disables automatic poweroff), returns OK |
| SETHOLDONSTOP | SET servo HOLD is maintained when the servos STOP (maintains servo PWM when not moving, default for EarGear 2); returns OK |
| UNSETHOLDONSTOP | UNSET servo HOLD when the servos STOP (servo PWM is dropped when not moving, default for tail-based devices); returns OK |
| SETHOME | SET HOME position (0 through 8) for each servo (e.g., SETHOME 4 4), NOTE: only available on FlutterWings, and EarGear 2; returns OK |
| SETLISTENMOVES | SET internal LISTEN Mode MOVES to play on a listen event in addition to sending event notifications; returns OK |
| UNSETLISTENMOVES | UNSET internal LISTEN Mode MOVES to play on a listen event, only an event notification will be sent and it is the responsibility of the connected application to send commands to react to events; returns OK |
| SETTILTMOVES | SET internal LISTEN Mode MOVES to play on a tilt event in addition to sending event notifications; returns OK |
| UNSETTILTMOVES | UNSET internal LISTEN Mode MOVES to play on a listen event, only an event notification will be sent and it is the responsibility of the connected application to send commands to react to events; returns OK |
| OTA | Starts firmware Over The Air update process (e.g., OTA <expected size in bytes> <expected MD5>); returns BEGIN OTA or ERR on failure to start, OTA SUCCESS on success, or OTA ERR on error during OTA process |
| FORMATNVS | FORMAT NVS (erase all contents of the default NVS partition, including BLE bonds), returns OK and reboots after 3 seconds |
| READNVS | READ CONFiguration from NVS; returns space-delimited configuration parameters stored in NVS (e.g., READNVS 1 5 0 15 40 3 8 0 0 1 3 0 1 0 1 1 495974 325 12 2900) [ver minsToSleep minsToNPM minNPMPauseSec maxNPMPauseSec groupsNPM servo1home servo2home listenModeNPMEnabled listenModeResponseOnly groupsLM tiltModeNPMEnabled tiltModeResponseOnly disconnectedCountdownEnabled homeOnAppPoweroff conferenceModeEnabled securityPasskey numRGBLEDs maxRGBVolt maxRGBmAmp] |
| REBOOT | REBOOT; returns OK and reboots after 3 seconds |
| TASKU | Prints to the hardware serial console the minimum amount of remaining stack space that was available to the task since the task started executing (high water mark), returns OK |
DSSP (Directly Set Servo Positions) allows a single-position move to be commanded and executed immediately. This is faster (and simpler) than defining a USERMOVE and then executing it. It also has the advantage of keeping the debug console output synchronous to the move flow, instead of interleaving the command and move flow responses.
The syntax is similar to USERMOVE, but fewer parameters:
DSSP [E<easeType1>F<easeType1>] A<point1>B<point1> L<numticks1>M<numticks1> [H{0|1}]
| Prefix | Parameter Type | Range of Values for Moves |
|---|---|---|
| E | Easing function to apply to Servo 1 | Default is Linear (no easing), if not specified. This is the decimal representation of the (hexadecimal) easing type enumeration, as per EaseTypes (e.g., 0 = Linear, 129 = Quadratic in/out, 130 = Cubic in/out, 131 = Quartic in/out). |
| F | Easing function to apply to Servo 2 | (Same as E) |
| A | Point for Servo 1 | <0 … 8> 0 → 25 degrees 1 → 41 degrees 2 → 58 degrees … 8 → 160 degrees |
| B | Point for Servo 2 | (Same as A) |
| L | Time between the current Servo 1 point and the next in ticks (in 20 ms increments) L will move from the current position to the next, over the time specified | 0 … 127 (time * 20 ms) |
| M | Time between the current Servo 2 point and the next in ticks (in 20 ms increments) M will move from the current position to the next, over the time specified | (Same as L) |
| H | Move to home position at end of move | 0 = false (default), 1 = true |
Notes:
AABBSS, ABABSS, ABSABS).
DSSP E130F130 A1B7 L75M75 H1
DSSP A1B7 L75M75 H1
Up to 4 user-defined move definitions and 4 Glow Tip LED patterns can be sent over the BT/BLE connection and assigned to user
presets (callable with the TAILU1 … TAILU4 commands). These presets will be lost once the unit is powered off.
The two instructions used to send a move or a Glow Tip LED pattern definition follow the same syntax and consist of a
keyword (USERMOVE or USERLEDS) followed by a number of parameters. These are letter-number pairs, where the letter
defines the type of parameter (see table, below).
USERMOVE U<preset> P<numpoints> N<numcycles> [E<easeType1>F<easeType1> … E<easeTypen>F<easeTypen>] A<point1>B<point1> … A<pointn>B<pointn> L<numticks1>M<numticks1> … L<numticksn>M<numticksn> [H{0|1}]
| Prefix | Parameter Type | Range of Values for Moves |
|---|---|---|
| U | User preset number | <1 … 4> |
| E | Easing function to apply to Servo 1 | Default is Linear (no easing), if not specified. This is the decimal representation of the (hexadecimal) easing type enumeration, as per EaseTypes (e.g., 0 = Linear, 129 = Quadratic in/out, 130 = Cubic in/out, 131 = Quartic in/out). |
| F | Easing function to apply to Servo 2 | (Same as E) |
| A | Point for Servo 1 | <0 … 8> 0 → 25 degrees 1 → 41 degrees 2 → 58 degrees … 8 → 160 degrees |
| B | Point for Servo 2 | (Same as A) |
| L | Time between the current Servo 1 point and the next in ticks (in 20 ms increments) L will move from the current position to the next, over the time specified | 0 … 127 (time * 20 ms) |
| M | Time between the current Servo 2 point and the next in ticks (in 20 ms increments) M will move from the current position to the next, over the time specified | (Same as L) |
| H | Move to home position at end of move | 0 = false (default), 1 = true |
USERLEDS U<preset> P<numpoints> N<numcycles> A<point1> … A<pointn> [S|L]<numticks1> … [S|L]<numticksn>
| Prefix | Parameter Type | Range of Values for Glow Tip LEDs |
|---|---|---|
| U | User preset number | <1 … 4> |
| P | Number of points in the Glow Tip pattern | <1 … 32> |
| N | Number of cycles (times the pattern will be repeated) | <0 … 255> |
| A | Brightness point for Glow Tip | <0 … 8> 0 → LEDs off … 4 → 50% intensity … 8→ LEDs max intensity |
| S/L | Time between the current point and the next (in 20 ms increments) S will wait in the current position, then move to the next when the time has elapsed L will gradually move from the current position to the next, over the time specified | 0 … 127 (time * 20 ms) |
Notes:
Position limits on the tail can be visualized as such:
Both servos move from 143° to 41° (position 7 to 1) and back, for 3 times; each cycle is (75 + 75) * 20 ms = 3 s long.
USERMOVE U1 P2 N3 E0E66 F0F66 A7A1 B7B1 L75L75 M75M75 H1
Moves servos in steps of 90° every 2 seconds; Servo 2 is delayed by 90°.
USERMOVE U2 P4 N3 A4A8A4A0 B4B8B4B0 L100L100L100L100 M100M100M100M100 H1 TAILU2
Because no easing parameters (E or F) are specified, no easing is used by default.
The Glow Tip LEDs light up for 100 ms every 1 s (Airbus A320 tail strobe).
USERLEDS U1 P2 N5 A8A0 S5S50 LEDUS1
The Glow Tip LEDs light up slowly, then dim until completely off; this is repeated 3 times.
USERLEDS U2 P2 N3 A0A8 L100L100
Conference mode pairs the user's phone with the TailControl device and establishes a bond that performs long-term storage of encryption info (particularly keys) so that the devices “know” each other and can easily reconnect in an encrypted way. This protects your device in a number of different ways:
Do NOT attempt to use Conference Mode on TailControl firmware prior to 5.3.0, or a condition requiring repair of the control board can occur.
Pairing is performed with a 6-digit number entered on each of the devices. In the case of TailControl, the passkey is set on the device in a “safe” location and saved to the firmware configuration.
SETPUSSKEY <nnnnnn>
The device will then reboot after 3 seconds. Conference Mode is then enabled, and pairing proceeds. The user's phone (or other device) will prompt for the passkey (which was set earlier), and the bond will be established on both devices. After that, the passkey or a previous bond (up to 3 can be stored) will be required to connect to the device.
Conference Mode can be disabled by sending the STOPPASSKEY command. This disables Conference Mode, and sets the stored and running configuration passkey to the default (123456).
STOPPUSSKEY
The device will then reboot after 3 seconds. If the bond needs to be removed or reset, see Unbinding, below.
Resetting/removing bonds requires two separate actions: resetting the TailControl device, and removing the bond on the phone or other device.
There are two different methods of factory-resetting a TailControl device (which resets all persistent options to defaults and removes all bonding information):
FORMATNVS command to the TailControl console. This will factory-reset and reboot.Note that the bond will also need to be removed on the phone or other device as well, or it will attempt to continue to use the bond (which will fail, because those stored credentials are no longer valid).
Listen Mode is only available on the EarGear 2. When Listen Mode is active, a detected sound above ambient will trigger a random move and a LISTEN BANG message will be sent back to the client. If listenModeMovEn is set (default), then the firmware move will be triggered, otherwise the controlling app will be expected to send a move (if desired).
Development support for basic sound localization for future hardware is supported, replacing the LISTEN BANG response with
LISTEN BANG CENTER, LISTEN BANG LEFT, and LISTEN BANG RIGHT, respectively.
LISTEN ARMED is sent to the debug console (but not currently to the BLE terminal) after all conditions to re-trigger have been met.
Triggering by Listen Mode is inhibited when the ears are in motion, as well as a 3-second counter that runs once a sound trigger has finished executing a move.
Perform random moves while disconnected from a BLE client, selected from any of three groups as below; interval between moves varies randomly from T1 to T2. This feature is comparable to Casual Mode in the app.
AUTOMODE G<n>[G<n>[G<n>]] T<1 … 240>T<1 … 240>T<251 … 254>
The tail will select a random move from the specified group(s), pausing for a random number of seconds between each move (min and max specified by the first and second T parameter, respectively). The tail will stop completely after the time passed by the 3rd T parameter.
No-phone Mode is suspended (after completing any ongoing move) if a BLE connection is made. It will resume after BLE is disconnected.
| Group | Move Group Name | Move List |
|---|---|---|
| 1 | Calm and Relaxed | Slow Wag 1, Slow Wag 2, Slow Wag 3 |
| 2 | Fast and Excited | Fast Wag, Short Wag, Happy Wag, Erect |
| 3 | Frustrated and Tense | Tremble 1, Tremble 2, Tremble Erect, High Wag |
The parameter order is not important, except that the three T parameters are interpreted in the order specified below.
| Prefix | Parameter Type | Range of Values |
|---|---|---|
| G | Move Group (see table above) | <1 … 3> |
| T1 | Minimum random pause between moves in 1-second increments | <1 … 240> (1 s … 4 min) |
| T2 | Maximum random pause between moves in 1-second increments | <1 … 240> (1 s … 4 min) |
| T3 | Delay to wait for BLE connection before starting NPM | <251 … 254> (1 … 4 min) |
No-phone Mode (NPM) will cause the tail to delay one to four minutes (based on the setting of the third T parameter of 251 through 254) to wait for a BLE connection. If no BLE connection is made during that time, the tail will select a random move from the specified group(s), pausing for a random number of seconds between each move (min and max specified by the first and second T parameter, respectively).
No-phone Mode is suspended (after completing any ongoing move) if a BLE connection is made. It will resume after BLE is disconnected.
STOPNPM
Stops No-phone mode and disables it in NVS configuration.
AUTOMODE T15T60T243 G1G2
Tilt Mode is only available on the EarGear 2. When Listen Mode is active, a detected sound above ambient will trigger a random move and a TILT FORWARD, TILT BACKWARD, TILT LEFT, or TILT RIGHT message (depending on the tilt direction) will be sent back to the client. If tiltModeMovesEnabled is set (default), then the firmware move will be triggered, otherwise the controlling app will be expected to send a move (if desired).
Triggering by Tilt Mode is inhibited when the ears are in motion, as well as a 3-second counter that runs once a sound trigger has finished executing a move AND the EarGear 2 has returned to the neutral tilt position during that time. This prevents tilt re-triggering if the user stays in the tilt position for an extended time.