# User Guide

## Hardware Overview

<figure><img src="https://content.gitbook.com/content/tpXGY8yRGIrUmuuiav4P/blobs/nmLl2pKhr2DgGCDoPKRn/image.png" alt=""><figcaption><p>RoverHatGen2 (Top)</p></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/tpXGY8yRGIrUmuuiav4P/blobs/IC8jUGaKHPW3ZnqCkdP0/image.png" alt=""><figcaption><p>RoverHatGen2 LEDs (D1-D4) and pushbutton (SW1). The silk screen denotes the phase of each motor channel with <em>PA</em> and <em>PC</em></p></figcaption></figure>

## BLE Role Selection

The device boots as a BLE <mark style="color:blue;">Central</mark> device after POR by default. D1 will be <mark style="color:blue;">BLUE</mark>.

<mark style="color:yellow;">Press and hold push button (SW1)</mark> during POR to boot as a BLE <mark style="color:green;">Peripheral</mark> Device. D1 will be <mark style="color:green;">GREEN.</mark>

## BLE Central Role

### LED States

| RGB1                                  | RGB2                                  | RGB3                                  | RGB4                                                                          | State          |
| ------------------------------------- | ------------------------------------- | ------------------------------------- | ----------------------------------------------------------------------------- | -------------- |
| <mark style="color:blue;">BLUE</mark> | OFF                                   | OFF                                   | OFF                                                                           | Idle           |
| <mark style="color:blue;">BLUE</mark> | <mark style="color:blue;">BLUE</mark> | OFF                                   | OFF                                                                           | Scanning       |
| <mark style="color:blue;">BLUE</mark> | <mark style="color:blue;">BLUE</mark> | <mark style="color:blue;">BLUE</mark> | OFF                                                                           | Paired         |
| <mark style="color:blue;">BLUE</mark> | <mark style="color:blue;">BLUE</mark> | <mark style="color:blue;">BLUE</mark> | <mark style="color:blue;">BLUE</mark> <mark style="color:green;">GREEN</mark> | Bond Saved     |
| <mark style="color:blue;">BLUE</mark> | <mark style="color:blue;">BLUE</mark> | <mark style="color:blue;">BLUE</mark> | <mark style="color:blue;">BLUE</mark>                                         | Encrypted Pair |

## BLE Peripheral Role

### LED States

| RGB1                                    | RGB2                                    | RGB3                                    | RGB4 | State       |
| --------------------------------------- | --------------------------------------- | --------------------------------------- | ---- | ----------- |
| <mark style="color:green;">GREEN</mark> | OFF                                     | OFF                                     | OFF  | Idle        |
| <mark style="color:green;">GREEN</mark> | <mark style="color:green;">GREEN</mark> | OFF                                     | OFF  | Advertising |
| <mark style="color:green;">GREEN</mark> | <mark style="color:green;">GREEN</mark> | <mark style="color:green;">GREEN</mark> | OFF  | Paired      |

### Unsolicited Data Characteristic

This characteristic is used to send telemetry data to the host via BLE notifications. Each 20-byte notification has the following format:

| Byte |     Field    |                                      Description                                     |
| :--: | :----------: | :----------------------------------------------------------------------------------: |
|   0  |   Packet ID  |                     Describes the contents of the Data Byte Field                    |
|   1  | Packet Index | Rolling counter. Packets with equal Packet Indices are from the same sample interval |
|   2  |  Data Byte 0 |                              Refer to dedicated section                              |
|  ... |              |                                                                                      |
|  19  | Data Byte 17 |                                                                                      |

{% hint style="info" %}
*Unsolicited Data* notifications will be sent out at a rate of 1 Hz. Frames with equivalent *Packet Indices* will have an inter-frame delay of 100 ms between them.
{% endhint %}

#### Packet ID 1 Data Bytes

This packet contains the raw IMU data and TOF distance measurement in mm (if active).

