PTENES
MODULE 3.1 · FOUNDATIONS

🍓 Raspberry Pi 5 and Linux

The ESP32 controls motors very well, but it can’t process camera images. In this module, you’ll set up a real Linux computer on the robot: prepare the Raspberry Pi 5 without a monitor, use the terminal, create a Python environment, turn on an LED through GPIO, and take care of its power and heat, the two most common reasons a Pi freezes inside a robot.

6
Topics
Intermediate
Level
Foundation
Type
Pi 5
Hardware
0%
0 of 0 topics read · Section 1 of 6

Detailed content

1

🧠 Why put a computer in the robot

A 640 × 480 camera image has more than 900,000 numbers (three colors per pixel), and dozens of images arrive every second. The ESP32 has enough memory to store only a few of these images and cannot run the vision libraries you’ll use. The Raspberry Pi 5 is a complete computer the size of a credit card: a quad-core processor, gigabytes of memory, a Linux system, Python, and OpenCV. It handles seeing and deciding; the ESP32 continues to handle the motors.

🌱 New here?

A operating system is the program that manages the computer and runs other programs (Windows, macOS, and Linux are examples). Linux is an open, free system; Raspberry Pi OS is the version of Linux made for the Pi. Real time means responding within a fixed deadline, like “correct the motor every 10 ms”: the microcontroller guarantees this; Linux does not, because it shares the processor among many programs.

camera 30 images/s Raspberry Pi 5 Linux + Python OpenCV, YOLO26 SEES and DECIDES ESP32 motors, sensors ACTS in real time “turn 20° left” the large image stays on the Pi; only the short command goes to the ESP32

How to read this map: the cyan arrow is wide because it carries a lot of data (the whole image); the purple arrow carries just a short sentence. This asymmetry is how almost every robot with vision is designed: the computer processes the image, and the microcontroller receives only the command. You’ll build this connection in module 3.5.

✓ What the Pi does well

  • ✓Process camera images with OpenCV and run detectors such as YOLO26.
  • ✓Store logs, serve a web page, connect to Wi-Fi and ROS 2.
  • ✓Run Python with large libraries installed from the command line.

✗ What the Pi does poorly

  • ✗Generate motor pulses with precise timing: Linux can be delayed by a few milliseconds.
  • ✗Read 5 V signals: the Pi’s pins use 3.3 V and can burn out.
  • ✗Be shut down by pulling the cable: the card can become corrupted.

Why learn this

Knowing what each board does well helps you avoid the two classic mistakes at this stage: trying to run vision on the microcontroller (it won’t fit) and connecting a motor directly to the Pi (it vibrates, lags, and can sometimes burn out a pin). The Pi 4 still works for this module’s basics; for camera use with an object detector, choose the Pi 5.

Key concepts

Single-board computer
A whole PC on one board
Linux
the Pi’s open system
Real time
guaranteed deadline: ESP32
Division of labor
Pi thinks, ESP32 acts
2

💾 Prepare the Pi 5 without a monitor

Inside the robot, the Pi won’t have a screen or keyboard. That’s why you prepare it in “headless” mode (without a head): write the system to the card with Raspberry Pi Imager, configuring the name, user, Wi-Fi, and SSH in advance, then access everything over the network from your computer. The system is Raspberry Pi OS 64-bit, currently based on Debian “Trixie.” For a robot, the Lite version (without a desktop environment) is lighter; if you’d rather see a desktop at first, use the full version.

🌱 New here?

SSH is a secure way to open another computer’s terminal over the network: you type on your laptop, and the commands run on the Pi. The hostname is the Pi’s name on the network (for example, robo); with it, you can find it at robo.local without needing to know its IP address.

1 Imagername, userWi-Fi, SSH 2 CardmicroSD32 GB or more 3 Pi powers on27 W power supplyjoins Wi-Fi 4 SSHssh you@robo.local everything configured BEFORE the first boot: no monitor needed the first boot takes a little longer: the system expands the card

