Maker.io main logo

XRP Meets Raspberry Pi: Simplifying Robot Control with Flask Server

2024-11-19 | By Aswin S Babu

License: Apache License, Version 2.0 Robot Accessories Robot Kits Raspberry Pi

In the first part of this series, we dove into programming the XRP robot with Thonny IDE, introducing you to this beginner-friendly robotic platform called XRP, powered by the Raspberry Pi Pico W. While the Pico W is perfect for foundational tasks with its Wi-Fi, UART, and USB capabilities, certain projects demand a bit more muscle—think AI-powered functions or advanced computer vision. This is where augmenting the XRP with a Raspberry Pi SBC becomes relevant.

Raspberry Pi 4 is one of the many single-board computers from the Raspberry Pi Foundation, developed in collaboration with Broadcom. Originally designed to teach basic computer science in schools and developing nations, it delivers significantly more processing power than the Pico W. It features a quad-core Cortex-A72 processor, up to 8GB of RAM, Ethernet, Bluetooth, USB ports, and powerful GPIOs.

Let’s explore controlling XRP through a Flask web server running on a Raspberry Pi in detail. This setup not only enables remote control of the XRP robot but also opens the door to numerous possibilities by combining the computing power of Raspberry Pi with XRP’s simplicity—paving the way for future robotics and automation projects with ease.

XRP robot

XRP robot             

Raspberry Pi SoC

Raspberry Pi 4   

There are several ways of connecting a Raspberry Pi to an XRP such as WiFi, Bluetooth, USB, UART etc. In this guide, we will be using USB connectivity as it is one of the simplest connections. You only require a Raspberry Pi 4 running Raspberry Pi OS and a micro-USB cable for this.

Step 1: Assembling the XRP robot

Assembling an XRP is straightforward, it is as simple as snapping some Lego bricks in place. Please go through the Experiential Robotics Platform (XRP) Kit Assembly Instructions for more details.

Step 2: Programming XRP through Thonny IDE

Once assembled, make sure that everything is working fine by programming your XRP robot. If you are not sure on how to program the robot, please follow the following link to see how you can program your first XRP robot using Thonny IDE. Run one of the default programs that comes along with the XRP robot to verify the assembly.

Step 3: Setting up the Raspberry Pi

Once you’ve confirmed that the XRP is functioning correctly, we can set up the Raspberry Pi. To begin, ensure you have a Raspberry Pi with Raspberry Pi OS already installed. If not, you can use this tutorial to guide you through the installation process using the Raspberry Pi Imager.

Next, log in to the Raspberry Pi. You can do this either by using SSH/VNC or by connecting peripherals like a monitor, keyboard, and mouse. In this project, we recommend using the Graphical User Interface (GUI) since we will be programming the XRP through the Raspberry Pi, making the GUI environment more convenient. So, try to use either the VNC method using a tool like MobaXterm or by connecting all the peripherals like keyboard, mouse and a monitor.

Step 3.1 Setting up Flask on RPi

Flask is a lightweight web framework for Python that simplifies building web applications. Here we are using Flask to create a Python-based web page that can control the XRP. Follow these steps on your Raspberry Pi to install the Flask library. Make sure the device is connected to the internet:

Command terminal window on the Raspberry Pi

Command terminal window on the Raspberry Pi displaying command output.

Run the following commands on the RPi terminal to install Flask library

Copy Code
sudo apt update
sudo apt install python3-pip
pip3 install flask

Step 3.2 Install PySerial library

PySerial is a library which provides support for serial connections ("RS-232") over a variety of different devices. Here, the PySerial library allows the Raspberry Pi to communicate with the XRP over a serial connection. Follow these steps to install it.

Run the following command on the RPi terminal to install Py serial library

Copy Code
pip3 install pyserial

Command terminal window on the Raspberry Pi 

Command terminal window on the Raspberry Pi displaying command output.

Step 4: Programming Raspberry Pi

Using one of the programming IDEs (e.g Geany) in the Raspberry Pi to create a Python file. It could be any name but let's call ours FlaskServer.py. Copy the following code to the file and save it.

Raspberry Pi Geany IDE

Raspberry Pi Geany IDE (Image Source: Geany).

Code to copy to RPi

This script sets up a Flask web server on the Raspberry Pi to control the XRP robot via joystick-like buttons in the browser.

Copy Code
# Filename: FlaskServer.py
# Author: Aswin S Babu
# Description: This script sets up a Flask web server on the Raspberry Pi to control the XRP robot via joystick-like buttons in the browser.
# The server communicates with the Pico via USB serial to send movement commands such as Forward, Backward, Left, Right, and Stop.

from flask import Flask, render_template_string, request  # Import necessary modules from Flask
import serial  # Import the serial module for USB communication

# Attempt to set up the serial connection to Pico
try:
    # Open a serial connection to the Pico on port "/dev/ttyACM1" with baud rate 115200
    # Adjust the port if Pico is connected to a different one (e.g., "/dev/ttyACM0")
    s = serial.Serial("/dev/ttyACM1", 115200)
    print("Connected to Pico via USB Serial.")
except serial.SerialException as e:
    # If there is an error opening the serial port, catch the exception and print the error message
    print(f"Failed to connect to Pico: {e}")
    print("Verify serial port number using ls /dev/ttyACM*")
    s = None  # Set the serial object to None to indicate the connection failed

# Initialize the Flask application
app = Flask(__name__)