<table><thead><tr><th align="center">Byte</th><th width="249" align="center">Description</th><th align="center">Type</th></tr></thead><tbody><tr><td align="center">0</td><td align="center">Accel X LSB</td><td align="center">int16</td></tr><tr><td align="center">1</td><td align="center">Accel X MSB</td><td align="center"></td></tr><tr><td align="center">2</td><td align="center">Accel Y LSB</td><td align="center">int16</td></tr><tr><td align="center">3</td><td align="center">Accel Y MSB</td><td align="center"></td></tr><tr><td align="center">4</td><td align="center">Accel Z LSB</td><td align="center">int16</td></tr><tr><td align="center">5</td><td align="center">Accel Z MSB</td><td align="center"></td></tr><tr><td align="center">6</td><td align="center">Gyro X LSB</td><td align="center">int16</td></tr><tr><td align="center">7</td><td align="center">Gyro X MSB</td><td align="center"></td></tr><tr><td align="center">8</td><td align="center">Gyro Y LSB</td><td align="center">int16</td></tr><tr><td align="center">9</td><td align="center">Gyro Y MSB</td><td align="center"></td></tr><tr><td align="center">10</td><td align="center">Gyro Z LSB</td><td align="center">int16</td></tr><tr><td align="center">11</td><td align="center">Gyro Z MSB</td><td align="center"></td></tr><tr><td align="center">12</td><td align="center">TOF Distance LSB (mm)</td><td align="center">uint16</td></tr><tr><td align="center">13</td><td align="center">TOF Distance MSB (mm)</td><td align="center"></td></tr><tr><td align="center">14</td><td align="center">Reserved</td><td align="center"></td></tr><tr><td align="center">15</td><td align="center">Reserved</td><td align="center"></td></tr><tr><td align="center">16</td><td align="center">Reserved</td><td align="center"></td></tr><tr><td align="center">17</td><td align="center">Reserved</td><td align="center"></td></tr></tbody></table>

#### IMU Data Conversion

The following code snippets show how to convert the raw int16 accelerometer and gyroscope data to their respective units:

{% code title="Accelerometer" overflow="wrap" lineNumbers="true" %}

```c
float_t lsm6dsox_from_fs8_to_mg(int16_t lsb)
{
  return ((float_t)lsb) * 0.244f;  // mg
}
```

{% endcode %}

{% code title="Gyroscope" overflow="wrap" lineNumbers="true" %}

```c
float_t lsm6dsox_from_fs500_to_mdps(int16_t lsb)
{
  return ((float_t)lsb) * 17.50f;  // mdps
}
```

{% endcode %}

{% hint style="info" %}
Accelerometer full-scale: +/- 8g

Gyroscope full-scale: +/- 500 dps
{% endhint %}

#### Packet ID 2 Data Bytes

This packet contains the motor current measurements in A.

| Byte |      Description     |  Type |
| :--: | :------------------: | :---: |
|   0  | Motor 1 Current XLSB | float |
|   1  |  Motor 1 Current LSB |       |
|   2  |  Motor 1 Current MSB |       |
|   3  | Motor 1 Current XMSB |       |
|   4  | Motor 2 Current XLSB | float |
|   5  |  Motor 2 Current LSB |       |
|   6  |  Motor 2 Current MSB |       |
|   7  | Motor 2 Current XMSB |       |
|   8  | Motor 3 Current XLSB | float |
|   9  |  Motor 3 Current LSB |       |
|  10  |  Motor 3 Current MSB |       |
|  11  | Motor 3 Current XMSB |       |
|  12  | Motor 4 Current XLSB | float |
|  13  |  Motor 4 Current LSB |       |
|  14  |  Motor 4 Current MSB |       |
|  15  | Motor 4 Current XMSB |       |
|  16  |       Reserved       |       |
|  17  |       Reserved       |       |

### &#x20;BLE Commands

The following table outlines BLE commands supported by the Rover. Refer to respective section for more information.