How to read this map: the three purple panels happen with the card and the board; the cyan panel is your computer communicating with the Pi. If step 4 fails, the problem is almost always in step 1 (the Wi-Fi password was typed incorrectly or SSH is turned off).

Step by step

1

Install Imager

Download Raspberry Pi Imager from raspberrypi.com/software (Windows, macOS, or Linux) and insert the microSD card into your computer’s card reader.

2

Choose the board, system, and card

Device: Raspberry Pi 5. System: Raspberry Pi OS (64-bit), or the Lite version under “Raspberry Pi OS (other).” Storage: your card. Double-check so you don’t erase the wrong drive.

3

Customize before writing

On the customization screen, set the hostname robo, a username and password of your choice, the Wi-Fi details (name and password, country BR), and enable SSH. Write the image and wait for verification to finish.

4

Power on and connect

Put the card in the Pi, connect the official 27 W power supply, and wait until the green LED is no longer flashing rapidly. In your computer’s terminal (on Windows, PowerShell already includes SSH), run the block below.

Goal: connect to the Pi over the network and update the system. Replace <seu_usuario> with the user you created in Imager.

on your computer → then on the Pi
# 1) On YOUR computer: connect to the Pi (the first time, answer "yes")
ssh <seu_usuario>@robo.local

# 2) Once inside the Pi: update the package list and system
sudo apt update
sudo apt full-upgrade -y

# 3) Check what is running
cat /etc/os-release | grep PRETTY_NAME   # should mention Debian and "trixie"
uname -m                                # aarch64 = 64-bit system
hostname -I                             # the Pi's IP address on the network

# 4) Restart to apply kernel updates
sudo reboot

How to check

  • ✓The prompt changes to something like <seu_usuario>@robo:~ $: you’re inside the Pi.
  • ✓uname -m returns aarch64 and PRETTY_NAME mentions trixie.
  • ✗“Could not resolve hostname”? Use the IP instead of robo.local (the router shows connected devices), or check that your computer is on the same network.

Why learn this

A Pi set up the right way connects to the robot and appears on the network automatically. Configuring everything in Imager saves you from needing a monitor and keyboard, and from trying to edit configuration files by hand—which is where many people get stuck at first.

Key concepts

Headless
without a screen, over the network
Pi Imager
flashes and customizes
SSH
secure remote terminal
apt
installs and updates
3

⌨️ Essential Linux terminal

On the robot, you’ll communicate with the Pi almost entirely through the terminal: a text line where each command is a short word followed by options. You don’t need to memorize dozens of them. With about fifteen, you can navigate folders, edit code, install packages, and figure out why something stopped working.

🌱 New here?

In Linux, everything is arranged in a tree of folders that starts at / (the root). Your personal folder is /home/<seu_usuario>, shortened to ~. sudo (“run as administrator”) is needed to change the system, such as when installing programs. Use it only when the command calls for it.

/ home/you etc/settings dev/ports, camera, serial ~/robo/your projects ~/robo-venv/isolated Python environment ~/robo/led.py the tilde (~) is a shortcut for /home/<seu_usuario>

How to read this map: on the left, the root and three system folders; on the right, what you’ll create yourself inside your personal folder. Keep your files in ~: that way, you won’t accidentally touch anything in the system.

CommandWhat it doesExample
pwd · ls -l · cdwhere am I · list · enter a foldercd ~/robo
mkdir · cp · mv · rmcreate a folder · copy · move/rename · deletemkdir -p ~/robo
nano filesimple text editor (Ctrl+O saves, Ctrl+X exits)nano led.py
cat · tail -fshow a file · follow a log livetail -f log.txt
htop · df -h · free -hprocesses and CPU · card space · memorydf -h
Ctrl+Cstop the program that’s runningstop the robot from the terminal
scpcopy a file between your computer and the Piscp foto.jpg you@robo.local:~

Goal: create the course folder, write a file, check available space, and safely shut down the Pi.

Pi terminal
mkdir -p ~/robo && cd ~/robo        # create the folder (if it doesn't exist) and enter it
pwd                                 # shows /home/<seu_usuario>/robo
echo "robo pronto" > notas.txt       # creates a file with one line
cat notas.txt                       # shows the contents
ls -l                               # lists files with size and date
df -h /                             # free space on the card
free -h                             # total and used memory

