Table of Contents

TailCoNTROL Command Protocol

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 at this time, especially EarGear 2 features.

Bluetooth Low Energy (BLE)

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 Advertisement

Device name is one of the following:

The BLE Device Service for the MiTail, MiTail Mini, and FlutterWings is 3af2108b-d066-42da-a7d4-55648fa0a9b6:

Note: For tail-series v3.6 controller hardware, the battery charging characteristic is unset (charging state is not available).

The BLE Device Service for the EarGear 2 is 927dee04-ddd4-4582-8e42-69dc9fbfae66:

TailCoNTROL Device Indicators

Blue LED

The Blue LED (D4) has five states:

  1. Off when powered off.
  2. Blink on-off when BLE is disconnected.
  3. Fade-off when BLE is disconnected and Autonomous Mode (either iOS Casual Mode or No-phone Mode, see below) is active.
  4. Constant on when BLE is connected.
  5. Fade-on when BLE is connected and Autonomous Mode is active.
  6. Blink fast three times when the button is held for more than 3 seconds (but less than 13), indicates the device is ready to power off when the button is released.
  7. Blink fast continuously when the button is held for more than 13 seconds, indicates the device is ready to factory reset when the button is released.

Red LED

For v3.2 through v3.5 tail-series controller hardware, the Red LED (D5) has four states:

  1. Off during normal operation.
  2. Breathing while charging.
  3. Constant on when charging is complete.
  4. Short flash on, followed by pause to indicate a low (⇐ 10%) battery condition.

For v3.6 tail-series controller hardware, the Red LED (D5) has two states:

  1. Off when charging is disconnected and when charging complete.
  2. Constant on when charging.

For the EarGear 2, the Red LED has two states:

  1. Off when charging is disconnected.
  2. Constant on when charging.

Note: Unlike the DIGITAiL, MiTail, MiTail Mini, and FlutterWings devices can be used while charging.

Green LED

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:

  1. Constant on is charge in progress.
  2. Off is charge completed.
  3. Blink on-off indicates a fault condition.

The EarGear 2 does not have a Green LED.

Automatic Actions

TailCoNTROL will automatically shut down the device if there is no BLE connection for 5 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) [Note: to be moved to a configuration option in NVS in a future release].

Additional automatic actions are described in No-phone Mode, below.

Tail Moves

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

Glow Tip LED Patterns

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

EarGear 2-only Commands

LISTENMODE Starts Listen Mode; see below, returns OK
STOPLISTEN Stops Listen Mode; see below, returns OK
STOPTILT Stops Tilt Mode; see below, returns OK
TILTMODE Starts Tilt Mode; see below, returns OK

Other Commands

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, and restart after 3 seconds; see below, returns OK
SHUTDOWN SHUT DOWN the unit (will lose the BLE connection), returns 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 See below, returns OK
STOPPUSSKEY STOP PaSSKEY, disable Conference Mode and restart after 3 seconds; see below, returns OK
USERLEDS See below, returns OK
VER Returns the firmware VERsion number; VER x.x.x, followed by a second message: either GLOWTIP FALSE if a Glow Tip is not connected, or GLOWTIP TRUE if one is

Developer Commands (use at own risk)

BATT BATTery percentage, returns the integer value of estimated battery capacity remaining (e.g., 61)
FORMATNVS FORMAT NVS (erase all contents of the default NVS partition, including BLE bonds) and reboot
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
READCONF READ running CONFiguration; returns space-delimited running configuration parameters (e.g., 1 5 0 15 40 3 8 0 0 0 3 0 0 0 1 0 123456) [ver minsToSleep minsToNPM minNPMPauseSec maxNPMPauseSec groupsNPM servo1home servo2home listenModeNPMEnabled listenModeResponseOnly groupsLM tiltModeNPMEnabled tiltModeResponseOnly disconnectedCountdownEnabled homeOnAppPoweroff conferenceModeEnabled securityPasskey]
READNVS READ CONFiguration from NVS; returns space-delimited configuration parameters stored in NVS (e.g., 1 5 0 15 40 3 8 0 0 0 3 0 0 0 1 0 123456) [ver minsToSleep minsToNPM minNPMPauseSec maxNPMPauseSec groupsNPM servo1home servo2home listenModeNPMEnabled listenModeResponseOnly groupsLM tiltModeNPMEnabled tiltModeResponseOnly disconnectedCountdownEnabled homeOnAppPoweroff conferenceModeEnabled securityPasskey]
REBOOT REBOOT after 3 seconds, 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
TASKU Prints to the hardware serial console the minimum amount in words of remaining stack space that was available to the task since the task started executing, returns OK
WRITECONF WRITE CONFiguration to NVS and set running configuration to match (e.g., WRITECONF 1 5 0 15 40 3 8 0 0 0 3 0 0 0 1 0 123456), returns OK [ver minsToSleep minsToNPM minNPMPauseSec maxNPMPauseSec groupsNPM servo1home servo2home listenModeNPMEnabled listenModeResponseOnly groupsLM tiltModeNPMEnabled tiltModeResponseOnly disconnectedCountdownEnabled homeOnAppPoweroff conferenceModeEnabled securityPasskey]