<table><thead><tr><th width="281">Command Name</th><th width="270" align="center">Value (HEX)</th><th align="right">Mailbox Parameter(s)</th></tr></thead><tbody><tr><td><a href="#set-motor-1-throttle">Set Motor 1 Throttle</a>**</td><td align="center">0x0003</td><td align="right">Motor 1 Throttle</td></tr><tr><td><a href="#set-motor-2-throttle">Set Motor 2 Throttle</a>**</td><td align="center">0x0004</td><td align="right">Motor 2 Throttle</td></tr><tr><td><a href="#set-motor-1-and-2-throttles">Set Motor 1 and 2 Throttles</a>**</td><td align="center">0x0005</td><td align="right">Motor 1, Motor 2 Throttles</td></tr><tr><td><a href="#kill-all-motors">Kill All Motors</a>**</td><td align="center">0x0007</td><td align="right">N/A</td></tr><tr><td><a href="#set-peripheral-state">Set Peripheral State</a></td><td align="center">0x000D</td><td align="right">Peripheral ID, Peripheral State</td></tr><tr><td><a href="#set-motor-3-throttle">Set Motor 3 Throttle</a></td><td align="center">0x0010</td><td align="right">Motor 3 Throttle</td></tr><tr><td><a href="#set-motor-4-throttle">Set Motor 4 Throttle</a></td><td align="center">0x0011</td><td align="right">Motor 4 Throttle</td></tr><tr><td><a href="#set-motor-3-and-4-throttles">Set Motor 3 and 4 Throttles</a></td><td align="center">0x0012</td><td align="right">Motor 3, Motor 4 Throttles</td></tr><tr><td><a href="#set-all-motor-throttles">Set All Motor Throttles</a></td><td align="center">0x0013</td><td align="right">Motor 1, Motor 2, Motor 3, Motor 4 Throttles</td></tr><tr><td><a href="#set-all-motor-throttles-finite">Set All Motor Throttles (Finite)</a></td><td align="center">0x0014</td><td align="right">Throttle and timeout for each motor</td></tr><tr><td><a href="#system-reset">System Reset</a></td><td align="center">0x0015</td><td align="right">N/A</td></tr><tr><td><a href="#no-operation-nop">No Operation (NOP)</a></td><td align="center">0x0016</td><td align="right">N/A</td></tr><tr><td><a href="#set-stick-dead-zones">Set Stick Dead Zones</a></td><td align="center">0x0017</td><td align="right">Left Stick X and Y Dead Zone, Right Stick X and Y Dead Zone</td></tr><tr><td><a href="#set-motor-csa-gains">Set Motor CSA Gains</a></td><td align="center">0x0018</td><td align="right">Motor 1,2,3 and 4 CSA Gains</td></tr><tr><td><a href="#control-telemetry">Control Telemetry</a></td><td align="center">0x0019</td><td align="right">Enable/Disable</td></tr></tbody></table>

\*\*Legacy MotorHAT BLE commands.

#### Set Motor 1 Throttle&#x20;

* Command: 0x0003
* Mailbox:
  * Byte 0:&#x20;
    * Description: Motor Throttle
    * Range: -100 to 100, inclusive
    * Type: int8
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_INV\_PARAM
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### Set Motor 2 Throttle&#x20;

* Command: 0x0004
* Mailbox:
  * Byte 0:&#x20;
    * Description: Motor Throttle
    * Range: -100 to 100, inclusive
    * Type: int8
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_INV\_PARAM
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### Set Motor 1 and 2 Throttles

* Command: 0x0005
* Mailbox:
  * Byte 0:&#x20;
    * Description: Motor 1 Throttle
    * Range: -100 to 100, inclusive
    * Type: int8
  * Byte 1:&#x20;
    * Description: Motor 2 Throttle
    * Range: -100 to 100, inclusive
    * Type: int8
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_INV\_PARAM
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### Kill All Motors&#x20;

* Command: 0x0007
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### Set Peripheral State&#x20;

Enables/disables optional on-board/off-board peripherals.

{% hint style="info" %}
State stored in NVM. <mark style="color:yellow;">Default: All peripherals disabled.</mark>
{% endhint %}

{% hint style="warning" %}
If successful, device performs a power-on-reset (POR) after 500 ms.
{% endhint %}

