> For the complete documentation index, see [llms.txt](https://guide.petoi.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://guide.petoi.com/product/quaddle-under-construction/control-and-program/controller.md).

# Controller

{Game controller operation demonstration video}

<figure><img src="/files/qmuUz5854vc1aJXckNwc" alt=""><figcaption></figcaption></figure>

## How to use

Quaddle is compatible with firmware-supported BM769, GamepadSpace-Q34B, and GamepadSpace-Q37 Bluetooth gamepads.

Before powering on the controller, please dial the mode switch on the back of the controller to the **D** position.

{Image of the mode switch on the back of the controller}

{% hint style="info" %}
The raw A/B and X/Y bits on the Q37 differ from those on the Q34B. The firmware automatically swaps them before mapping the controls to the physical labels printed on the gamepad. Users can therefore always follow the A, B, X, and Y labels shown on the gamepad itself.
{% endhint %}

### Connecting and Getting Started

{% stepper %}
{% step %}

### Power on

Press the **Home** button (![](/files/Mhtq49iMBW7UaCeJk3a5)) to turn on the controller and make it discoverable, then start the robot. At startup, the robot scans for a supported controller for approximately 1 second. When one is found, the robot automatically enters **GamepadClient** mode and connects. Simultaneously, the controller will emit vibration feedback.
{% endstep %}

{% step %}

### Finishing control

Return the left stick to the center to stop any movement it initiated and restore the standing posture. Click the **Pair** button at the top of the controller to power it off. If the controller disconnects unexpectedly, the robot program also automatically sends the "**kup**" safe-standing command.
{% endstep %}
{% endstepper %}

{% hint style="info" %}

### Note

**Wait for the gamepad to connect**

A previously saved gamepad is given priority when reconnecting. Once connected, the sticks and buttons can directly control the robot.

**No gamepad is found during startup**

Bluetooth enters mobile App Server mode. If the mobile app is not connected, briefly press the mainboard BOOT button to clear the old gamepad information, return to gamepad scanning, and pair the current gamepad.

**How to connect to the other gamepad**&#x20;

When the robot successfully connects to a controller for the first time, it saves the controller information. Upon the next power-up, it will connect only to the controller that was saved via Bluetooth and will not connect to other controllers. If you are sure you want to connect to another controller in this case, without connecting to the mobile app, first press the **Home** button on the new controller to power it on, and then briefly press the **Boot** button on the side of the robot. This will clear the previously saved controller Bluetooth information and then establish a Bluetooth connection with the new controller.
{% endhint %}

{% hint style="warning" %}
Holding the **Boot** button on the side of the robot for 2 seconds clears Wi-Fi configuration; it is not a gamepad-pairing operation.&#x20;

If the mobile app is connected, briefly pressing **Boot** on the side of the robot will **not** interrupt the app session (just clear the previously saved controller Bluetooth information) or switch to gamepad mode.
{% endhint %}

### Basic Functions

The image below shows all the function joysticks and buttons, and their functions after individual movement, long press, or click:

<figure><img src="/files/UxACZ9tfeWlubu3F9h68" alt=""><figcaption></figcaption></figure>

### Combination button functions

The image below shows the functions when you simultaneously press a button on the controller, move a joystick, or press a steering wheel button.

<figure><img src="/files/7dAe9ttLXQjW5wfKokLq" alt=""><figcaption></figcaption></figure>

<table><thead><tr><th width="123">Control</th><th>Operation</th><th>Function</th><th>Command/Notes</th></tr></thead><tbody><tr><td>Left stick</td><td>Move in any direction without holding a modifier button</td><td>Make the robot walk forward, backward, sideways, or diagonally</td><td>Uses the eight-direction mapping shown below.</td></tr><tr><td>Left stick</td><td>Release and return to center</td><td>Stop the movement initiated by the left stick and restore the standing posture</td><td>Sends <code>kup</code> once only if a left-stick movement was actually executed earlier. Center jitter immediately after connecting does not trigger repeated commands.</td></tr><tr><td>Left stick</td><td>Hold A/B/X/Y/ZR (labeled R2 on some gamepads), then move the stick</td><td>Execute an action or special gait assigned to that modifier</td><td>The current version no longer distinguishes between “half-push” and “full-push.” Once the stick leaves the center dead zone, the combination for that direction is executed.</td></tr><tr><td>Left stick</td><td>Hold R1, then move the stick</td><td>Execute one of four special Quaddle movements</td><td>Forward: biped gait; backward: rear scoot; left: front scoot; right: glide posture.</td></tr><tr><td>Right stick</td><td>Move left or right</td><td>Turn the head and make the body lean sideways; the eyes move with it when the TFT eye interface is active</td><td>Continuously sends <code>Jr x y</code> control data. The horizontal output is limited by the input layer.</td></tr><tr><td>Right stick</td><td>Move up or down</td><td>Coordinate the front and rear legs to change body pitch/posture; the eyes move with it when the TFT eye interface is active</td><td>Returning the stick to center restores the head and related leg joints to the neutral position for this control.</td></tr></tbody></table>

#### 2.1 Eight-Direction Left-Stick Movement Without a Modifier

#### 2.2 R1 + Left Stick

| Combination                   | Function                   | Action ID     |
| ----------------------------- | -------------------------- | ------------- |
| Hold R1 + left stick forward  | Enter biped movement       | `qBiped`      |
| Hold R1 + left stick backward | Enter rear-scoot movement  | `qScoot`      |
| Hold R1 + left stick left     | Enter front-scoot movement | `qFrontScoot` |
| Hold R1 + left stick right    | Enter the glide posture    | `glide`       |

### 3. Individual Button Functions

Each ABXY button has an approximately 200 ms combination-detection window. Its individual function is executed after waiting approximately 200 ms, or immediately if the button is released sooner. If the left stick or D-pad is operated during this window, the combination action takes priority, preventing accidental execution of the individual button action.

| Button/Operation                    | Function                                         | Instructions                                                                                                                                                                              | Command                                                                  |
| ----------------------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| A individually                      | Handstand action                                 | Briefly press A without operating the left stick or D-pad at the same time.                                                                                                               | `khds`                                                                   |
| B individually                      | Enter the servo-calibration posture              | Briefly press B. This posture is used when attaching the legs or fine-tuning joint zero offsets; avoid triggering it accidentally during normal play.                                     | `c`                                                                      |
| X individually                      | Rest and disable the servos                      | Briefly press X. The robot enters its rest posture and releases the servos.                                                                                                               | `d`                                                                      |
| Y individually                      | Wave/greeting action                             | Briefly press Y.                                                                                                                                                                          | `khi`                                                                    |
| L1                                  | Glide posture                                    | Press once to trigger. Release it before triggering it again.                                                                                                                             | `kglide`                                                                 |
| R2                                  | Toggle posture balancing                         | Each press toggles gyroscope posture balancing once. Release it before toggling again.                                                                                                    | `g`, supplemented with `F/f` according to the current sampling precision |
| ZL short press (less than 1 second) | Direct step-climbing sequence                    | Release within 1 second. The step-climbing sequence starts from its second stage.                                                                                                         | `kqStepHalf`                                                             |
| ZL long press (at least 1 second)   | Full step-climbing sequence                      | Hold for approximately 1 second to trigger the full sequence. Releasing after the long-press action fires does not also trigger the short-press action.                                   | `kqStep`                                                                 |
| MINUS                               | Replay the most recent combination action        | If an A/B/X/Y/ZR + left-stick or D-pad combination has been executed, the most recent combination is forced to execute again. Otherwise, the most recent temporary skill data is invoked. | Most recent `k...` combination; `T` if none is recorded                  |
| PLUS short press                    | Stop recording, start playback, or stop playback | Its behavior depends on the current macro state. See “Macro Recording and Playback.”                                                                                                      | Internal macro control                                                   |
| PLUS long press (at least 1 second) | Start a new macro recording                      | Clears the previous macro and starts recording subsequent valid gamepad commands and their timing intervals.                                                                              | Internal macro control                                                   |
| O (Q34B/Q37)                        | Enable/disable IMU data updates                  | Each press alternates between stopping and resuming updates. The first press stops updates.                                                                                               | Alternates between `gu` and `gU`                                         |
| T (Q34B/Q37)                        | Invoke the most recent temporary skill data      | Press once to execute. It only has an effect if temporary skill data was previously sent through the serial port or app.                                                                  | `T`                                                                      |
| HOME                                | No robot-control function is currently assigned  | The firmware recognizes this button, but the current control layer does not execute a command for it.                                                                                     | None                                                                     |

> The BM769 right trigger is reported as R2 in firmware events, while the internal button-bit enum calls it `ZR`. ZR and R2 therefore refer to the same right trigger in this document. In the current code, pressing it first toggles R2 gyroscope balancing once. Continuing to use the left stick or D-pad while holding it also executes the corresponding combination action. O and T are additional face buttons on the Q34B/Q37 and are generally not present on the BM769.

### 4. D-Pad Functions

#### 4.1 Using the D-Pad by Itself

| D-Pad Direction | Function                                        | Details                                                                                                                                           | Command |
| --------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| Up              | Enable the dual-light-sensor module             | Switches to light detection/light-following. Availability depends on whether the hardware is installed and enabled in the current firmware build. | `XL`    |
| Left            | Enable the dual infrared distance-sensor module | Switches to dual infrared distance detection. Availability depends on the hardware configuration.                                                 | `XD`    |
| Right           | Enable the gesture-sensor module                | Switches to Grove I2C gesture recognition. Availability depends on the hardware configuration.                                                    | `XG`    |
| Down            | Enable the second Grove serial-port module      | Switches to the Grove UART2 module.                                                                                                               | `XS`    |

#### 4.2 Modifier Button + D-Pad Action Matrix

Recommended operating order: hold the modifier button first, then tap a D-pad direction. These D-pad combinations replace the “modifier + left-stick half-push” actions used in earlier versions.

| Held Modifier | D-Pad Up                 | D-Pad Left            | D-Pad Right                | D-Pad Down                      |
| ------------- | ------------------------ | --------------------- | -------------------------- | ------------------------------- |
| Y             | Trot forward `trF`       | Trot left `trL`       | Trot right `trR`           | `bdF` action                    |
| X             | Crawl forward `crF`      | Crawl left `crL`      | Crawl right `crR`          | Drag-walk forward `dragWkF`     |
| B             | Front flip `ff`          | Roll over `flipRoll`  | Jump and slide `jumpSlide` | Backflip `bf`                   |
| A             | Tiptoe forward `tiptoeF` | Move left `sideL`     | Move right `sideR`         | March in place/forward `marchF` |
| ZR/R2         | Tripod forward `triCatF` | Tripod left `triCatL` | Tripod right `triCatR`     | Circle action `circle2L`        |

### 5. Modifier Button + Left-Stick Action Matrix

Hold the modifier button first, then move the left stick in a primary direction. The current version has only a center dead zone and an active directional zone; there is no need to deliberately push the stick halfway or fully.

| Held Modifier | Left Stick Forward       | Left Stick Left              | Left Stick Right              | Left Stick Backward         |
| ------------- | ------------------------ | ---------------------------- | ----------------------------- | --------------------------- |
| Y             | Trot forward `trF`       | Trot left `trL`              | Trot right `trR`              | Slide `slide`               |
| X             | Crawl forward `crF`      | Crawl left `crL`             | Crawl right `crR`             | Drag-walk forward `dragWkF` |
| B             | Front flip `ff`          | Roll over `flipRoll`         | Jump and slide `jumpSlide`    | Backflip `bf`               |
| A             | Tiptoe forward `tiptoeF` | Turning movement left `vt2L` | Turning movement right `vt2R` | Pace forward `paceF`        |
| ZR/R2         | Tripod forward `triCatF` | Tripod left `triCatL`        | Tripod right `triCatR`        | Combined dance `qDance`     |

> If multiple modifier buttons are held simultaneously, the firmware uses this fixed priority: A > B > Y > X > ZR/R2. R1 + left stick is a separate override and takes priority over the face-button combinations above. Using a ZR/R2 combination also triggers the button's individual gyroscope-balancing toggle once.

### 6. Macro Recording and Playback

| Stage              | Gamepad Operation                                                            | Result                                                                                                                                 |
| ------------------ | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Start recording    | Hold PLUS for at least 1 second                                              | Clears the old macro and starts recording. The serial output displays `[MACRO] recording`.                                             |
| Record actions     | Operate the sticks and buttons normally                                      | Records up to 48 robot commands that were actually accepted, including the interval between adjacent commands.                         |
| Stop and save      | Briefly press PLUS                                                           | Stops recording and retains the macro in runtime memory. The serial output displays the number of saved steps.                         |
| Start playback     | Briefly press PLUS again                                                     | Plays from the first step using the recorded timing intervals.                                                                         |
| Interrupt playback | Briefly press PLUS during playback, or execute another valid gamepad command | Stops the current playback immediately.                                                                                                |
| Clear the macro    | Hold PLUS again, disconnect/re-pair, or restart                              | A long press clears the old macro and starts a new recording. Resetting the connection state or restarting clears the in-memory macro. |

### 7. Operating Precautions

| Scenario                                                               | Recommendation or Firmware Behavior                                                                                                                                             |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Performing rolls, jumps, handstands, step climbing, or similar actions | Place the robot on an open, level, nonslip surface, away from table edges, people, and fragile objects.                                                                         |
| Using button combinations                                              | Hold A/B/X/Y/ZR/R1 before moving the left stick or tapping the D-pad. Moving the stick first may initiate normal walking. Pressing ZR/R2 also toggles gyroscope balancing once. |
| Rapidly changing the left-stick direction                              | The firmware discards older unexecuted stick-movement states and retains the latest direction, reducing control lag.                                                            |
| Gamepad disconnects or is turned off                                   | The firmware clears pending gamepad commands and macro state, then queues `kup` for a safe standing posture. New input is required after reconnecting.                          |
| During Wi-Fi provisioning                                              | If a gamepad is connected, the firmware may disconnect it temporarily to avoid BLE/Wi-Fi coexistence congestion. It scans and reconnects automatically after provisioning.      |
| A D-pad module shortcut has no effect                                  | Check that the corresponding sensor module is installed, its build option is enabled, and its interface is connected correctly.                                                 |
| An action name is unavailable on a particular robot model              | The mapping sends the same action ID, but actual availability depends on the current robot model and its skill table.                                                           |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://guide.petoi.com/product/quaddle-under-construction/control-and-program/controller.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