# Shut down safely (wait for the green LED to stop blinking before unplugging the power)
sudo shutdown -h now

How to check

  • ✓cat shows “robo pronto” and ls -l lists notas.txt.
  • ✓df -h shows several GB free (if usage is above 90%, the card is too small).
  • ✓After shutdown, the SSH connection drops and the green LED stops blinking.

💡 Edit on your computer

If nano is getting in your way, open the Pi’s folder right in your editor: VS Code with the “Remote - SSH” extension edits the Pi’s files as if they were local. The terminal is still where you run and stop the robot.

Why learn this

Everything else in the learning path (camera, YOLO26, communication with the ESP32) and all of Learning Path 4 (ROS 2) happen in the terminal. Once you know these commands, you can handle “the card is full,” “the program froze,” and “where did I save that file?” on your own.

Key concepts

Home folder ~
where your files are stored
sudo
only for changing the system
Ctrl+C
for the program
shutdown
shut down without corrupting data
4

🐍 Python with a virtual environment

If you try pip install directly on Raspberry Pi OS, you’ll see the error externally-managed-environment. This isn’t a defect: the system protects the Python it uses. The right solution is to create a virtual environment (venv) for the robot. One important detail on the Pi: create the venv with --system-site-packages, so it can see libraries installed by the system, such as picamera2 (camera) and gpiozero (pins).

🌱 New here?

A A package is a ready-to-use Python library (OpenCV, Ultralytics). pip is Python’s package installer; apt is the system installer. A venv virtual environment is a folder with its own Python: what you install there won’t disrupt the system, and if something goes wrong, you can delete the folder and create it again.

~/robo-venv (your environment) pip install: opencv, ultralytics, pyserial safe to delete and recreate System Python apt: picamera2, gpiozero (already included in Raspberry Pi OS) --system-site-packages

How to read this map: the venv (purple) sits on top of System Python (cyan). The arrow shows that with the --system-site-packagesoption, the venv “looks down” and finds the camera and pins; without it, import picamera2 fails inside the venv.

Goal: create the course venv, activate it, install a package, and confirm that it can see the system libraries.

Pi terminal
# Create the environment (just once)
python3 -m venv --system-site-packages ~/robo-venv

# Activate (each time you open a new terminal)
source ~/robo-venv/bin/activate      # the prompt gets "(robo-venv)" at the beginning

# Install packages INSIDE the venv (without sudo)
pip install --upgrade pip
pip install numpy

# Test: Python version and visible system libraries
python -c "import sys; print(sys.prefix)"
python -c "import gpiozero, picamera2; print('gpiozero e picamera2 OK')"

# Exit the venv whenever you want
deactivate

How to check

  • ✓sys.prefix terminal /home/<seu_usuario>/robo-venv: the active Python is the one in the venv.
  • ✓You’ll see “gpiozero and picamera2 OK”.
  • ✗“No module named picamera2”? The venv was created without --system-site-packages, or you’re using the Lite version without the library: run sudo apt install -y python3-picamera2 and recreate the venv.

✓ Do

  • ✓Use one venv per large project; one is enough for the course.
  • ✓Keep track of the packages with pip freeze > requirements.txt.
  • ✓Run scripts with the virtual environment’s Python activated.

✗ Don't

  • ✗sudo pip install: mixes packages with the system ones.
  • ✗Use --break-system-packages to “fix” the error.
  • ✗Install picamera2 with pip: on the Pi, it comes from apt.

Why learn this

OpenCV, Ultralytics, and pyserial, which you’ll use in the next modules, all go in this virtual environment. Doing it right now avoids the most common vision problem on the Pi: “the camera works in the terminal, but my script can’t find the library.”

Key concepts

venv
Python isolated in a folder
pip vs. apt
Python vs. system
system-site-packages
can access picamera2
requirements.txt
list for recreating
5

📍 GPIO on the Pi (gpiozero) and 3.3 V precautions

