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.
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
and567A99D6-A442-4AC0-B676-4993BF95F805
.0x180A
) is0x2A29
(The Mechanical Tail Company Limited
),0x2A24
,0x2A26
, and0x2A27
.0x180F
) is0x2A19
,E818BDA3-88A7-43C0-8509-6E0BBB6F55D9
, and the5073792e-4fc0-45a0-b0a5-78b6c1756c91
.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 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.
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 |
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 |
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., READCONF 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., READNVS 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 ] |
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 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 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 (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 performed) | <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 performed 3 times.
USERLEDS U2 P2 N3 A0A8 L100L100
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 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:
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.
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.
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.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).
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.
AUTOMODE T15T60T240 G1G2
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.
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 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.