# HTML template for the joystick interface
# This template includes buttons for controlling the Pico: Forward, Backward, Left, Right, and Stop
HTML_TEMPLATE = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Joystick Control</title>
    <style>
        /* Styling for the joystick buttons */
        .button {
            padding: 20px 40px; /* Button size */
            font-size: 24px; /* Text size */
            margin: 5px; /* Space around buttons */
            cursor: pointer; /* Pointer cursor on hover */
            background-color: #4CAF50; /* Green background color */
            color: white; /* White text */
            border: none; /* No border */
            border-radius: 5px; /* Rounded corners */
        }
        .button-container {
            display: grid; /* Use CSS Grid layout for joystick arrangement */
            grid-template-columns: repeat(3, 1fr); /* 3 columns equally spaced */
            gap: 10px; /* Space between buttons */
            justify-items: center; /* Center the buttons horizontally */
            align-items: center; /* Center the buttons vertically */
        }
        .spacer {
            visibility: hidden; /* Invisible spacers to maintain layout */
        }
    </style>
</head>
<body>
    <h1>Joystick Control</h1>
    <!-- Form containing the joystick control buttons arranged in a cross pattern -->
    <form method="POST">
        <div class="button-container">
            <!-- Spacer to align Forward button in the center -->
            <div class="spacer"></div>
            <!-- Forward button placed directly above the Stop button -->
            <button class="button" name="command" value="F">Forward</button>
            <div class="spacer"></div> <!-- Spacer for alignment -->

            <!-- Left button placed to the left of the Stop button -->
            <button class="button" name="command" value="L">Left</button>
            <!-- Stop button in the center -->
            <button class="button" name="command" value="S">Stop</button>
            <!-- Right button placed to the right of the Stop button -->
            <button class="button" name="command" value="R">Right</button>

            <!-- Spacer to align Backward button in the center -->
            <div class="spacer"></div>
            <!-- Backward button placed directly below the Stop button -->
            <button class="button" name="command" value="B">Backward</button>
            <div class="spacer"></div> <!-- Spacer for alignment -->
        </div>
    </form>
</body>
</html>
"""

@app.route('/', methods=['GET', 'POST'])  # Define route for the root URL ('/')
def index():
    """Render the joystick control page and handle button presses."""
    if request.method == 'POST':  # Check if the request method is POST (form submitted)
        command = request.form.get('command')  # Get the command value from the button pressed
        if command:  # If a command is received, send it to the Pico
            send_usb_command(command)  # Call the function to send the command over USB
    return render_template_string(HTML_TEMPLATE)  # Render the HTML template

def send_usb_command(command):
    """Send the corresponding command to the Pico via USB Serial."""
    if not s:  # Check if the serial connection is established
        print("Serial connection not established.")  # Print error if not connected
        return  # Exit the function if no connection
    try:
        # Send the command to the Pico by writing it to the serial port
        # Append a newline character '\n' to the command for proper parsing on the Pico side
        s.write((command + '\n').encode('utf-8'))  # Encode the command as bytes and send
        print(f"Sent command: {command}")  # Print the command sent for debugging
    except Exception as e:  # Catch any exceptions during serial communication
        print(f"Error sending command: {e}")  # Print the error message

if __name__ == '__main__':
    # Start the Flask web server on all available IPs (host='0.0.0.0'), on port 5000
    try:
        app.run(host='0.0.0.0', port=5000)  # Start the Flask server
    except KeyboardInterrupt:
        print("Server stopped by user.")  # Print message if server is stopped with Ctrl+C
    finally:
        if s:  # Check if the serial connection is open
            s.close()  # Close the serial connection to clean up resources
            print("Serial connection closed.")  # Confirm that the connection has been closed

Step 4.1 Find out which port the XRP is connected to on the RPi

In the above code, at line number 13, we are defining the serial communication port (s = serial.Serial("/dev/ttyACM1", 115200)). Verify that you see the same port name by executing the command ls /dev/ttyACM*. Update the code accordingly if the output is different.

Terminal window on the RPi showing serial ports

Command terminal window on the Raspberry Pi displaying serial communication port.

Step 5: Programming XRP

Using Thonny, create a file named xrp_motion_cntrl.py (refer to Step 2) and copy the following content to the file. Follow this link to see how you can program the XRP using Thonny IDE.

Code to be copied to XRP

Github Code Link

Step 6: Controlling XRP through Raspberry Pi

First, run the code on the XRP side using Thonny IDE and then run the program on the Raspberry Pi side. Refer to Step 2 in case you have any confusion. After running the code, you should see the output as follows.

Thonny IDE 

Thonny IDE

After this, run the RPi side code using Geany. Now you should be able to access the local web server using your browser. Open your browser and type <Raspberry Pi IP>:5000. Example 192.168.137.208:5000. In case you are not aware of the IP of the RPi, you can find out the IP by using the hostname -I command.

  Web joystick interface

Web joystick interface

Now if you press the joystick buttons on the webpage, you can observe the corresponding movements of the XRP. Feel free to tinker with the code and have fun. Happy coding!

制造商零件编号 KIT-22296
XRP ROBOTICS PLATFORM KIT BETA (
SparkFun Electronics
制造商零件编号 ROB-22727
XRP CONTROLLER
SparkFun Electronics
制造商零件编号 SC0400ES
SBC 1.5GHZ 4 CORE 2GB RAM ES
Raspberry Pi
Add all DigiKey Parts to Cart
TechForum

Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.

Visit TechForum