* Command: 0x000D
* Mailbox:
  * Byte 0:&#x20;
    * Description: Peripheral ID
    * Range:
      * Supported ID(s)
        * <mark style="color:yellow;">0x00: MODI</mark>
    * Type: uint8
  * Byte 1:
    * Description: Peripheral State
    * Range:&#x20;
      * 0 (dec): Peripheral disabled
      * 1 (dec): Peripheral enabled
    * Type: uint8
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_INV\_PARAM
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### Set Motor 3 Throttle&#x20;

* Command: 0x0010
* Mailbox:
  * Byte 0:&#x20;
    * Description: Motor Throttle
    * Range: -100 to 100, inclusive
    * Type: int8
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_INV\_PARAM
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### Set Motor 4 Throttle&#x20;

* Command: 0x0011
* Mailbox:
  * Byte 0:&#x20;
    * Description: Motor Throttle
    * Range: -100 to 100, inclusive
    * Type: int8
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_INV\_PARAM
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### Set Motor 3 and 4 Throttles

* Command: 0x0012
* Mailbox:
  * Byte 0:&#x20;
    * Description: Motor 3 Throttle
    * Range: -100 to 100, inclusive
    * Type: int8
  * Byte 1:&#x20;
    * Description: Motor 4 Throttle
    * Range: -100 to 100, inclusive
    * Type: int8
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_INV\_PARAM
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### Set All Motor Throttles

* Command: 0x0013
* Mailbox:
  * Byte 0:&#x20;
    * Description: Motor 1 Throttle
    * Range: -100 to 100, inclusive
    * Type: int8
  * Byte 1:&#x20;
    * Description: Motor 2 Throttle
    * Range: -100 to 100, inclusive
    * Type: int8
  * Byte 2:&#x20;
    * Description: Motor 3 Throttle
    * Range: -100 to 100, inclusive
    * Type: int8
  * Byte 3:&#x20;
    * Description: Motor 4 Throttle
    * Range: -100 to 100, inclusive
    * Type: int8
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_INV\_PARAM
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### Set All Motor Throttles (Finite)

* Command: 0x0014
* Mailbox:
  * Byte 0:&#x20;
    * Description: Motor 1 Throttle
    * Range: -100 to 100, inclusive
    * Type: int8
  * Bytes 1-4:
    * Description: Motor 1 Timeout
    * Range: -1, 0 to 2^31, inclusive
      * <mark style="color:yellow;">0 (dec): Motor throttle is applied indefinitely</mark>
      * <mark style="color:yellow;">-1 (dec): Current motor state remains unchanged</mark>
    * Type: int32
  * Byte 5:&#x20;
    * Description: Motor 2 Throttle
  * Bytes 6-9:
    * Description: Motor 2 Timeout
  * Byte 10:&#x20;
    * Description: Motor 3 Throttle
  * Bytes 11-14:
    * Description: Motor 3 Timeout
  * Byte 15:&#x20;
    * Description: Motor 4 Throttle
  * Bytes 16-19:
    * Description: Motor 4 Timeout
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_INV\_PARAM
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### System Reset

Performs a power on reset (POR) after 1 second.

* Command: 0x0015
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### No Operation (NOP)

Does nothing. Can be used to poll telemetry data safely.

* Command: 0x0016
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS

#### Set Stick Dead Zones

Sets the dead zone for both the left and right sticks of the controller. &#x20;

For example, if dead zone is set to 100 (dec), a stick value that falls within range -100 <= *stick value* <= +100 will be set to 0.

{% hint style="info" %}
Value is stored in NVM. <mark style="color:yellow;">Default: 20 (dec)</mark>&#x20;
{% endhint %}

{% hint style="warning" %}
Analog sticks experience stick drift as they experience heavy use. Therefore, it is typical for the user to increase the dead zone to prevent false positives.
{% endhint %}