The Pi 5 has a double row of 40 pins, like the ESP32 has its own. Some provide power (3.3 V, 5 V, and GND); most are GPIO, pins that your program turns on, turns off, or reads. In Python, the library gpiozero turns these into simple objects: LED(17), Button(27). On the robot, the Pi’s GPIO is for status LEDs, a stop button, and serial communication with the ESP32; the ESP32 handles the motors.

🌱 New here?

The pins have two numbers. O physical counts the position in the row (1 to 40). BCM (or “GPIO”) is the logical name used by the chip, and it’s what gpiozero expects: physical pin 11 is GPIO17. If you’re unsure, run pinout in the Pi’s terminal: it shows the complete map.

1 · 3,3 V2 · 5 V 4 · 5 V6 · GND 9 · GND 11 · GPIO17 → LED 330 Ω + LED → GND 13 · GPIO27 → button (next pin down) red = power: never connect 5 V to a GPIO

How to read this map: the rectangle marks the start of the connector, viewed from above, with pin 1 in the corner (the square pad on the board). Red is power, gray is GND, and purple is the GPIO you’ll use. The button goes to pin 13, just below pin 11, and to GND on pin 14 next to it.

Goal: make a status LED blink and keep it on while the button is pressed. Connect: GPIO17 (pin 11) → 330 Ω resistor → long leg of the LED; short leg → GND (pin 9). Connect the button between GPIO27 (pin 13) and GND (pin 14). With the virtual environment activated, save as ~/robo/led.py.

~/robo/led.py
# Status LED and button on Raspberry Pi 5 with gpiozero
# Run with: python ~/robo/led.py   (Ctrl+C to exit)
from gpiozero import LED, Button
from signal import pause

led = LED(17)                       # BCM number: GPIO17 = physical pin 11
botao = Button(27, bounce_time=0.05) # GPIO27 = pin 13; internal pull-up enabled

def apertou():
    led.on()
    print("button pressed: LED on")

def soltou():
    led.blink(on_time=0.2, off_time=0.8)  # starts blinking in the background again
    print("button released: LED blinking")

botao.when_pressed = apertou
botao.when_released = soltou
soltou()                            # initial state: blinking
print("Ready. Press the button. Ctrl+C to exit.")
pause()                             # keeps the program running and waiting for events

How to check

  • ✓The LED blinks quickly (0.2 s on, 0.8 s off) when it starts.
  • ✓While you hold the button, the LED stays on and the terminal shows “button pressed.”
  • ✗Nothing lights up? Check that you used the BCM number (17), not the physical number (11), and that the LED isn’t reversed.

✓ Safe for GPIO

  • ✓Signals up to 3.3 V; for a 5 V sensor, use a voltage divider or level shifter.
  • ✓Always use a resistor with an LED; only a few milliamps per pin.
  • ✓Connect wires with the Pi turned off.

✗ Damages the Pi

  • ✗Arduino’s 5 V TX connected directly to the Pi’s RX.
  • ✗A motor, relay, or servo powered from a GPIO.
  • ✗Touching the 5 V pin to a neighboring pin while the Pi is on.

Why learn this

The 3.3 V pin requires the same care as on the ESP32, but a mistake costs more: a burned-out Pi 5 costs much more than an ESP32. And gpiozero, with events like when_pressed, is the simplest way to add a physical stop button to the robot, which you’ll use in project 3.6.

Key concepts

BCM vs. physical
GPIO17 = pin 11
gpiozero
LED, Button, events
pinout
map in the terminal
3.3 V maximum
5 V damages the pin
6

🔋 Power and heat inside the Pi 5 in the robot

On the workbench, the Pi 5 uses the official 27 W power supply (5 V, 5 A, USB-C). With a weaker power supply, it still works, but limits current to the USB ports and may restart when the camera and AI draw power at the same time. In the robot, there’s no wall outlet: the battery goes through a buck regulator that provides stable 5 V with enough current. And when running vision, the processor heats up: without the active cooler, it slows itself down to protect itself, and your detector gets slower without warning.

