Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
en:dev:tailcontrol-command-protocol [2026/08/02 16:17] darkgrueen:dev:tailcontrol-command-protocol [2026/08/03 19:18] (current) darkgrue
Line 1: Line 1:
-===== Introduction =====+====== TailControl Command Protocol ======
  
-These instructions do not purport to cover all details or variations of the product and do not claim to provide for every possible contingency in connection with installation, operation, or maintenance. Self-repairs performed by the customer may lead to damage or loss of your product. Should further information be desired or if repair services are desired, please contact The Tail Company ([[contact@thetailcompany.com]]). 
  
-For the purposes of this manual, “left” and “right” references will refer to the MiTail’s orientation when worn on the body, relative to the wearerSo, the “left” side is the side of the MiTail on the wearer’s left.+Command list for the Tail Company TailControl firmwareTailControl is the unified firmware platform (version 5.//x//.//x// and higher) for the EarGear 2, FlutterWings, MiTail, MiTail Mini, and Paws with Claws (ClawGear); 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.
  
-===== MiTail Case =====+<WRAP round todo 90%> 
 +**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. 
 +</WRAP>
  
-The MiTail case is injection-molded ABS. Replacements may be ordered from The Tail Company, or installed by a repair depot. 
  
 +===== Bluetooth Low Energy (BLE) =====
  
-==== Case Screws ====+The hardware platform uses the "Just Works" Bluetooth Low Energy (BLE) pairing method to connect. If Conference Mode ([[#Conference Mode|see below]]) is used, "Passkey" pairing is used.
  
-There are eight Phillips-head self-tapping screws holding the case together. In addition to a serial number foil may be present that must be cut or removed to open the case. One of the screws is behind the left actuator cable, and is easy to miss. 
  
-{{ :en:manuals:mitail_case_8_holes_.jpg?600 |}}+===== Device Advertisement =====
  
 +Device name is one of the following:
  
-==== Case Replacement ====+  * ''clawgear'' for ClawGear/Paws with Claws, 
 +  * ''EG2'' for EarGear 2, 
 +  * ''flutter'' for FlutterWings, 
 +  * ''mitail'' for MiTail, and 
 +  * ''minitail'' for MiTail Mini.
  
-Replacing the lower case half (with the belt hook portion) is the most common reason for replacing the MiTail case+TailControl will uses the same Service and Characteristics UUIDs across all supported products: ''19F8ADE2-D0C6-4C0A-912A-30601D9B3060''.
  
-<WRAP round tip 90%> +  * RX Characteristic is ''5E4D86AC-EF2F-466F-A857-8776D45FFBC2'', 
-Before starting, read all the sections of this guide. Take photos or videos of your disassembly, to assist you in reassembling the tail. The sections that most users have trouble in are in the area of setting the servo home position, reassembling the control board to the case, and reassembling the case halves. Tips have been provided for each of those trouble areas.</WRAP>+  * TX Characteristic is ''567A99D6-A442-4AC0-B676-4993BF95F805'' and the 
 +  * Battery Voltage is ''E818BDA3-88A7-43C0-8509-6E0BBB6F55D9''.
  
-This requires that the case be opened, the two batteries taken out of the case (they may stay attached to the control board)the control board removed from the case halfthe four servo frame mount screws be removed to free both servos and the tail spine from the case half, and the servo pulley be removed from the servo (one screw in the center). The cable must be removed from the pulley (requiring 7 screws removed from the pulleyto remove the case half from the cable.+<WRAP round important 90%> 
 +For tail-series (MiTailMiTail Mini, and FlutterWingsv3.6 controller hardware, the battery charging characteristic is unset (charging state is not available). 
 +</WRAP>
  
-The disassembly is then reversed. Note the procedure in [[#Resetting Servo Home Position]] to reset the pulley position on the servo shaft correctly. 
  
 +===== TailControl Device Indicators =====
  
-===== Installing the Control Board ===== 
  
-Early production issues with the power button and/or USB-C connector mechanically separating from the control board were corrected with hot glue to protect the connector.+==== Blue LED ====
  
-<WRAP round important 90%> +The Blue LED (D4) has five states:
-Assembly of the control board can be made easier by reaming out the case hole for the button to be slightly larger. This can help prevent the button from being broken off the board and requiring a full board replacement. +
-</WRAP>+
  
-Check for plastic swarf on the interior of the case edge around the power button from post-manufacturing rework that may interfere with installation of the control board.+  - **Off** when powered off. 
 +  - **Blink on-off** when BLE is disconnected. 
 +  - **Fade-off** when BLE is disconnected and Autonomous Mode (either iOS Casual Mode or No-phone Mode, [[#Autonomous Mode|see below]]) is active. 
 +  - **Constant on** when BLE is connected. 
 +  - **Fade-on** when BLE is connected and Autonomous Mode is active. 
 +  - **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. 
 +  **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.
  
-{{ :en:manuals:case_bottom_tabs.jpg?400 | }} 
  
-Firmly squeezing the sides of the case to cause the button-facing edge of the case to bow out slightly can afford a small amount of extra space to manipulate the control board into place.+==== Red LED ====
  
-{{ :en:manuals:board_squeeze.jpg?nolink&400 | }}+For v3.2 through v3.5 tail-series controller hardware, the Red LED (D5) has four states:
  
-<WRAP round tip 90%> +  - **Off** during normal operation. 
-When reassembling the case halves, pay close attention that there is a slot for engaging the PCB board on the other half of the case as wellThis will sometimes keep the halves from mating completely, and should not be forced. Offsetting the case forward or backwards from the belt attachment lug and seating that end first may assist in getting the PCB to seat correctly in the case slot. Check for swarf in the PCB slot, or hot glue traces on the PCB, if getting it to seat completely is proving difficultSeparating the case halves and re-assembling can also sometimes "magically" cure difficult alignment problems. Be patientand don't force them. +  - **Breathing** while charging. 
-</WRAP>+  - **Constant on** when charging is complete. 
 +  **Short flash** onfollowed by pause to indicate a low (<= 10%) battery condition.
  
-{{ :en:manuals:case_top_tab.jpg?400 | }}+For v3.6 tail-series controller hardware, the Red LED (D5) has two states:
  
 +  - **Off** when charging is disconnected and when charging complete.
 +  - **Constant on** when charging.
 +  
 +For the ClawGear and EarGear 2, the Red LED has two states:
  
-===== Installing Batteries =====+  - **Off** when charging is disconnected. 
 +  - **Constant on** when charging.
  
-The MiTail Battery is a 3.7V3000 mAh103665 (approximately 10 x 36 x 65 mm) LiPo battery with a "JST PH 2-pin" connector. There are two of them.+**Note:** Unlike the DIGITAiLClawGearEarGear 2, MiTail, MiTail Mini, and FlutterWings devices **can** be used while charging.
  
-{{ :en:manuals:battery.jpg?nolink&600 |}} 
  
-<WRAP round tip 90%> +==== Green LED ====
-FAA rules on installed batteries are that devices containing lithium batteries (laptops, phones, and also tails) can be checked, but carry-on is preferred to prevent damage/fire. There is a battery capacity limit generally allowing capacities under 100 Wh. The tails, with two 11.1 Wh batteries, have a total capacity of 22.2 Wh, well under the device capacity limits. Travel rules and restrictions should be reviewed in advance, but the Tail Co devices fall well under realistic limits being an "installed, non-removable battery" and a very modest capacity that should be acceptable anywhere a cellphone or laptop would. +
-</WRAP>+
  
-The positive lead for the batteries is oriented to the left for J1 and J2 (closest to the corner of the PCB).+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:
  
-{{ :en:manuals:battery_connectors.jpg?nolink&400 |}}+  - **Constant on** is charge in progress. 
 +  - **Off** is charge completed. 
 +  - **Blink on-off** indicates a fault condition.
  
-The plugs can be difficult to remove from the board. It’s suggested to pull out and slightly down towards the board (somewhat of slight rolling motion) helps the plugs release better, instead of pulling straight back.+The ClawGear and EarGear 2 does not have Green LED.
  
-The foam pad faces towards the other battery, but it's not structurally critical. Both batteries are constrained fully in the slots in the ABS case (and care should be taken not to crush the battery ends or wires when closing the case), and won't come in contact with each other or the metal rod around the spine. 
  
-<WRAP round important 90%> +==== Automatic Actions ====
-Be aware that, although the JST-PH 2.0 connectors used on the batteries and across industry are polarized, the polarity that any one battery is set up for is EXTREMELY RANDOM. Positive and negative should be correctly indicated by red and black wires, but the position of the wires in the connector may not be correct for the MiTail (or whatever device you plan on using the battery in), because there's actually no real standard. Plugging in the battery with the polarity reversed can, depending on a lot of factors, be quite bad for the device and/or battery. +
-</WRAP>+
  
 +TailControl will automatically shut down the device if there is no BLE connection for ''currConfig.minsToSleep'' (default 0, [[#Developer Commands (use at own risk)|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).
  
-===== Testing Servos =====+Additional automatic actions are described in [[en:dev:tailcontrol-command-protocol#No-phone Mode|No-phone Mode]], below.
  
-Servo failures can cause the tail not to move (or to curve to one side because one servo is not working), to stop moving after a certain time of operation (thermal issues), or the controller to shut down or reboot (brownout of the ESP32). 
  
-Servos should be tested separately from the control board to ensure that they are operational. An inexpensive tester, such as the [[https://smile.amazon.com/gp/product/B08K7SVXRZ|Barnabas Robotics Servo Motor Tester Kit, 180 Degree 9g Servo Motor + RC Servo Tester Controller + 6V Battery Holder]] (approximately $16.95)is sufficient to determine if the servo is weakshortedor dead.+===== Servo-Based Moves (ClawGearEarGear 2MiTailMiTail Mini, FlutterWings) =====
  
-{{ :en:manuals:servo_tester.png?nolink&400 |}}+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.
  
-<WRAP round tip 90%+A command will return ''LOWBATT'' and reject the command if the battery is less than 10%. ''ERR'' will be returned if the command can'be parsed or otherwise executed.
-Long-term testing can be performed with Casual Mode set with a short intra-move delay, to try to replicate irregular problems. +
-</WRAP>+
  
 +A new command that is received before the currently executing command is finished will immediately end the current command and start the new one.
  
-===== Installing Servos =====+Easing functions are as per the ServoEasing libary [[https://github.com/ArminJo/ServoEasing/blob/bb19cd4cfd9e92fed3b0f91b90a7b2f7dd83094a/src/ServoEasing.h#L296|EaseTypes]]. However, those functions are presented in Hexidecimal and must be converted to a Decimal number before being used in command syntax. The [[https://easings.net/|Easing Functions Cheat Sheet]] is useful to help visualize what easing functions do.
  
-The tails use two 5521MG-equivalent 180 Degrees 20KG digital (PWM, **not ** serial) servos. They are 4.5-6.4VDC standard hobby servos:+**TAILHM** | **H**o**M**e position | 
 +| **TAILS1** | **S**low wag **1** | 
 +| **TAILS2** | **S**low wag **2** | 
 +| **TAILS3** | **S**low wag **3** | 
 +| **TAILFA** | **FA**st wag | 
 +| **TAILSH** | **SH**ort wag | 
 +| **TAILHA** | **HA**ppy wag | 
 +| **TAILER** | **ER**ect | 
 +| **TAILEP** | **E**rect **P**ulse | 
 +| **TAILT1** | **T**remble **1** | 
 +| **TAILT2** | **T**remble **2** | 
 +| **TAILET** | **E**rect **T**rem | 
 +| **TAILU1** | **U**ser defined **1** | 
 +| **TAILU2** | **U**ser defined **2** | 
 +| **TAILU3** | **U**ser defined **3** | 
 +| **TAILU4** | **U**ser defined **4** |
  
-{{ :en:manuals:servo.jpg?nolink&600 |}} 
  
 +===== Stepper-Based Moves (Not Currently Used) =====
  
-==== Servo Connections ====+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.
  
-Internally, the firmware refers to the servos as Servo 1 (the "top" servo) and Servo 2 (the "bottom" servo). The bottom servo cable (the one that emerges from the "bottom" of the case when the servo bracket is installed) goes to the bottom (closest to the board itself) PCB pins.+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.
  
-{{ :en:manuals:bottom_servo.png?nolink&600 |}}+A new command that is received before the currently executing command is finished will immediately end the current command and start the new one.
  
-The board servo connectors are designated as below:+| **TAILHM** | **H**o**M**e position | 
 +| **MOVE1** | **MOVE** **1** | 
 +| **MOVE2** | **MOVE** **2** | 
 +| **MOVE3** | **MOVE** **3** | 
 +| **MOVE4** | **MOVE** **4** | 
 +| **MOVE5** | **MOVE** **5** | 
 +| **MOVE6** | **MOVE** **6** | 
 +| **MOVE7** | **MOVE** **7** | 
 +| **MOVEU1** | **MOVE** **U**ser defined **1** | 
 +| **MOVEU2** | **MOVE** **U**ser defined **2** | 
 +| **MOVEU3** | **MOVE** **U**ser defined **3** | 
 +| **MOVEU4** | **MOVE** **U**ser defined **4** |
  
-{{ :en:manuals:board_connections.jpg?nolink&600 |}} 
  
-The "bottom" (Servo 2) servo cable goes to the bottom (closest to the board itself) PCB pins.+===== ClawGear-only Commands =====
  
-The visible shiny edge of the servo connectors go up (facing the vieweraway from the PCB):+| **CLAPMODE** | Starts Clap Mode (and disables Tilt Modeif enabled), returns ''OK''
 +| **STOPCLAP** | Stops Clap Mode, returns ''OK''
 +| **STOPTILT** | Stops Tilt Mode, returns ''OK''
 +| **TILTMODE** | Starts Tilt Mode (and disables Clap Mode, if enabled), returns ''OK'' |
  
-{{ :en:manuals:servo_connectors.jpg?nolink&400 |}}+===== EarGear 2-only Commands =====
  
-Avoid connecting the servos to the LED pins on the end of the header block. These pins are reserved for the Glow Tip LEDs.+| **LISTENMODE** | Starts Listen Mode ([[#Listen Mode|see below]]), returns ''OK''
 +| **STOPLISTEN** | Stops Listen Mode ([[#Listen Mode|see below]]), returns ''OK''
 +| **STOPTILT** | Stops Tilt Mode ([[#Tilt Mode|see below]]), returns ''OK''
 +| **TILTMODE** | Starts Tilt Mode ([[#Tilt Mode|see below]]), returns ''OK'' |
  
-<WRAP round tip 90%> 
-Before removing the servo cables, it’s recommended to mark the Servo 2 cable (closest to the PCB) with a black marker stripe for reference, as it’s easy for the cables to get confused and difficult to trace the cables when they are bundled. 
-</WRAP> 
  
-If a "fresh" servo (shown in top of photo) is being installed, you will first need to modify the replacement servo to remove the mounting tab furthest from the servo shaft so that it can fit into the case (shown in bottom of photo).+===== Glow Tip LED Patterns =====
  
-{{ :en:manuals:servo_tab_cut.jpg?400 |}}+LED pattern commands return ''<movename> BEGIN'' upon start, and ''<movename> END'' upon completion.
  
-Remove the pulley from the old servo, dismount the old servo and mount the new servo in it's place, and reattach it to the new servo, making sure that the new one is in the correct starting position.+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.
  
-===== Installing Cable Pulleys / Servo Horns =====+| **LEDOFF** | **LED**s **OFF** | 
 +| **LEDREC** | **REC**tangle wave pattern (blink 1 second on, 1 second off) | 
 +| **LEDTRI** | **TRI**angle wave pattern (fade in 1 second, fade out 1 second) | 
 +| **LEDSAW** | **SAW**tooth wave pattern (fade in 2 seconds, off) | 
 +| **LEDSOS** | Morse **SOS** pattern | 
 +| **LEDBEA** | **BEA**con (100ms on every 2 seconds) | 
 +| **LEDFLA** | **FLA**me | 
 +| **LEDSTR** | **STR**obe | 
 +| **LEDUS1** | **US**er defined **1** | 
 +| **LEDUS2** | **US**er defined **2** | 
 +| **LEDUS3** | **US**er defined **3** | 
 +| **LEDUS4** | **US**er defined **4** |
  
-There are seven screws holding the pulley assembly halves together. Three are at the edge, near the cable slot. And four more that hold the servo horn to the pulley. All seven must be removed or loosened to free the cable from the pulley (which is required if the case is being replaced). The screws are M3 × 5.75 mm, Pozidriv PZ1 drive, 7.75 mm overall length. 
  
-<WRAP round important 90%> +===== RGB LED Commands ===== 
-Note that the pulley screws are soft metalUsing medium-sized electric screwdriver that's slow and steady with very firm downward pressure so the bit doesn't skip and grind out the headsDo not install or remove the screws with the pulley attached to the servo to avoid damaging the servo shaft and/or gearbox.+ 
 +RGB support is new with the introduction of the ClawGear, and support is experimental on other hardware. 
 + 
 +All **RGB**''xxx'' pattern commands below (except **RGBOFF**), accept an optional trailing **brightness** parameter, an integer from ''0'' to ''100'' representing the overall brightness of the string in percent (e.g., ''RGBRBW 50''). If omitted, brightness defaults to ''DEFAULT_RGB_BRIGHTNESS'' (100%). 
 + 
 +| **RGBOFF** | **RGB** LEDs **OFF**, returns ''OK''
 +| **RGBBRT** | Set **RGB** **BR**igh**T**ness percentage in NVS and running configuration (e.g., ''RGBBRT 100''), returns ''OK''
 +| **RGBCHS** | **RGB** **CH**a**S**e; theater marquee chase; optionally takes a hue color (in RGB Hexidecimal, otherwise default #7F7F7F is used) (e.g., ''RGBCHS'' [''7F7F7F''] [''brightness'']), returns ''OK''
 +| **RGBCLN** | **RGB** **CY**lo**N**; color dot sweeping back and forth, with fading trails; optionally takes a hue color (in RGB Hexidecimal, otherwise default #FF0000 is used) (e.g., ''RGBCLN'' [''FF0000''] [''brightness'']); returns ''OK''
 +| **RGBDMO** | **RGB** **DE**m**O**; cycle through all the preceding patterns, changing every 10 seconds (e.g., ''RGBDMO'' [''brightness'']); returns ''OK''
 +| **RGBFDE** | **RGB** **F**a**DE**; fade in/out effect (e.g., ''RGBFDE'' [''brightness'']), returns ''OK''
 +| **RGBFIR** | **RGB** **FIR**e; fire effect (e.g., ''RGBFIR'' [''brightness'']), returns ''OK''
 +| **RGBRBW** | **RGB** **R**ain**B**o**W** pattern (e.g., ''RGBRBW'' [''brightness'']), returns ''OK''
 +| **RGBSLD** | **RGB** **S**o**L**i**D**; display a solid color (in RGB Hexidecimal) on all pixels (e.g., ''RGBSLD FFD700'' [''brightness'']), returns ''OK''
 +| **RGBSNO** | **RGB** **SNO**w; snow effect; optionally takes a hue color (in RGB Hexidecimal, otherwise default #FFFFFF is used) (e.g., ''RGBSNO'' [''FFFFFF''] [''brightness'']), returns ''OK''
 +| **RGBTST** | **RGB** **TE**s**T**; color cycle the first and last pixel of the RGB string (endpoints test) (e.g., ''RGBTST'' [''brightness'']), returns ''OK''
 +| **RGBTWK** | **RGB** **TW**in**K**le; random twinkle effect (e.g., ''RGBTWK'' [''brightness'']), returns ''OK''
 +| **RGBWPE** | **RGB** **W**i**PE**; color wipe (e.g., ''RGBWPE'' [''brightness'']), returns ''OK''
 + 
 + 
 +==== RGB Hardware Support ==== 
 + 
 +RGB LED support is provided through various headers, depending on the hardware. Certain hardware configurations require amounts of soldering and electronics design skill to modify, and can damage the board if current draw or other limits are exceeded. Mods are performed solely at user's risk. 
 + 
 + 
 +==== ClawGear ==== 
 + 
 +The ClawGear supports a **maximum** of 42, 5 VDC, WS2811-protocol RGB LED pixels on the Servo 2 connector: 
 + 
 +{{ :en:dev:clawgear_rgb_connections.png?200 |}} 
 + 
 + 
 +==== MiTail ==== 
 + 
 +The MiTail supports **externally-powered**, WS2811-protocol RGB LED pixels on the serial console connector. Note that a level-shifter may need to be used to address voltage-level disparities between the RGB strip and the controller. An [[https://www.adafruit.com/product/6066|Adafruit Pixel Shifter]] is an excellent choice for this. 
 + 
 +{{ :en:dev:mitail_rgb_connections.png?200 |}} 
 + 
 + 
 +==== MiTail Mini ==== 
 + 
 +The MiTail Mini supports a **maximum** of 42, 5 VDC, WS2811-protocol RGB LED pixels on the Servo 2 connector: 
 + 
 +{{ :en:dev:mitail_mini_rgb_connections.png?200 |}} 
 + 
 + 
 +===== Other Commands ===== 
 + 
 +| **AUTOMODE** | **AUTO**nomous **MO**de ([[#Autonomous Mode|see below]]), returns ''OK''
 +| **DSSP** | **D**irectly **S**et **S**ervo **P**osition ([[#Directly Set Servo Position|see below]]), returns ''OK''
 +| **HWVER** | Returns **H**ard**W**are **VER**sion; 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** **P**a**SSKEY**; enable Conference Mode, returns ''OK'', and restarts after 3 seconds ([[#Conference Mode|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 AUTO**nomous Mode, returns ''OK'', followed by ''AUTO END''
 +| **STOPNPM** | **STOP** **N**o-**P**hone **M**ode and disables it in NVS configuration; returns ''OK'', followed by ''AUTO END''
 +| **USERMOVE** | Set user-defined move ([[#User-defined Moves and Glow Tip Patterns|see below]]), returns ''OK''
 +| **STOPPUSSKEY** | **STOP** **P**a**SSKEY**; disable Conference Mode, returns ''OK'', and restarts after 3 seconds ([[#Conference Mode|see below]]) | 
 +| **USERLEDS** | Set user-defined Glow Tip pattern ([[#User-defined Moves and Glow Tip Patterns|see below]]), returns ''OK''
 +| **VER** | Returns the firmware **VER**sion 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 | 
 + 
 + 
 +===== Developer Commands (use at own risk) ===== 
 + 
 +| **BATT** | **BATT**ery percentage, returns the integer value of estimated battery capacity remaining  (e.g., ''61'') | 
 +| **READCONF** | **READ** running **CONF**iguration; 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'' ''nomRGBVolt'' ''maxRGBmAmp''] | 
 +| **WRITECONF** | **WRITE** **CONF**iguration 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'' ''nomRGBVolt'' ''maxRGBmAmp''], returns ''OK''
 +| **SETDISCONNECTEDCOUNT** | **SET** BLE **DISCONNECTED** power off **COUNT**down parameter in NVS and running configuration (in minutes, ''SETDISCONNECTEDCOUNT 0'' disables automatic poweroff), returns ''OK''
 +| **SETHOLDONSTOP** | **SET** whether servo **HOLD** is maintained when the servos **STOP** in NVS and running configuration (maintains servo PWM when not moving, default for EarGear 2); returns ''OK''
 +| **UNSETHOLDONSTOP** | **UNSET** servo **HOLD** when the servos **STOP** in NVS and running configuration (servo PWM is dropped when not moving, default for tail-based devices and ClawGear); returns ''OK''
 +| **SETHOME** | **SET** **HOME** position (0 through 8) for each servo (e.g., ''SETHOME 4 4'') in NVS and running configuration, **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 in NVS and running configuration; returns ''OK''
 +| **SETRGB** | **SET** **RGB** configuration in NVS and running configuration; returns ''OK'' and restarts after 3 seconds; (e.g., ''SETRGB 325 12 2900'') [''numRGBLEDs'' ''nomRGBVolt'' ''maxRGBmAmp''; **NOTE:** the ''nomRGBVolt'' and ''maxRGBmAmp'' are not currently utilized internally, but are required.] | 
 +| **UNSETLISTENMOVES** | **UNSET** internal **LISTEN** Mode **MOVES** to play on a listen event in NVS and running configuration, 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 in NVS and running configuration; returns ''OK''
 +| **UNSETTILTMOVES** | **UNSET** internal **LISTEN** Mode **MOVES** to play on a listen event in NVS and running configuration, 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 **O**ver **T**he **A**ir 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** **CONF**iguration 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'' ''nomRGBVolt'' ''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''
 + 
 + 
 +===== 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<easeType<sub>1</sub>>F<easeType<sub>1</sub>>] A<point<sub>1</sub>>B<point<sub>1</sub>> L<numticks<sub>1</sub>>M<numticks<sub>1</sub>> [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 [[https://github.com/ArminJo/ServoEasing/blob/bb19cd4cfd9e92fed3b0f91b90a7b2f7dd83094a/src/ServoEasing.h#L296|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:** 
 +  * Parameters of type **A**, **B**, **E**, **F**, **H**, **L**, and **M** can appear in any order (e.g., ''AABBSS'', ''ABABSS'', ''ABSABS''). 
 +  * Parameters can be separated by any character that is not a number or a letter (e.g., space, comma, semicolon). However, the letters themselves act as separators, and it is recommended that no additional characters are used, as the serial buffer has a limited capacity and may not be able to store the whole instruction. 
 +  * Depending on the tail and position, it can sag out of the commanded position when servo power is released at the end of the DSSP move. This may cause a visual defect of jerking back into the previous position when the next move starts. 
 + 
 + 
 +==== DSSP Example ==== 
 + 
 +**DSSP E130F130 A1B7 L75M75 H1**\\  
 +**DSSP A1B7 L75M75 H1**\\  
 + 
 + 
 +===== User-defined Moves and Glow Tip Patterns ===== 
 + 
 +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<easeType<sub>1</sub>>F<easeType<sub>1</sub>> ... E<easeType<sub>n</sub>>F<easeType<sub>n</sub>>] A<point<sub>1</sub>>B<point<sub>1</sub>> ... A<point<sub>n</sub>>B<point<sub>n</sub>> L<numticks<sub>1</sub>>M<numticks<sub>1</sub>> ... L<numticks<sub>n</sub>>M<numticks<sub>n</sub>> [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 [[https://github.com/ArminJo/ServoEasing/blob/bb19cd4cfd9e92fed3b0f91b90a7b2f7dd83094a/src/ServoEasing.h#L296|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<point<sub>1</sub>> ... A<point<sub>n</sub>> [S|L]<numticks<sub>1</sub>> ... [S|L]<numticks<sub>n</sub>>**   
 + 
 +^ 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:** 
 +  * Parameters of type **A**, **B**, **E**, **F**, **H**, **L**, **M**, and **S** can appear in any order (e.g., `EEAABBSS`, `ABAEBESS`, etc.). 
 +  * Parameters can be separated by any character that is not a number or a letter (e.g., space, comma, semicolon). However, the letters themselves act as separators, and it is recommended that no additional characters are used, as the serial buffer has a limited capacity and may not be able to store the whole instruction. 
 +  * Note the upper limit on the **P** parameter (and the consequential limit of moves in a move or LED pattern). 
 +  * There is a **128-character limit** on the serial input buffer. 
 + 
 +Position limits on the tail can be visualized as such: 
 + 
 +{{:en:dev:position_limits_visualization.png?400|}} 
 + 
 + 
 +==== 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 E0E66 F0F66 A7A1 B7B1 L75L75 M75M75 H1** 
 + 
 +  * **U1** Store into user preset 1   
 +  * **P2** The move consists of 2 points   
 +  * **N3** Repeat the sequence 3 times   
 +  * **E0E66** Servo 1 move to Position 1 has no easing, move to Position 2 uses EASE_CUBIC_OUT (0x42) 
 +  * **F0F66** Servo 2 move to Position 1 has no easing, move to Position 2 uses EASE_CUBIC_OUT (0x42) 
 +  * **A7A1** Servo 1 moves from 7 to 1 (143° to 41°)   
 +  * **B7B1** Servo 2 moves exactly as Servo 1   
 +  * **L75L75** Position 2 is reached in 75 * 20 ms = 1.5 s; return to Position 1 in the same time   
 +  * **L75L75** Position 2 is reached in 75 * 20 ms = 1.5 s; return to Position 1 in the same time   
 +  * **H1** Home at end of move 
 + 
 + 
 +=== 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** 
 + 
 +  * **U2** Store into user preset 2   
 +  * **P4** The move consists of 4 points   
 +  * **N3** Repeat the sequence 3 times   
 +  * **A0A4A8A4** Move Servo 1 90° at a time, starting from 0°   
 +  * **B4B8B4B0** Move Servo 2 90° at a time, starting from 90°   
 +  * **L100L100L100L100** Each Servo 1 move takes 100 * 20 ms = 2 s to complete   
 +  * **M100M100M100M100** Each Servo 2 move takes 100 * 20 ms = 2 s to complete   
 +  * **H1** Home at end of move 
 + 
 +<WRAP round info 90%> 
 +Because no easing parameters (''E'' or ''F'') are specified, no easing is used by default.
 </WRAP> </WRAP>
  
-==== Pulley Calibration / Resetting Servo Home Position ==== 
  
-To do this correctly, first power up the PCB with the new servo attached directly to the board. That will center or "home" the servo before you reattach the pulley. Secondly, make sure the pulley is in the following "ten minutes to the hour" position; the topmost screw head will also align with the servo mount rib below it (note that the servo splines may not line up perfectly and may land a tooth to the left or the right slightly or a particular trail might bias more towards the center screw):+==== USERLEDS Examples ====
  
-{{ :en:manuals:pulley_alignment.jpg?nolink&600 |}} 
  
 +=== Example 1 – Beacon (same as the ''LEDBEA'' command) ===
  
-===== Glow Tip - Installing LED Lights =====+The Glow Tip LEDs light up for 100 ms every 1 s (Airbus A320 tail strobe).
  
-The tails use 3 or 4 5V SMD 3528 LED strip lights, connected to the first pair (closest to the edge of the board) of pins on J5 (positive pin is up, negative pin is closest to the PCB).+**USERLEDS U1 P2 N5 A8A0 S5S50** 
 +**LEDUS1**
  
-{{ :en:manuals:glow_tip.jpg?400 |}}+  * **U1** Store into user preset 1   
 +  * **P2** The pattern consists of 2 brightness points   
 +  * **N5** Repeat pattern 5 times   
 +  * **A8A0** Start at full brightness, then turn off   
 +  * **S5S95** On for 5 * 20 ms = 100 ms; off for 50 * 20ms = 1 s  
  
 +=== Example 2 – Fade in/out (similar to ''LEDTRI'') ===
  
-===== Board-level Repairs and Modifications =====+The Glow Tip LEDs light up slowly, then dim until completely off; this is repeated 3 times.
  
-The tail PCB uses small surface-mounted componentsand is not generally considered repairable unitReplacements are available for order from The Tail Company.+**USERLEDS U2 P2 N3 A0A8 L100L100** 
 + 
 +  * **U2** Store into user preset 2   
 +  * **P2** The pattern consists of 2 brightness points   
 +  * **N3** Repeat pattern 3 times   
 +  * **A0A8** Start offfinish at full brightness   
 +  * **L100L100** Each brightness point is reached in 100 * 20 ms = 2 s 
 + 
 + 
 +===== Conference Mode ===== 
 + 
 +Conference mode pairs the user's phone with the TailControl device and establishes 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 wayThis protects your device in a number of different ways: 
 + 
 +  * **Authentication:** verifying the identity of the device connecting. 
 +  * **MITM (Man In The Middle):** process by which a third device impersonates the other two legitimate devices, in order to fool them into connecting to it. Both BLE central and peripheral will connect to the malicious device, which in turn routes the communication between the other two devices. The malicious device intercepts all data being sent and can inject false data or remove data before it reaches its recipient. 
 +  * **Replay Attack:** a type of network attack in which an attacker captures a valid network transmission and then retransmits it later. The main objective is to trick the system into accepting the retransmission of the data as legitimate.
  
 <WRAP round important 90%> <WRAP round important 90%>
-Users who are experienced with surface-mount board rework may attempt repair at their own riskbut the Tail Company is unable to provide specific assistance with this. +Do **NOT** attempt to use Conference Mode on TailControl firmware prior to 5.3.0or a condition requiring repair of the control board can occur.</WRAP>
-</WRAP>+
  
-The most likely repair would be to replace the USB connector or a damaged tactile switch, which are reinforced with hot glue. Removal of the hot glue is possible, but requires care to prevent components from being removed from the board, along with the glue. The best method to remove the hot glue is high-concentration Isopropyl alcohol (IPA), also known as rubbing alcohol. Soak a Q-Tip in rubbing alcohol, and working your way from the edges in, brush the dried glue gently with the Q-Tip. As the alcohol weakens the adhesive, lift the edge and peel the hot glue away from the board surface, reapplying the alcohol as resistance is met from the glue. 
  
 +==== Enabling Conference Mode (Pairing and Binding) ====
  
-===== Charging =====+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.
  
-Some versions of tail-series controller hardware require specific charging support. The version of hardware can be determined by looking at the "About your gear" in The Tail Company App, the "Hardware Version" will  say `MITAIL 3.x`, which can be used to determine what kind of charging is required.+**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.
  
-==== USB Power Delivery (USB PD) ==== 
  
-MiTail hardware versions v3.2 through v3.5 require a USB Power Delivery (USB PDcapable charging adapterPD charging is only possible using a USB-C to USB-C cable and a USB PD chargers togetherAdapters with USB-A output, even with USB-A to USB-C cable **WILL NOT** charge MiTailThe adapter should provide at least 9V almost all PD adapters can. If the adapter's rated power is less than 24Wcharging will take around 3 hours.+==== Disabling Conference Mode ==== 
 + 
 +Conference Mode can be disabled by sending the ''STOPPASSKEY'' commandThis 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 [[en:dev:tailcontrol-command-protocol#Unbinding / Factory Reset|Unbinding / Factory Reset]], below. 
 + 
 + 
 +==== Unbinding / Factory Reset ==== 
 + 
 +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 TailControl device (which resets all persistent options to defaults and removes all bonding information): 
 + 
 +  Sending a ''FORMATNVS'' command to the TailControl console. This will factory-reset and reboot. 
 +  Performing factory reset using the single button (TailControl v5.1.0, forward): 
 +      Press and hold the power button. 
 +      - At approximately 3 seconds, the blue LED will flash three times and turn off. Continue to hold without releasing the button. If you wish to cancel the factory reset, release at any time before the next step and the device will power off. 
 +      - Ten seconds after the triple-flash (13 seconds total of continuous holding)the blue LED will blink quickly continuously, release to perform the factory reset. The blue LED will go solid, then the ESP will restart, with the blue LED flashing slowly (ready to connect). 
 + 
 +<WRAP round info 90%> 
 +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). 
 + 
 +  * On Android, enter Settings, Connections, Bluetooth and find the device to remove (e.g., "mitail"). Select the gear icon, and then select "Unpair". Confirm the dialog to unpair and forget the device. 
 +  * On iOS, enter Settings, Bluetooth and find the device to remove under "My Devices". Select the circle-i icon next to the device name, and then select "Forget This Device". Confirm by selecting "Forget Device".
  
-<WRAP round tip 90%> 
-If the MiTail red LED is not "breathing" red, it is not charging! 
 </WRAP> </WRAP>
  
-|  {{ :en:manuals:usb-a_to_usb-c.jpg?nolink&400 |}}  |  {{ :en:manuals:usb-c_to_usb-c.jpg?nolink&400 |}}  |   
-|  This **WILL NOT** charge a MiTail (but will charge an EarGear 2).\\ Even though this is a PD charger, it's using a USB-A to USB-C cable,\\ and the tail and charger can't negotiate.  |  This **WILL** charge a MiTail (and an EarGear 2).\\ This is a PD charger, with a USB-C to USB-C cable.  |   
  
 +===== Listen Mode =====
  
-==== "Plain" USB ====+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).
  
-MiTail hardware versions v3.6 onward require a USB charger. Charging can be performed through any USB-C cable (such as the EarGear2 USB-A to USB-C charging cable and charger). Note that on these boards, the Red LED is controlled directly by the battery charger and there is **NO** breathing animation. Instead, the Red LED is constant on when charging, and off when charging is disconnected or when charging is complete.+Development support for basic sound localization for future hardware is supportedreplacing 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.
  
-===== Indicator Lights =====+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.
  
-The following visual indicators are presented by the firmware on the board: 
  
 +===== No-phone Mode =====
  
-==== Blue LED ====+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.
  
-The Blue LED (D4) has five states:+**AUTOMODE G<n>[G<n>[G<n>]] T<1 ... 240>T<1 ... 240>T<251 ... 254>**
  
-  - **Off** when powered off. +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.
-  - **Blink on-off** when BLE is disconnected. +
-  - **Fade-off** when BLE is disconnected and Autonomous Mode (either iOS Casual Mode or No-phone Modeis active. +
-  - **Constant on** when BLE is connected. +
-  - **Fade-on** when BLE is connected and Autonomous Mode is active. +
-  - **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. +
-  - **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.+
  
 +No-phone Mode is suspended (after completing any ongoing move) if a BLE connection is made. It will resume after BLE is disconnected.
  
-  * Red LED: Slow breathing = tail is charging (when connected to USB PD power).   +^ Group  ^ Move Group Name  ^ Move List  
-  * Red LED: Solid on = charge complete (when connected to USB PD power).  +| 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 |
  
-  * Blue LED: Blinking = ready to connect.   +The parameter order is not important, except that the three ''T'' parameters are interpreted in the order specified below.
-  * Blue LED: ON = MiTail is connected +
  
-  Green LED: ON = USB power is charging batteriesVisible only on the PCB +^ 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 | <25**1** ... 25**4**> (1 ... 4 min) |
  
-==== Red LED ====+No-phone Mode (NPM) will cause the tail to delay one to four minutes (based on the setting of the third ''T'' parameter of 25**1** through 25**4**) 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).
  
-For v3.2 through v3.5 tail-series controller hardware, the Red LED (D5has four states:+No-phone Mode is suspended (after completing any ongoing moveif a BLE connection is made. It will resume after BLE is disconnected.
  
-  - **Off** during normal operation. +**STOPNPM**
-  - **Breathing** while charging. +
-  - **Constant on** when charging is complete. +
-  - **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:+Stops No-phone mode and disables it in NVS configuration.
  
-  - **Off** when charging is disconnected and when charging complete. 
-  - **Constant on** when charging. 
-   
-**Note:** Unlike the DIGITAiL, MiTail, and MiTail Mini **can** be used while charging. 
  
 +==== No-phone Mode Example ====
  
-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:+**AUTOMODE T15T60T243 G1G2**
  
-  **Constant on** is charge in progress. +  * **T15** 15-second minimum random pause between moves 
-  **Off** is charge completed. +  * **T60** 60-second (1 minute) maximum random pause between moves 
-  **Blink on-off** indicates fault condition.+  * **T240** 3600-second (240 * 15 = 3600 s = 1 hour) total duration of Autonomous Mode 
 +  * **G1G2** Randomly select move from groups 1 and 2
  
  
-===== Function Check =====+===== Tilt Mode =====
  
-The MiTail should be checked with the tail oriented as if hanging from the belt mountTesting the tail with it horizontal will cause the tail to move unpredictablyUpside-down tails (with the black vinyl-coated pull cables towards the floor) won't appear to work at all.+Tilt Mode is only available on the ClawGear and EarGear 2When 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 clientIf tiltModeMovesEnabled is set (default), then the firmware move will be triggered, otherwise the controlling app will be expected to send a move (if desired).
  
-  * Test fast and slow moves. Tail should move **symmetrically** and **smoothly**.   +Triggering by Tilt Mode is inhibited when the ears are in motionas well as a 3-second counter that runs once a sound trigger has finished executing a move AND the ClawGear/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.
-  * If a Glow Tip is presenttest that the tip lights up and animates correctly.   +
-  * Test that the tail charges and indicates charging and end-of-charge correctly +
  
  
-== Copyright 2023-2026 © The Mechanical Tail Company Limited contact@thetailcompany.com. All Rights Reserved. ==+== Copyright 2024-2026 © The Mechanical Tail Company Limited contact@thetailcompany.com. All Rights Reserved. The Mechanical Tail Company Limited also claims trademark rights in the following: TailControl, MiTail, MiTail Mini, FlutterWings, and EarGear.  Any unauthorized use is expressly prohibited. ==