* Command: 0x0017
* Mailbox:
  * Bytes 0-1:&#x20;
    * Description: **Left** Stick X Dead Zone (+/-)
    * Range: 0 to 2^16 -1
    * Type: uint16
  * Bytes 2-3:&#x20;
    * Description: **Left** Stick Y Dead Zone (+/-)
    * Range: 0 to 2^16 -1
    * Type: uint16
  * Bytes 4-5:&#x20;
    * Description: **Right** Stick X Dead Zone (+/-)
      * Range: 0 to 2^16 -1
      * Type: uint16
  * Bytes 6-7:&#x20;
    * Description: **Right** Stick Y Dead Zone (+/-)
      * Range: 0 to 2^16 -1
      * Type: uint16
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_INV\_PARAM
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### Set Motor CSA Gains

Sets the gain of the Current Sense Amplifier (CSA) for each of the motor channels.

{% hint style="info" %}
Value is stored in NVM. <mark style="color:yellow;">Default: 0x03 (2.0 V/A , +/- 825 mA max current)</mark>
{% endhint %}

{% hint style="warning" %}
If successful, device performs a power-on-reset (POR) after 500 ms.
{% endhint %}

* Command: 0x0018
* Mailbox:
  * Byte 0:&#x20;
    * Description: Motor 1 CSA Gain
    * Range:
      * <mark style="color:yellow;">0x00: 0.25 V/A (+/- 6.6 A max current)</mark>
      * <mark style="color:yellow;">0x01: 0.5 V/A (+/- 3.3 A max current)</mark>
      * <mark style="color:yellow;">0x02: 1.0 V/A (+/- 1.65 A max current)</mark>
      * <mark style="color:yellow;">0x03: 2.0 V/A (+/- 825 mA max current)</mark>
    * Type: uint8
  * Byte 1:
    * Description: Motor 2 CSA Gain
    * Range: See above
    * Type: uint8
  * Byte 2:
    * Description: Motor 3 CSA Gain
    * Range: See above
    * Type: uint8
  * Byte 3:
    * Description: Motor 4 CSA Gain
    * Range: See above
    * Type: uint8
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_INV\_PARAM
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### Control Telemetry

This enables/disables telemetry data which consists of on-board sensor data and/or active, off-board peripherals (i.e. MODI) data.&#x20;