🌱 New here?

Undervoltage is when the voltage briefly drops below what’s needed (for example, when a motor starts); the Pi records this and may restart. Throttling is when the Pi itself slows down the processor because of heat or weak power. A buck regulator converts a higher voltage (from the battery) to a lower one (5 V) with little heat loss.

battery2S or 3S 5 V buck5 A or more Pi 5+ active cooler drivermotors ESP32Common GND separate branches: the motor’s surge won’t cause the Pi to lose power

How to read this map: power (amber) comes from the battery and splits before reaching any board. The upper branch, with the buck converter highlighted, keeps the Pi stable. The gray dashed line reminds you that the GND connections on all boards must be connected to each other.

Goal: monitor temperature and power alerts while the robot is running. Save as ~/robo/saude.py and leave it running in a second terminal during vision tests.

~/robo/saude.py
# Pi 5 health monitor: temperature and power/thermal alerts
import subprocess, time

def temperatura():
    with open("/sys/class/thermal/thermal_zone0/temp") as f:
        return int(f.read()) / 1000          # reported in thousandths of a degree

def alertas():
    saida = subprocess.run(["vcgencmd", "get_throttled"],
                           capture_output=True, text=True).stdout
    valor = int(saida.strip().split("=")[1], 16)
    msgs = []
    if valor & 0x1:     msgs.append("UNDERVOLTAGE NOW")
    if valor & 0x4:     msgs.append("throttled NOW")
    if valor & 0x10000: msgs.append("undervoltage occurred since boot")
    if valor & 0x40000: msgs.append("throttling occurred since boot")
    return msgs or ["power OK"]

while True:
    t = temperatura()
    aviso = "  HOT: check the cooler" if t > 75 else ""
    print(f"{time.strftime('%H:%M:%S')}  {t:.1f} °C  {', '.join(alertas())}{aviso}")
    time.sleep(2)

How to check

  • ✓Every 2 s, a line appears, such as “14:02:10 48.3 °C power OK.”
  • ✓With the cooler, the temperature under vision workloads stays well below 80 °C.
  • ✗“undervoltage occurred”? Replace the power supply, USB-C cable, or buck converter with one that provides more current before continuing.

✓ Do

  • ✓Official active cooler installed and ventilation in the chassis.
  • ✓Buck converter dedicated to the Pi, with enough current headroom and short, thick wires.
  • ✓Shut down with sudo shutdown -h now before disconnecting the battery.

✗ Don't

  • ✗Any power bank: many can’t sustain 5 A, so the Pi restarts.
  • ✗Pi and motors on the same regulator.
  • ✗Pi enclosed in a box without airflow, in the sun.

💡 Lithium battery

If you use LiPo or 18650 cells, use a pack with a BMS (protection board), always charge it under supervision and in a fireproof bag, and never puncture or crush a cell. The rules from module 1.5 apply twice as strongly here, because the Pi draws much more current than the ESP32.

Why learn this

Most vision “bugs” in robots start here: the Pi restarts when the robot speeds up, or the detector drops to half speed after a few minutes. Measuring temperature and undervoltage helps distinguish a power problem from a code problem and saves you from looking for the error in the wrong place.

Key concepts

27 W power supply
5 V and 5 A on the bench
5 V buck converter
battery → Pi
get_throttled
0x0 = all clear
Active cooler
prevents performance loss

✅ Module summary

✓
Pi thinks, ESP32 acts: heavy image processing stays on the computer; only the command goes to the microcontroller.
✓
Headless from the Imager: Raspberry Pi OS 64-bit (Trixie), Wi-Fi and SSH configured before the first boot.
✓
Terminal and venv: about fifteen commands and an environment with --system-site-packages solve almost everything.
✓
3.3 V GPIO: gpiozero with BCM numbering; no 5 V or motors on the pins.
✓
Measured power and temperature: dedicated buck converter, active cooler and get_throttled at 0x0.

To go further

Next module

3.2 · Camera and OpenCV: connect the Camera Module 3, find an object by color and stream the video to your browser.