Directly Set Servo Position

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, if not specified.
As per EaseTypes;
e.g., 0 = Linear (no easing), 129 = Quadratic, 130 = Cubic, 131 = Quartic
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:

DSSP Example

DSSP E130F130 A1B7 L75M75 H1
DSSP A1B7 L75M75 H1

User-defined Tail Moves and LEDs Patterns

Up to 4 user-defined move definitions and 4 LED patterns can be sent over the BT/BLE connection and assigned to user presets (callable with the TAILU1TAILU4 commands). These presets will be lost once the unit is powered off.

The two instructions used to send a tail 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, if not specified.
As per EaseTypes;
e.g., 0 = Linear (no easing), 129 = Quadratic, 130 = Cubic, 131 = Quartic
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:

USERMOVE Examples

Example 1 – Slow Wag 1 (same as the ''TAILS1'' command)

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 E2E42 F2F42 A7A1 B7B1 L75L75 M75M75 H1

Example 2 – Test Servos

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

USERLEDS Examples

Example 1 – Beacon (same as the ''LEDBEA'' command)

The Glow Tip LEDs light up for 100 ms every 1 s (Airbus A320 tail strobe).

USERLEDS U1 P2 N5 A8A0 S5S50 LEDUS1

Example 2 – Fade in/out (similar to ''LEDTRI'')

The Glow Tip LEDs light up slowly, then dim until completely off; this is repeated 3 times.

USERLEDS U2 P2 N3 A0A8 L100L100

Autonomous Mode

Defines a sequence of random moves, selected from any of three groups as below; interval between moves varies randomly from T1 to T2.

AUTOMODE G<n>[G<n> … [G<n>]] T<nnn>T<nnn>T<nnn>

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.

Autonomous Mode is ended (after completing any ongoing move) if a BLE connection is made.

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 Total duration in 15-second increments <1 … 240> (15 s … 60 min); <251 … 254> are reserved, see No-phone Mode, below)

STOPAUTO

STOPAUTO will abort the current Autonomous Mode after completing any ongoing move.

Conference Mode

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:

Enabling Conference Mode (Pairing and Binding)

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 in 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.

Disabling Conference Mode

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 in 3 seconds. If the bond needs to be removed or reset, see Unbinding, below.

Unbinding

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):

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 will no longer be valid).

iOS Casual Mode

[This feature is pending removal in a future release.]

Because the CRUMPET application is not currently permitted to manage the tail while the iOS application is in the background, the application uses the AUTOMODE command to have the tail emulate the Casual Mode behavior on-board the tail (Note there is a typo in the string the iOS app sends: there is no space between the command and the first parameter):

AUTOMODEG1 T15 T100 T240

Note that the G and the first two T parameters will depend on the selections made in the app.

Important! The minimum random pause cannot be less that 15 seconds.

iOS Casual Mode Example

AUTOMODE T15T60T240 G1G2

Listen Mode

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.

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.

No-phone Mode

No-phone mode is a feature exclusive of MiTail firmware 4.0.0 or greater or TailCoNTROL.

AUTOMODE G<n>[G<n>[G<n>]] T<nnn>T<nnn>T<251 … 254>

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.

Tilt Mode

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.

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.