If enabled, UART *Command Response* frames will contain sensor data. When device is in the *Peripheral* state and paired with via BLE, telemetry data will be sent in the form of BLE notifications via the *Unsolicited Data* characteristic. Refer to [dedicated section](#unsolicited-data-characteristic) for more information.

If disabled, UART *Command Response* frame sensor data fields will be zero. No BLE notifications will be sent.

{% hint style="warning" %}
When in *BLE Peripheral* mode, telemetry will automatically be disabled upon link termination. *Control Telemetry* command will need to be resent by host upon link re-establishment to re-enable telemetry BLE notifications.
{% endhint %}

* Command: 0x0019
* Mailbox:
  * Byte 0:&#x20;
    * Description: Enable/Disable
    * Range: If 1 (dec), telemetry is enabled. If 0 (dec), telemetry is disabled.
    * Type: uint8
* Command Response(s)
  * MDRDIOPROFILE\_CMDRSP\_SUCCESS
  * MDRDIOPROFILE\_CMDRSP\_FAILURE

#### Command Response Codes

<table><thead><tr><th width="379">Name</th><th>Value (uint16)</th><th>Notes</th></tr></thead><tbody><tr><td>MDRDIOPROFILE_CMDRSP_SUCCESS</td><td>0x0000</td><td>Generic success</td></tr><tr><td>MDRDIOPROFILE_CMDRSP_BUSY</td><td>0x0001</td><td>System busy with previous command</td></tr><tr><td>MDRDIOPROFILE_CMDRSP_INV_PARAM</td><td>0x00FD</td><td>Invalid command parameter(s)</td></tr><tr><td>MDRDIOPROFILE_CMDRSP_INV_CMD</td><td>0x00FE</td><td>Invalid command</td></tr><tr><td>MDRDIOPROFILE_CMDRSP_FAILURE</td><td>0x00FF</td><td>Generic failure</td></tr></tbody></table>

## UART Interface

This section outlines the UART functionality of the device.

### UART Settings

* Baud Rate: 115200
* Data Bit(s): 8
* Stop Bit(s): 1
* Parity: None
* Flow Control: None
* Endianness: Little (LSB first)

### Host To RoverGen2: *Command* Frame Format

The *Command* frame consists of the 4-byte preamble (0xDEADBEEF), command ID, mailbox data and the 8-bit CRC, for a total of **27 bytes**.

<table data-full-width="true"><thead><tr><th align="center">Byte #</th><th align="center">Byte Description</th><th align="center">Value</th></tr></thead><tbody><tr><td align="center">0</td><td align="center">Preamble XLSB</td><td align="center">0xEF</td></tr><tr><td align="center">1</td><td align="center">Preamble LSB</td><td align="center">0xBE</td></tr><tr><td align="center">2</td><td align="center">Preamble MSB</td><td align="center">0xAD</td></tr><tr><td align="center">3</td><td align="center">Preamble XMSB</td><td align="center">0xDE</td></tr><tr><td align="center">4</td><td align="center">Command LSB</td><td align="center"><a href="#ble-commands">Commands</a></td></tr><tr><td align="center">5</td><td align="center">Command MSB</td><td align="center"></td></tr><tr><td align="center">6</td><td align="center">Mailbox Byte 0</td><td align="center"></td></tr><tr><td align="center">...</td><td align="center">...</td><td align="center"></td></tr><tr><td align="center">25</td><td align="center">Mailbox Byte 19</td><td align="center"></td></tr><tr><td align="center">26</td><td align="center">8-bit CRC</td><td align="center"></td></tr></tbody></table>

### RoverHatGen2 To Host: *Command Response* Frame Format

The *Command Response* frame is solicited; it is generated on each received *Command* frame from the host.

It consists of the 4-byte preamble (0xDEADBEEF), the Command ID which generated the Command Response frame, the Response ID itself, IMU data, TOF distance data, and the 8-bit CRC, for a total of ~~**23**~~**&#x20;39 bytes**.

{% hint style="warning" %}
It is highly recommended that the Host await the *Command Response,* before sending any subsequent *Command* frames.
{% endhint %}

| Byte # |   Byte Description   |                 Value                |
| :----: | :------------------: | :----------------------------------: |
|    0   |     Preamble XLSB    |                 0xEF                 |
|    1   |     Preamble LSB     |                 0xBE                 |
|    2   |     Preamble MSB     |                 0xAD                 |
|    3   |     Preamble XMSB    |                 0xDE                 |
|    4   |      Command LSB     |       [Commands](#ble-commands)      |
|    5   |      Command MSB     |                                      |
|    6   |     Response LSB     | [Responses](#command-response-codes) |
|    7   |     Response MSB     |                                      |
|    8   |      Accel X LSB     |                 int16                |
|    9   |      Accel X MSB     |                                      |
|   10   |      Accel Y LSB     |                 int16                |
|   11   |      Accel Y MSB     |                                      |
|   12   |      Accel Z LSB     |                 int16                |
|   13   |      Accel Z MSB     |                                      |
|   14   |      Gyro X LSB      |                 int16                |
|   15   |      Gyro X MSB      |                                      |
|   16   |      Gyro Y LSB      |                 int16                |
|   17   |      Gyro Y MSB      |                                      |
|   18   |      Gyro Z LSB      |                 int16                |
|   19   |      Gyro Z MSB      |                                      |
|   20   |   TOF Distance LSB   |                uint16                |
|   21   |   TOF Distance MSB   |                                      |
|   22   | Motor 1 Current XLSB |                 float                |
|   23   |  Motor 1 Current LSB |                                      |
|   24   |  Motor 1 Current MSB |                                      |
|   25   | Motor 1 Current XMSB |                                      |
|   26   | Motor 2 Current XLSB |                 float                |
|   27   |  Motor 2 Current LSB |                                      |
|   28   |  Motor 2 Current MSB |                                      |
|   29   | Motor 2 Current XMSB |                                      |
|   30   | Motor 3 Current XLSB |                 float                |
|   31   |  Motor 3 Current LSB |                                      |
|   32   |  Motor 3 Current MSB |                                      |
|   33   | Motor 3 Current XMSB |                                      |
|   34   | Motor 4 Current XLSB |                 float                |
|   35   |  Motor 4 Current LSB |                                      |
|   36   |  Motor 4 Current MSB |                                      |
|   37   | Motor 4 Current XMSB |                                      |
|   38   |       8-bit CRC      |                                      |

### CRC Generation

The CRC appended to the *Command* and *Command Response* frames is an 8-bit XOR CRC:

{% code lineNumbers="true" %}

```c
static uint8_t calculate_xor_crc(uint8 *data, int length)
{
    uint8_t crc = 0;
    for (int i = 0; i < length; i++)
    {
        crc ^= data[i];
    }
    return crc;
}// calculate_xor_crc
```

{% endcode %}

The CRC is computed across the payload data of the frame, **EXCLUDING** the preamble.

For example: Bytes 4 to 25 of the *Command* Frame and bytes 4 to 21 of the *Command Response* Frame.

### UART Interface Debug

[RealTerm overview from Sparkfun.](https://learn.sparkfun.com/tutorials/terminal-basics/real-term-windows)&#x20;

Can be downloaded [here.](https://flex-controller-se.mantismc.com/flex-controller-se-edition/broken-reference)

<figure><img src="https://content.gitbook.com/content/tpXGY8yRGIrUmuuiav4P/blobs/jx3s5CTBHSXqApYJZ5Yp/image.png" alt=""><figcaption><p>Configure UART connection via <em>Port</em> tab. Click <em>Change</em> to apply.</p></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/tpXGY8yRGIrUmuuiav4P/blobs/GeX27YODbOgw42iEe1Cj/image.png" alt=""><figcaption><p>Ensure <em>Hex</em> radio button is selected under <em>Display As</em>.</p></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/tpXGY8yRGIrUmuuiav4P/blobs/ptHS0O8m873GDsKqeUxn/Screenshot%202025-02-12%20114339.png" alt=""><figcaption><p>Paste hex data in either of drop-downs and click corresponding <em>Send Numbers</em> button.</p></figcaption></figure>

#### Set Motor 1 and Motor 2 Throttles (Command 0x0005) Example

* Motor 1 Throttle: 50 %&#x20;
* Motor 2 Throttle: -100%

{% code overflow="wrap" %}

```
0xEF 0xBE 0xAD 0xDE 0x05 0x00 0x32 0x9C 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xAB
```

{% endcode %}

#### Set All Motor Throttles (Command 0x0013) Example

Sets motors 1-4 to 100 % throttle.

{% code overflow="wrap" %}

```
0xEF 0xBE 0xAD 0xDE 0x13 0x00 0x64 0x64 0x64 0x64 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x13
```

{% endcode %}

#### Kill All Motors (Command 0x0007) Example

{% code overflow="wrap" %}

```
0xEF 0xBE 0xAD 0xDE 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x07
```

{% endcode %}

#### Set Motor 1 Throttle (Command 0x0003) Example

Sets motor 1 to 100 % throttle.

{% code overflow="wrap" %}

```
0xEF 0xBE 0xAD 0xDE 0x03 0x00 0x64 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x67
```

{% endcode %}

#### Set All Motor Throttles (Finite) (Command 0x0014) Example

* Motor 1: Unchanged
* Motor 2 : 100 % throttle for 5 seconds
* Motor 3: 50 % throttle, indefinately
* Motor 4: -25 % throttle for 10 seconds

{% code overflow="wrap" %}

```
0xEF 0xBE 0xAD 0xDE 0x14 0x00 0x00 0xFF 0xFF 0xFF 0xFF 0x64 0x88 0x13 0x00 0x00 0x32 0x00 0x00 0x00 0x00 0xE7 0x10 0x27 0x00 0x00 0x09
```

{% endcode %}

#### System Reset (Command 0x0015) Example

{% code overflow="wrap" %}

```
0xEF 0xBE 0xAD 0xDE 0x15 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x15
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://flex-controller-se.mantismc.com/flex-controller-se-edition/user-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
