# Hardware Setup

**Cyclops requires a drive** to store maps and recordings, a **camera**, and a **connection to the flight controller**. We will walk through each of those and ensure they are properly setup.

For our own systems we store everything on a single boot micro SD card. This helps save on system cost. The connection to the flight controller is a serial connection that uses mavlink to communicate. Minimizing the length of the serial cable can help eliminate noise and mavlink connection issues.

## Setting up an NVME as the storage device

You only need to follow these directions if you plan on using an NVME with cyclops. If you are satisfied the read/write speeds of the SD card, you can skip this step.

{% file src="/files/A9imv78mOM9IUeRuPAaM" %}

This [tutorial on mounting a drive on linux](https://www.wikihow.com/Linux-How-to-Mount-Drive#:~:text=To%20mount%20a%20drive%20on,to%20mount%20and%20unmount%20drives.) will work with a PCIE NVME drive or a USB SSD.\
**OR**\
you can run the above script to setup a USB SSD drive.

You may pick any name for the drive. I am using a Samsung T9 SSD, so I call it `/t9`

```bash
pi@pi5:~$ sudo Downloads/setup-storage-mount.sh /dev/sda2 /mnt/t9
Device: /dev/sda2
UUID: C443-4727
Filesystem: exfat
Mount point: /mnt/t9

Creating systemd mount unit: mnt-t9.mount
Created symlink /etc/systemd/system/multi-user.target.wants/mnt-t9.mount → /etc/systemd/system
/mnt-t9.mount.
Creating udev rule for auto-mount on plug: /etc/udev/rules.d/99-auto-mount-C443-4727.rules
Mounting...

✓ Successfully mounted /dev/sda2 to /mnt/t9
```

Verify that the drive is mounted with:

```bash
lsblk
```

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

## Setup UART Serial

Your device needs to communicate with the flight controller using a serial connection. There are many ways to set this up. You can find docs on the manufacturer's website for your specific hardware setup.

In the case of the nanopi, you can use a serial hat. In the case of the raspi 5, you can look at their provided [docs](https://www.raspberrypi.com/documentation/computers/configuration.html#configure-uarts) on configuring this.

Once you've set up the serial connection, verify you have the serial connections:

```
pi@pi5:~$ ls /dev/tty*
```

### Raspberry Pi 5 Serial Setup (Ubuntu 24)

#### Setup script

To save time, if using a new rpi 5 we recommend using this setup script after flashing the boot sd card. The script will apply some default configurations so you don't need to manually setup the serial port.

On first boot, cloud-init will:

* Set hostname: clop-$DEVICE\_NUM
* Create user 'pi' (password: pi, sudo)
* Enable SSH with password auth
* Set static IP: 192.168.218.100
* Create /home/pi/recordings
* Disable EEE on eth0 (Pi 5 link-flap fix)
* Setup pi serial port
* Reboot to apply boot config changes

{% file src="/files/oZeH01vOyNBLVrz2034s" %}

#### Manual setup of MAVLink Serial

UART0 is used for the MAVLink serial connection between the Pi 5 and the flight controller at 921600 baud.

**Pinout:**

| Function | GPIO | Header Pin | Connects To |
| -------- | ---- | ---------- | ----------- |
| TX       | 14   | Pin 8      | FC RX       |
| RX       | 15   | Pin 10     | FC TX       |
| GND      | —    | Any GND    | FC GND      |

Both the Pi 5 and flight controller operate at 3.3V logic. No level shifting required.

**Background — Pi 5 UART naming:**

On Pi 5, GPIO 14/15 are driven by a PL011 UART in the RP1 southbridge, which shows up at MMIO `0x1f00030000`. The device node it enumerates to depends on the OS image:

* **Ubuntu 24.04 Desktop (Pi 5):** `/dev/ttyAMA0` (with a `/dev/serial0` symlink in some releases)
* **Ubuntu 24.04 Server (recommended for 2GB Pi 5):** `/dev/ttyAMA0`, no `/dev/serial0` symlink
* A second node `/dev/ttyAMA10` (at `0x107d001000`) will also appear — this is an internal SoC UART, **not** GPIO 14/15. Ignore it.

To confirm which node is GPIO 14/15, check `dmesg`:

bash

```bash
sudo dmesg | grep -iE 'pl011|107d001|1f00030'
```

The line containing `1f00030000.serial` identifies the GPIO header UART (typically `ttyAMA0`).

**Setup:**

1. Disable the serial console if active (Desktop images sometimes enable this; Server typically does not):

bash

```bash
    sudo systemctl disable serial-getty@ttyAMA0.service
    sudo systemctl stop serial-getty@ttyAMA0.service
```

2. Remove `console=ttyAMA0,115200` or `console=serial0,115200` from `/boot/firmware/cmdline.txt` if present:

bash

```bash
    sudo nano /boot/firmware/cmdline.txt
```

{% code overflow="wrap" %}

```
The file should be a single line. Remove only the `console=ttyAMA0,...` or `console=serial0,...` token (leave everything else intact). Save with `Ctrl+O`, Enter, `Ctrl+X`.
```

{% endcode %}

3\. Edit `/boot/firmware/config.txt`. Under the `[all]` section, ensure both of these are set:

```bash
    sudo nano /boot/firmware/config.txt
```

```
    enable_uart=1
    dtoverlay=uart0-pi5
```

{% code overflow="wrap" %}

```
Note: on Ubuntu for Pi 5, `enable_uart=1` alone is **not** sufficient — the `uart0-pi5` overlay is required to instantiate the PL011 on GPIO 14/15.
```

{% endcode %}

4\. Reboot. UART is available at `/dev/ttyAMA0`.

**Verification:**

Connect the Pi to the flight controller and ensure the FC's corresponding serial port is configured to output MAVLink2 at 921600 baud. Then:

bash

```bash
sudo stty -F /dev/ttyAMA0 921600 raw -echo
sudo cat /dev/ttyAMA0 | head -c 200 | xxd
```

You should see binary output with recurring `fd` bytes (MAVLink2 start byte) followed by a length byte and incrementing sequence numbers. Example:

```
00000000: fd1c 0000 d901 0121 0000 4704 1200 5d2c  .......!..G...],
00000010: 0000 18ae 0000 6a04 0000 6904 0000 0000  ......j...i.....
```

This confirms MAVLink data is flowing and the serial link is working. `Ctrl+C` to stop.

**Troubleshooting:**

* `cat: /dev/ttyAMA0: No such file or directory` → `uart0-pi5` overlay not loaded. Verify `config.txt` and reboot.
* Only `/dev/ttyAMA10` exists → same cause; the GPIO UART hasn't been instantiated.
* No `0x1f00030000.serial` line in `dmesg` → overlay didn't apply; check for typos in `config.txt`.
* Data flowing but garbled even at correct baud → check TX/RX aren't swapped, and confirm FC is set to MAVLink2 (not MAVLink1, which starts with `fe`).

***

### USB Port Full Power (GPIO Header Power Input)

When powering the Pi 5 via the GPIO header (pins 2/4 for 5V, bypassing the USB-C PMIC), USB ports default to a 600mA total current budget. This must be overridden to provide full power to USB peripherals.

**Edit `/boot/firmware/config.txt`:**

bash

```bash
sudo nano /boot/firmware/config.txt
```

Add this line under the `[all]` section:

```
usb_max_current_enable=1
```

Save with `Ctrl+O`, Enter, `Ctrl+X`. Reboot to apply:

bash

```bash
sudo reboot
```

This raises the total USB port current budget to 1.6A.

#### Recap

We have now set up all of our hardware.&#x20;

Your addresses may vary, but we have:

```
Recording drive at /mnt/t9
Serial connections at /dev/ttySC0 and /dev/ttySC1
Video device at /dev/video0
```

Great job!


---

# 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://docs.theseus.us/cyclops/cyclops-computer/pi-5-walkthrough/hardware-setup.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.
