Robotics_with_Raspberry_Pi_-_Thompson_Carter
Robotics_with_Raspberry_Pi_-_Thompson_Carter
THOMPSON CARTER
OceanofPDF.com
All rights reserved
No part of this book may be reproduced, distributed, or transmitted in any
form or by any means without the prior written permission of the publisher,
except in the case of brief quotations embodied in critical reviews and
certain other noncommercial uses permitted by copyright law.
OceanofPDF.com
Table of Contents
Introduction
Robotics with Raspberry Pi: Build Your First Robot
Why Robotics with Raspberry Pi?
What You’ll Learn
Who This Book is For
How to Use This Book
The Future of Robotics with Raspberry Pi
Chapter 1: Introduction to Robotics and Raspberry Pi
Chapter 2: Getting Started with Raspberry Pi
Chapter 3: Introduction to Python for Robotics
Chapter 4: Understanding the Basics of Electronics
Chapter 5: GPIO Programming with Python
Exercise 1: Controlling an LED
Exercise 2: Reading a Button Input
Chapter 6: Working with Motors
Exercise 1: Controlling a DC Motor
Exercise 2: Controlling a Servo Motor
Exercise 3: Controlling a Stepper Motor
Chapter 7: Building Your First Simple Robot Chassis
Chapter 8: Powering Your Robot
Chapter 9: Adding Basic Sensors
Understanding the HC-SR04 Ultrasonic Sensor
Wiring the Ultrasonic Sensor to the Raspberry Pi
Writing a Python Program to Read Distance
Running the Program
Using the Ultrasonic Sensor in Robotics Applications
Chapter 10: Controlling Your Robot with a Remote or Smartphone
Chapter 11: Programming Basic Movements and Control Loops
Explanation of the Code
Running the Program
Enhancing the Control Loop
Chapter 12: Introducing Obstacle Avoidance
Explanation of the Code
Running the Program
Expanding the Obstacle Avoidance System
Chapter 13: Building a Line-Following Robot
Explanation of the Code
Running the Program
Fine-Tuning the Line-Following Behavior
Chapter 14: Adding a Camera for Vision Processing
Running the Program
Running the Enhanced Program
Chapter 15: Basic Image Processing for Object Detection
Running the Object Detection Program
Chapter 16: Implementing Object Tracking
Running the Object Tracking Program
Chapter 17: Introducing Artificial Intelligence in Robotics
Running the Object Recognition Program
Chapter 18: Voice Control for Your Robot
Running the Voice Control Program
Chapter 19: Adding Wi-Fi Control with a Web Interface
Running the Web Server
Chapter 20: Autonomous Navigation with Sensors and Mapping
Running the Autonomous Navigation Program
Chapter 21: Testing, Debugging, and Optimization
Chapter 22: Showcasing and Expanding Your Robot
OceanofPDF.com
Introduction
Robotics with Raspberry Pi: Build Your First
Robot
Welcome to Robotics with Raspberry Pi: Build Your First Robot, a
comprehensive, hands-on guide that will take you from understanding the
basics of robotics and Raspberry Pi to creating a fully functional robot that
you can control, expand, and showcase. Whether you’re a student, hobbyist,
or technology enthusiast, this book is designed to provide a jargon-free,
practical approach to robotics, making complex concepts accessible and
enjoyable. By the end of this journey, you’ll not only have a working robot
but also a strong foundation in robotics, programming, and engineering
principles that will serve you well in future projects.
greet_robot("PiBot")
7. Modules and Libraries
A module is a file containing Python code, usually functions or classes. You
can import modules to use existing functionality, which helps keep your
code organized and efficient.
Example:
python
import math
distance = math.sqrt(16) # Using the sqrt function from the math module
print("Square root of 16 is:", distance)
Writing and Running Your First Python Program on the Raspberry Pi
With the basics of Python syntax covered, let’s write a simple program to
get familiar with the process of creating, saving, and executing Python code
on the Raspberry Pi.
Step 1: Open a Text Editor
1. Open Terminal on your Raspberry Pi.
2. Use the nano text editor, which is pre-installed on Raspberry Pi
OS, to create a new Python file.
bash
nano hello_robot.py
Step 2: Write Your Python Code
Inside the nano editor, type the following Python code. This program will
ask for the robot’s name and display a greeting.
python
# hello_robot.py
robot_name = input("Enter your robot's name: ")
print(f"Hello, {robot_name}! Let's start coding.")
Here’s a breakdown of what this code does:
input() function prompts the user to enter the robot’s name.
print() function outputs a greeting that includes the name
entered by the user.
Step 3: Save and Exit
1. Save the file by pressing Ctrl + O, then press Enter to confirm
the filename.
2. Exit the editor by pressing Ctrl + X.
Step 4: Run Your Program
Back in the Terminal, run the program by typing:
bash
python3 hello_robot.py
When you run the code, it will prompt you to enter a robot name, then
display the greeting.
Step 5: Try Modifying the Program
Now, let’s expand on this simple program by adding a loop and a condition.
Open the file again:
bash
nano hello_robot.py
Update the code to include a simple loop that repeats the greeting three
times:
python
# hello_robot.py
robot_name = input("Enter your robot's name: ")
for i in range(3):
print(f"Hello, {robot_name}! Let's start coding.")
print("Goodbye!")
Save the file (Ctrl + O) and exit (Ctrl + X), then run the program again:
bash
python3 hello_robot.py
The program should now greet the robot three times before saying
“Goodbye!”
In this chapter, you learned why Python is the preferred language for
Raspberry Pi robotics and were introduced to essential Python syntax,
including variables, loops, functions, and modules. You also created, saved,
and ran your first Python program on the Raspberry Pi. These foundational
skills will be essential as we progress through the book and begin building
more complex code for controlling hardware and integrating robotics
functionality.
By understanding Python’s basic structures, you’re now equipped to start
programming your robot. In the next chapter, we’ll introduce basic
electronics and the components you’ll be using in your robot, including
how to connect these components to the Raspberry Pi.
Get ready to bring your robot to life!
Chapter 4: Understanding the Basics of
Electronics
In this chapter, we’ll introduce you to essential electronics concepts and
components, including resistors, capacitors, LEDs, and how they work.
We’ll then explore using breadboards and jumper wires to build simple
circuits, which will enable you to connect and control components through
the Raspberry Pi’s GPIO (General Purpose Input/Output) pins. Mastering
these basics is crucial for building and expanding your robot.
Introduction to Key Electronic Components
Understanding a few fundamental components is essential for building
circuits with the Raspberry Pi. Let’s cover the basics of resistors, capacitors,
and LEDs, which will be used throughout your robotics projects.
1. Resistors
A resistor is a component that limits the flow of electric current in a
circuit. Resistance is measured in ohms (Ω), and resistors are used
to control the current flowing to sensitive components, such as
LEDs, to prevent them from burning out.
Color Bands: Resistors have colored bands that
indicate their resistance value. You can use an online
calculator or a color chart to interpret the color bands.
Example: When using an LED, a resistor is often added
in series with it to limit the current, preventing the LED
from overheating.
2. Capacitors
Capacitors store and release electrical energy, which helps smooth
out fluctuations in voltage. They are measured in farads (F) and
come in various sizes and types.
Polarized vs. Non-Polarized: Some capacitors (like
electrolytic capacitors) have polarity, meaning they
have positive (+) and negative (−) leads and must be
connected correctly in a circuit.
Example: Capacitors are often used in motor circuits to
reduce electrical noise and prevent voltage spikes.
2. Jumper Wires
Jumper wires are flexible cables used to connect components on a
breadboard or between a breadboard and the Raspberry Pi’s GPIO
pins. They come in various colors, helping you keep track of
connections. Jumper wires can be male-to-male, female-to-female,
or male-to-female, allowing you to connect between different types
of pins and sockets.
Quick Exercise: Try setting up a simple breadboard with a resistor and
LED. Practice using jumper wires to connect components and get a feel for
how they fit into the breadboard.
Building Simple Circuits and Connecting Them to the Raspberry Pi’s
GPIO Pins
Now that we understand some basic components and how to use a
breadboard, let’s create a simple circuit and connect it to the Raspberry Pi’s
GPIO pins.
The Goal: Build a circuit with an LED that lights up when connected to the
Raspberry Pi, which will serve as a foundation for controlling components
in future chapters.
Understanding GPIO Pins
The Raspberry Pi’s GPIO (General Purpose Input/Output) pins allow it to
communicate with and control various electronic components. The GPIO
pins can be set as input (to read data) or output (to control components like
LEDs or motors).
1. Locate the GPIO Pins: The GPIO header on the Raspberry Pi
has multiple pins, each with a specific function. The standard
pins are divided into:
Power Pins: 3.3V and 5V pins supply power to
components.
Ground Pins (GND): These pins connect to the
ground in your circuits.
GPIO Pins: The general-purpose input/output pins
that can be programmed to send or receive signals.
2. Setting Up the Circuit: Let’s create a basic circuit to control
an LED.
Materials Needed
1 LED
1 resistor (220Ω or 330Ω, to limit current for the LED)
Jumper wires
Breadboard
Step-by-Step Instructions
1. Insert the LED into the Breadboard:
Place the LED on the breadboard, with its longer
leg (anode, +) in one row and its shorter leg
(cathode, -) in another row.
2. Connect a Resistor to the LED:
Insert a 220Ω or 330Ω resistor in series with the
LED. Connect one end of the resistor to the same
row as the anode of the LED and the other end to a
different row.
3. Connect to Raspberry Pi GPIO:
Use a jumper wire to connect the row with the free
end of the resistor to GPIO Pin 18 on the
Raspberry Pi (you can choose another GPIO pin if
you prefer, just remember which one).
Connect the cathode (shorter leg) of the LED to a
ground (GND) pin on the Raspberry Pi using
another jumper wire.
Diagram of Connections:
csharp
[GPIO 18] ----> Resistor ----> Anode (long leg) of LED
[Cathode (short leg) of LED] ----> GND
Writing a Python Script to Control the LED
With the circuit in place, let’s write a Python script to turn the LED on and
off using the Raspberry Pi’s GPIO library.
1. Open the Terminal and create a new Python file:
bash
nano led_control.py
2. Write the following code in led_control.py:
python
Copy code
import RPi.GPIO as GPIO
import time
try:
# Turn the LED on and off repeatedly
while True:
GPIO.output(18, GPIO.HIGH) # Turn LED on
print("LED is ON")
time.sleep(1) # Wait for 1 second
GPIO.output(18, GPIO.LOW) # Turn LED off
print("LED is OFF")
time.sleep(1) # Wait for 1 second
except KeyboardInterrupt:
# Clean up GPIO settings on exit
GPIO.cleanup()
print("Program stopped")
try:
# Check for button press
while True:
if GPIO.input(17) == GPIO.HIGH: # Button is pressed
print("Button Pressed!")
time.sleep(0.5) # Debounce delay
else:
print("Button Released")
time.sleep(0.5)
except KeyboardInterrupt:
# Clean up GPIO settings on exit
GPIO.cleanup()
print("Program stopped")
3. Save and exit (Ctrl + O, Enter, then Ctrl + X).
4. Run the program:
bash
python3 button_input.py
When you press the button, the program should print “Button Pressed!” and
“Button Released” when you let go. To stop the program, press Ctrl + C.
Explanation of Pull-Down Resistors and Debouncing
1. Pull-Down Resistor: The pull-down resistor (10kΩ in this
example) ensures the GPIO pin stays at a low (0) state when
the button isn’t pressed, preventing floating values and false
signals.
2. Debouncing: When a button is pressed, it can produce multiple
signals as it settles. Adding a small delay (e.g., time.sleep(0.5))
helps filter out these erratic signals, creating a clean, single
press detection.
In this chapter, you explored the basics of GPIO programming on the
Raspberry Pi. You learned how to set up and control GPIO pins using
Python and completed two hands-on exercises: one to control an LED and
another to read a button input. These exercises demonstrated how to use
GPIO output and input modes, providing you with essential skills for
building circuits and controlling devices with the Raspberry Pi.
With this foundational understanding, you’re ready to begin adding more
complex components and control mechanisms to your robot. In the next
chapter, we’ll dive into motors and how to control them, enabling your
robot to move and respond to commands. Let’s keep building!
Chapter 6: Working with Motors
Motors are essential components in robotics, as they allow your robot to
move and perform tasks. In this chapter, we’ll explore the different types of
motors commonly used in robotics, how to control them with a Raspberry
Pi using motor drivers, and build a basic motor control program in Python.
By the end of this chapter, you’ll understand how to set up and control DC
motors, servo motors, and stepper motors, giving you the ability to bring
motion to your robot.
Types of Motors: DC Motors, Servo Motors, and Stepper Motors
Each motor type has unique characteristics suited to different tasks. Let’s
examine each one:
1. DC Motors
Description: DC (Direct Current) motors are the
simplest type of motor, operating when current
flows through them. They provide continuous
rotational motion and are often used in applications
where simple on/off and speed control are required.
Control: You can control a DC motor’s speed by
varying the voltage supplied or using Pulse Width
Modulation (PWM).
Common Use: DC motors are typically used in
wheels for basic robots, fans, and simple machinery.
2. Servo Motors
Description: Servo motors offer precise control of
angular position within a limited range (usually 0 to
180 degrees). Internally, a servo motor has a small
DC motor, gears, and a feedback system that allows
precise control.
Control: A servo motor is controlled by a PWM
signal, which sets the position of the motor shaft
based on the duty cycle.
Common Use: Servos are used in applications
requiring precise angle control, such as controlling
robot arms or adjusting a camera’s position.
3. Stepper Motors
Description: Stepper motors move in fixed
increments or "steps." Unlike DC motors, they
rotate in precise steps, allowing you to control both
speed and position very accurately.
Control: Stepper motors require specific step
sequences for operation, which are controlled by
sending pulses to the motor driver.
Common Use: Stepper motors are ideal for
applications requiring precise control, such as 3D
printers, CNC machines, and precise robotic arms.
Choosing the Right Motor: The motor type you choose depends on the
level of control and precision required. For basic movement, DC motors are
usually sufficient, while servo and stepper motors are best suited for
applications needing precise angular or step control.
Setting Up Motor Driver Circuits to Control Motors with the Raspberry Pi
Since the Raspberry Pi’s GPIO pins cannot supply enough current to drive
motors directly, we use motor driver circuits. Motor drivers amplify the
low-current signal from the GPIO pins to the level needed by motors.
Here’s an overview of common motor drivers:
1. L293D Motor Driver (for DC Motors)
The L293D is a popular H-bridge motor driver chip
that allows control of two DC motors
independently. It supports forward and reverse
rotation and provides enough current to drive small
to medium-sized DC motors.
Pin Connections:
IN1/IN2: Control direction of Motor 1.
IN3/IN4: Control direction of Motor 2.
Enable Pins: Control motor speed
through PWM signals.
2. PWM for Servo Motors
Servo motors are controlled by sending a PWM
signal from the Raspberry Pi’s GPIO pins directly,
without an external driver in many cases. The PWM
duty cycle determines the position of the servo arm.
Pin Connection:
Connect the control wire of the servo to a
PWM-enabled GPIO pin.
Use a separate power source (often 5V)
for larger servos to avoid overloading the
Raspberry Pi.
3. ULN2003 Driver Board (for Stepper Motors)
The ULN2003 is a driver board commonly used for
small stepper motors. It contains transistors that
amplify the GPIO signals to drive the motor.
Pin Connections:
Connect the stepper motor’s four control
wires to the driver board, which then
connects to the Raspberry Pi’s GPIO pins
for control.
# Reverse rotation
GPIO.output(18, GPIO.LOW)
GPIO.output(23, GPIO.HIGH)
pwm.ChangeDutyCycle(50) # 50% speed
time.sleep(2)
# Set up PWM
pwm = GPIO.PWM(18, 50) # 50 Hz (20ms PWM period)
pwm.start(0) # Start with 0% duty cycle
try:
# Move to 0 degrees
pwm.ChangeDutyCycle(2) # 2% duty cycle
time.sleep(1)
# Move to 90 degrees
pwm.ChangeDutyCycle(7) # 7% duty cycle
time.sleep(1)
try:
for _ in range(512): # Move 512 steps (one full rotation)
for step in seq:
for pin in range(4):
GPIO.output(control_pins[pin], step[pin])
time.sleep(0.001)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
print("Program stopped")
3. Save and run the code. The stepper motor should rotate one full
revolution.
In this chapter, you learned about three common types of motors—DC,
servo, and stepper—and how to control them with the Raspberry Pi. You set
up motor driver circuits to safely control these motors and wrote Python
programs to manage motor direction, speed, and position.
With these skills, you can now make your robot move and perform tasks
requiring precision and control. In the next chapter, we’ll begin constructing
the robot chassis and integrating these motors, laying the groundwork for
your first mobile robot!
Chapter 7: Building Your First Simple Robot
Chassis
In this chapter, we’ll focus on the physical structure of your robot: the
chassis. The chassis is the foundation of your robot, providing stability and
housing for components like motors, batteries, and the Raspberry Pi. We’ll
start with an overview of common robot chassis designs, assemble a simple
wheeled chassis with DC motors, and wire up the motors to test basic
movement commands.
Overview of Common Robot Chassis Designs
There are various chassis designs used in robotics, each suited to different
types of movement and terrains. Here’s an overview of the most common
designs:
1. Two-Wheeled Differential Drive
Description: This is one of the simplest and most
popular designs for small robots. It features two
powered wheels on either side, with each wheel
driven by a separate motor. A caster or omni-
directional wheel supports the rear, allowing the
robot to balance.
Pros: Simple to control; can pivot in place, making
it highly maneuverable.
Cons: Limited stability and traction on uneven
surfaces.
Common Uses: Educational robots, indoor robots,
small hobby robots.
2. Four-Wheeled Drive
Description: A chassis with four powered wheels,
each driven by a separate motor or paired motors. It
provides more stability and traction than a two-
wheeled design.
Pros: Good stability and can handle uneven terrain
better than a two-wheeled robot.
Cons: More complex control and wiring, increased
power consumption.
Common Uses: Outdoor robots, larger autonomous
robots, robots requiring more stability.
3. Tracked or Tank-Style
Description: This design uses continuous tracks
instead of wheels, similar to a tank. The tracks
provide excellent traction and stability on a variety
of surfaces.
Pros: High stability and traction; suitable for rough
and uneven terrain.
Cons: Complex mechanics and higher power
requirements; slower speeds compared to wheeled
robots.
Common Uses: Robots designed for outdoor
exploration or rough terrains, rescue robots.
Choosing a Chassis Design: For our project, we’ll build a simple two-
wheeled differential drive robot. This design is easy to assemble and
control, making it ideal for beginners. You can later expand or upgrade your
robot with a four-wheel or tracked chassis as you gain experience.
Assembling a Simple Wheeled Chassis with DC Motors
Let’s assemble a basic two-wheeled robot chassis that uses DC motors for
propulsion. Here’s what you’ll need for the assembly:
Materials Needed
1 two-wheeled robot chassis kit (including two DC motors, two
wheels, and a caster wheel)
Motor mounts (if not included in your chassis kit)
Screws and nuts (often included with the kit)
Screwdriver
Battery holder (for powering motors)
Step-by-Step Assembly Instructions
1. Attach the DC Motors to the Chassis
Secure the DC motors to the chassis using motor
mounts and screws. Place each motor on opposite
sides of the chassis so that each motor drives one
wheel.
Ensure that the motors are securely attached and
align with the sides of the chassis to keep the
wheels stable.
2. Attach the Wheels to the Motors
Push the wheels onto the output shafts of each DC
motor until they fit snugly.
Verify that the wheels spin freely when the motor
shafts are rotated.
3. Install the Caster Wheel
Attach the caster wheel (the small, omni-directional
support wheel) to the rear of the chassis. This wheel
stabilizes the robot and allows it to pivot.
Ensure that the caster wheel can move smoothly in
all directions.
4. Add a Battery Holder
Place the battery holder on the chassis (often there
is a slot or mount specifically for the batteries).
Secure it in place with screws or zip ties if
necessary.
5. Mount the Raspberry Pi (Optional)
If your chassis has space, you can mount the
Raspberry Pi to the chassis using mounting holes
and screws. However, for initial testing, you may
leave the Raspberry Pi nearby on a stable surface.
Your basic robot chassis should now be assembled! Next, we’ll wire up the
motors and test basic movement commands to ensure the motors and
chassis function as expected.
Wiring Up the Motors and Testing Basic Movement Commands
To control the DC motors, we’ll use the L293D motor driver (or an L298N
motor driver if preferred). The motor driver allows us to control each motor
independently, enabling the robot to move forward, backward, and turn.
Circuit Setup
1. Connect the L293D Motor Driver to the Raspberry Pi:
Connect IN1 to GPIO pin 18 on the Raspberry Pi.
Connect IN2 to GPIO pin 23 on the Raspberry Pi.
Connect IN3 to GPIO pin 24 on the Raspberry Pi.
Connect IN4 to GPIO pin 25 on the Raspberry Pi.
Connect the Enable 1 pin (for Motor 1) to GPIO
pin 17, and Enable 2 (for Motor 2) to GPIO pin 27.
These will control the speed of each motor through
PWM.
2. Connect the Motors to the Motor Driver:
Attach one motor to the OUT1 and OUT2 terminals
on the motor driver.
Attach the second motor to the OUT3 and OUT4
terminals.
3. Power the Circuit:
Connect an external power source (battery pack) to
the motor driver’s VCC and GND pins to power the
motors.
Connect the Raspberry Pi’s GND to the motor
driver’s GND to share a common ground.
# Motor pins
IN1 = 18
IN2 = 23
IN3 = 24
IN4 = 25
ENA = 17
ENB = 27
def backward():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.HIGH)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.HIGH)
def turn_left():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.HIGH)
GPIO.output(IN3, GPIO.HIGH)
GPIO.output(IN4, GPIO.LOW)
def turn_right():
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.HIGH)
def stop():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
# Test movement
try:
print("Moving forward")
forward()
time.sleep(2)
print("Moving backward")
backward()
time.sleep(2)
print("Turning left")
turn_left()
time.sleep(2)
print("Turning right")
turn_right()
time.sleep(2)
print("Stopping")
stop()
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
print("Program stopped")
3. Save and exit the file (Ctrl + O, Enter, then Ctrl + X).
4. Run the code to test the movement commands:
bash
python3 motor_test.py
Expected Results: The robot should perform the following movements:
Move forward for 2 seconds
Move backward for 2 seconds
Turn left for 2 seconds
Turn right for 2 seconds
Stop
You can adjust the motor speeds by changing the duty cycle (50% in this
example) of the pwmA and pwmB PWM signals.
In this chapter, you assembled a basic two-wheeled robot chassis, wired up
the DC motors using an L293D motor driver, and wrote a Python program
to test basic movement commands. This setup forms the foundation of your
robot, enabling it to perform basic maneuvers. You now have a mobile
platform to which you can add sensors, controls, and more advanced
functionalities.
In the next chapter, we’ll dive into powering your robot and managing
power sources effectively. This will ensure your robot runs reliably and
safely as we add more components and functionality.
Chapter 8: Powering Your Robot
Powering your robot effectively is essential for smooth and reliable
operation. This chapter covers the basics of powering the Raspberry Pi,
choosing the right power source for your robot, and wiring it up correctly.
We’ll also discuss power management and safety tips to prevent issues like
overheating, power surges, and accidental damage.
Powering the Raspberry Pi: Batteries vs. External Power Sources
The Raspberry Pi needs a stable 5V power source to function correctly.
Let’s explore the most common options for powering both the Raspberry Pi
and other components of your robot.
1. Using Batteries
Battery Packs: A portable battery pack or
rechargeable battery pack is a popular choice,
especially if you want a fully mobile robot. Many
packs provide 5V via USB, making them
compatible with the Raspberry Pi’s power input.
Battery Types: Common types include lithium-ion
(Li-Ion), lithium-polymer (LiPo), and AA battery
packs. Each has its pros and cons:
Li-Ion and LiPo batteries provide high
capacity and low weight but require
careful handling and proper chargers.
AA Battery Packs (6x AA batteries can
provide ~9V) can work with a voltage
regulator to step down to 5V for the
Raspberry Pi.
2. External Power Sources
Wall Adapters: If your robot doesn’t need to be
mobile (e.g., during testing), a wall adapter is ideal.
A 5V/3A power supply is recommended for the
Raspberry Pi 4, as it can handle the Pi’s power
needs along with some connected components.
USB Power Banks: Portable USB power banks are
compatible with the Pi’s micro-USB or USB-C
power port. Ensure the power bank provides at least
2.5A for Raspberry Pi models requiring more
current.
3. Power Requirements for Motors and Sensors
Motors often require more power than the
Raspberry Pi itself, so you may need a separate
battery pack dedicated to motors.
It’s common to use a higher-voltage power source
(e.g., 6V or 9V) for the motors and a 5V power
source for the Raspberry Pi. A common ground
between these sources is necessary for them to
communicate effectively.
def measure_distance():
# Trigger a pulse
GPIO.output(TRIG, True)
time.sleep(0.00001) # Send a 10µs pulse
GPIO.output(TRIG, False)
# Calculate distance in cm
distance = (duration * 34300) / 2 # Speed of sound is 34300
cm/s
return distance
try:
while True:
dist = measure_distance()
print(f"Distance: {dist:.2f} cm")
time.sleep(1) # Wait before the next measurement
except KeyboardInterrupt:
print("Measurement stopped by user")
finally:
GPIO.cleanup()
3. Save and exit the file (Ctrl + O, Enter, then Ctrl + X).
# Motor pins
IN1 = 18
IN2 = 23
IN3 = 24
IN4 = 25
ENA = 17
ENB = 27
def move_backward():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.HIGH)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.HIGH)
def turn_left():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.HIGH)
GPIO.output(IN3, GPIO.HIGH)
GPIO.output(IN4, GPIO.LOW)
def turn_right():
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.HIGH)
def stop():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
try:
while True:
# Receive data from the smartphone
data = client_socket.recv(1024).decode("utf-8").strip()
print(f"Received: {data}")
# Motor pins
IN1 = 18
IN2 = 23
IN3 = 24
IN4 = 25
ENA = 17
ENB = 27
def move_backward():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.HIGH)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.HIGH)
def turn_left():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.HIGH)
GPIO.output(IN3, GPIO.HIGH)
GPIO.output(IN4, GPIO.LOW)
def turn_right():
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.HIGH)
def stop():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
if command == "w":
print("Moving forward")
move_forward()
time.sleep(2)
stop()
elif command == "s":
print("Moving backward")
move_backward()
time.sleep(2)
stop()
elif command == "a":
print("Turning left")
turn_left()
time.sleep(1)
stop()
elif command == "d":
print("Turning right")
turn_right()
time.sleep(1)
stop()
elif command == "x":
print("Stopping")
stop()
elif command == "q":
print("Exiting program")
break
else:
print("Invalid command. Please use w, s, a, d, x, or q.")
except KeyboardInterrupt:
print("Program interrupted")
finally:
stop()
GPIO.cleanup()
print("GPIO cleaned up")
3. Save and exit the file (Ctrl + O, Enter, then Ctrl + X).
Hands-on: Writing Code to Make the Robot Avoid Obstacles in Its Path
With the ultrasonic sensor connected, let’s write a Python program to detect
obstacles and command the robot to change direction when an obstacle is
detected within a certain distance.
Step 1: Writing the Obstacle Avoidance Code
1. Open the Terminal and create a new Python file:
bash
nano obstacle_avoidance.py
2. Write the following code to control the robot’s movement and
detect obstacles using the ultrasonic sensor:
python
import RPi.GPIO as GPIO
import time
def move_backward():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.HIGH)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.HIGH)
def turn_left():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.HIGH)
GPIO.output(IN3, GPIO.HIGH)
GPIO.output(IN4, GPIO.LOW)
def turn_right():
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.HIGH)
def stop():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
def turn_left():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.HIGH)
GPIO.output(IN4, GPIO.LOW)
def turn_right():
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
def stop():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
# Line-following logic
if center_detected:
print("Line detected in center, moving forward")
move_forward()
elif left_detected:
print("Line detected on left, turning left")
turn_left()
elif right_detected:
print("Line detected on right, turning right")
turn_right()
else:
print("No line detected, stopping")
stop()
time.sleep(0.1)
except KeyboardInterrupt:
print("Program interrupted")
finally:
stop()
GPIO.cleanup()
print("GPIO cleaned up")
3. Save and exit the file (Ctrl + O, Enter, then Ctrl + X).
if not camera.isOpened():
print("Error: Could not access the camera.")
exit()
# Wait for the 'q' key to exit or 'c' key to capture an image
key = cv2.waitKey(1)
if key == ord('q'):
print("Exiting live feed.")
break
elif key == ord('c'):
# Capture and save the current frame as an image
img_name = "captured_image.png"
cv2.imwrite(img_name, frame)
print(f"Image saved: {img_name}")
finally:
# Release the camera and close windows
camera.release()
cv2.destroyAllWindows()
3. Save and exit the file (Ctrl + O, Enter, then Ctrl + X).
Explanation of the Code:
Accessing the Camera: VideoCapture(0) initializes the
camera. If it’s not detected, the program prints an error and
exits.
Reading Frames: The camera.read() function reads frames
from the camera in real-time.
Displaying the Feed: cv2.imshow() displays each frame in a
window named “Live Camera Feed.”
Keyboard Controls:
Press 'q' to exit the live feed.
Press 'c' to capture an image and save it as
"captured_image.png" in the current directory.
if not camera.isOpened():
print("Error: Could not access the camera.")
exit()
try:
while True:
ret, frame = camera.read()
if not ret:
print("Failed to grab frame")
break
key = cv2.waitKey(1)
if key == ord('q'):
print("Exiting live feed.")
break
elif key == ord('c'):
img_name = "captured_image.png"
cv2.imwrite(img_name, frame)
print(f"Image saved: {img_name}")
finally:
camera.release()
cv2.destroyAllWindows()
3. Save and exit the file.
Explanation of Additional Code:
Grayscale Conversion: cv2.cvtColor(frame,
cv2.COLOR_BGR2GRAY) converts each frame to grayscale,
simplifying edge detection.
Edge Detection: cv2.Canny() performs edge detection on the
grayscale frame. You can adjust the threshold values (50 and
150 in this case) to change the sensitivity.
Multiple Windows: This code displays the original feed and a
processed feed with edges detected.
if not camera.isOpened():
print("Error: Could not access the camera.")
exit()
try:
while True:
# Capture frame-by-frame
ret, frame = camera.read()
if not ret:
print("Failed to grab frame")
break
# Edge Detection
gray_frame = cv2.cvtColor(frame,
cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray_frame, 50, 150)
# Shape Recognition
_, thresh = cv2.threshold(gray_frame, 127, 255,
cv2.THRESH_BINARY)
contours, _ = cv2.findContours(thresh, cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
approx = cv2.approxPolyDP(contour, 0.02 *
cv2.arcLength(contour, True), True)
x, y, w, h = cv2.boundingRect(approx)
if len(approx) == 3:
shape = "Triangle"
elif len(approx) == 4:
shape = "Rectangle"
elif len(approx) > 4:
shape = "Circle"
else:
shape = None
finally:
# Release the camera and close all windows
camera.release()
cv2.destroyAllWindows()
3. Save and exit the file (Ctrl + O, Enter, then Ctrl + X).
Explanation of the Code:
Edge Detection: We use Canny edge detection to highlight
edges in the live feed, which is displayed in a separate window.
Color Tracking: We isolate a color (red in this example) using
a mask in the HSV color space and display the masked color.
Shape Recognition: We detect contours in the frame,
approximate their shapes, and label recognized shapes (triangle,
rectangle, circle) in the live feed.
def turn_left():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.HIGH)
GPIO.output(IN4, GPIO.LOW)
def turn_right():
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
def stop():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
try:
while True:
# Capture frame-by-frame
ret, frame = camera.read()
if not ret:
print("Failed to grab frame")
break
return frame
try:
while True:
# Capture frame-by-frame
ret, frame = camera.read()
if not ret:
print("Failed to grab frame")
break
finally:
camera.release()
cv2.destroyAllWindows()
3. Save and exit the file (Ctrl + O, Enter, then Ctrl + X).
Explanation of the Code:
Loading the Model: The code loads the MobileNet SSD model
with TensorFlow Lite and prepares it for inference.
Object Detection: The detect_objects function resizes each
frame to the model’s input size, runs inference, and retrieves
the bounding boxes, class IDs, and confidence scores.
Displaying Results: For each detected object, the program
draws a bounding box and displays the object label and
confidence score.
def move_backward():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.HIGH)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.HIGH)
def turn_left():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.HIGH)
GPIO.output(IN4, GPIO.LOW)
def turn_right():
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
def stop():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
while True:
# Listen for a command
audio = recognizer.listen(source)
try:
# Recognize the command
command =
recognizer.recognize_google(audio).lower()
print(f"Command received: {command}")
except sr.UnknownValueError:
print("Could not understand the command")
except sr.RequestError:
print("Error with the speech recognition service")
except KeyboardInterrupt:
print("Program interrupted")
finally:
stop()
GPIO.cleanup()
print("GPIO cleaned up")
3. Save and exit the file (Ctrl + O, Enter, then Ctrl + X).
Explanation of the Code:
Speech Recognition: The program uses
recognizer.listen(source) to listen for voice commands and
recognizer.recognize_google(audio) to convert audio to text.
Command Processing: Based on the recognized text, the
program calls different movement functions to control the
robot.
Error Handling: If the speech recognizer fails to understand or
if there’s an issue with the service, it catches the error and
continues listening.
def move_backward():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.HIGH)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.HIGH)
def turn_left():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.HIGH)
GPIO.output(IN4, GPIO.LOW)
def turn_right():
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
def stop():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
@app.route('/forward')
def forward():
move_forward()
time.sleep(1)
stop()
return 'Moving Forward'
@app.route('/backward')
def backward():
move_backward()
time.sleep(1)
stop()
return 'Moving Backward'
@app.route('/left')
def left():
turn_left()
time.sleep(0.5)
stop()
return 'Turning Left'
@app.route('/right')
def right():
turn_right()
time.sleep(0.5)
stop()
return 'Turning Right'
@app.route('/stop')
def halt():
stop()
return 'Stopping'
if __name__ == '__main__':
try:
app.run(host='0.0.0.0', port=5000)
finally:
GPIO.cleanup()
4. Save and exit the file (Ctrl + O, Enter, then Ctrl + X).
Explanation of the Code:
Flask Routes: Each route (e.g., /forward, /backward)
corresponds to a movement command. When a button is
clicked on the web interface, the robot performs the action for a
specified duration, then stops.
Web Server Setup: The Flask app is set to run on the IP
address 0.0.0.0, making it accessible from any device on the
same network.
GPIO Cleanup: The program ensures GPIO is cleaned up after
stopping the server.
Step 2: Creating the HTML Template for the Control Panel
1. Create a folder for templates:
bash
mkdir templates
2. Create an HTML file for the control panel:
bash
Copy code
nano templates/index.html
3. Write the following HTML code for a simple web interface
with movement buttons:
html
Copy code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>Robot Control Panel</title>
<style>
body { text-align: center; font-family: Arial, sans-serif; }
button { font-size: 20px; padding: 10px 20px; margin: 10px;
}
</style>
</head>
<body>
<h1>Robot Control Panel</h1>
<button onclick="fetch('/forward')">Forward</button><br>
<button onclick="fetch('/left')">Left</button>
<button onclick="fetch('/stop')">Stop</button>
<button onclick="fetch('/right')">Right</button><br>
<button onclick="fetch('/backward')">Backward</button>
</body>
</html>
4. Save and exit the file.
Explanation of the HTML Code:
JavaScript Fetch Calls: Each button uses JavaScript’s fetch
function to send a request to the corresponding route (e.g.,
/forward for forward movement).
Control Panel Layout: The control panel has buttons for each
movement direction and a “Stop” button in the center.
GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)
def turn_left():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.HIGH)
GPIO.output(IN4, GPIO.LOW)
time.sleep(0.5)
def turn_right():
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
time.sleep(0.5)
def stop():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
start_time = time.time()
stop_time = time.time()
while GPIO.input(ECHO) == 0:
start_time = time.time()
while GPIO.input(ECHO) == 1:
stop_time = time.time()
finally:
stop()
GPIO.cleanup()
print("GPIO cleaned up")
3. Save and exit the file (Ctrl + O, Enter, then Ctrl + X).
Explanation of the Code:
Grid Map: The grid_map is a 5x5 matrix representing the
environment. Cells are updated as "free" or "occupied" based
on sensor readings.
Movement Logic: The robot moves forward unless an obstacle
is detected within 20 cm, in which case it turns right.
Map Display: After each step, the program prints the current
map to show detected obstacles.
GPIO.setmode(GPIO.BCM)
GPIO.setup(IN1, GPIO.OUT)
GPIO.setup(IN2, GPIO.OUT)
GPIO.setup(IN3, GPIO.OUT)
GPIO.setup(IN4, GPIO.OUT)
GPIO.setup(ENA, GPIO.OUT)
GPIO.setup(ENB, GPIO.OUT)
def move_forward():
print("Moving forward")
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.HIGH)
GPIO.output(IN4, GPIO.LOW)
time.sleep(1)
stop()
def turn_left():
print("Turning left")
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.HIGH)
GPIO.output(IN4, GPIO.LOW)
time.sleep(0.5)
stop()
def stop():
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
def measure_distance():
GPIO.output(TRIG, True)
time.sleep(0.00001)
GPIO.output(TRIG, False)
start_time = time.time()
stop_time = time.time()
while GPIO.input(ECHO) == 0:
start_time = time.time()
while GPIO.input(ECHO) == 1:
stop_time = time.time()
try:
print("Starting movement and sensor tests...")
move_forward()
turn_left()
distance = measure_distance()
finally:
stop()
GPIO.cleanup()
print("GPIO cleaned up")
3. Save and run the script:
bash
python3 test_robot.py
This script provides a basic test of movement functions and the ultrasonic
sensor, helping to identify any issues before moving on to more complex
tasks.
In this chapter, you learned about common issues and debugging techniques
in Raspberry Pi robotics, tested and refined the robot’s movement and
sensor accuracy, and applied optimization strategies to improve
performance and reliability. These steps are essential to ensure your robot
functions consistently and can handle various environments and tasks.
In the final chapter, we’ll discuss deployment and maintenance, covering
strategies to keep your robot operational over time, including regular
testing, maintenance routines, and potential upgrades to expand
functionality.
Chapter 22: Showcasing and Expanding Your
Robot
With your robot now operational and optimized, it’s time to consider how to
showcase it effectively and think about expanding its capabilities for future
projects. In this chapter, we’ll cover best practices for preparing your robot
for demonstrations or project showcases, provide tips for documenting and
sharing your work, and explore ideas for enhancing your robot with
advanced features.
Preparing Your Robot for a Demonstration or Project Showcase
A well-prepared demonstration not only highlights your robot’s capabilities
but also communicates the effort and thought behind your work. Here are
key steps to prepare your robot for a successful showcase:
1. Define the Purpose of the Demonstration:
Decide on the key features you want to showcase. Is
it autonomous navigation, object tracking, or remote
control? Tailoring the demonstration to highlight
specific capabilities ensures a focused presentation.
Outline the sequence of actions your robot will
perform during the demo. For example, if you’re
showcasing navigation, plan a path with obstacles to
show the robot’s ability to avoid them.
2. Test and Troubleshoot in Advance:
Conduct multiple test runs in the demonstration
space to ensure the robot performs as expected in
the given environment. This is particularly
important if lighting or floor texture differs from
your testing area.
Prepare for potential issues by checking power
sources, confirming stable connections, and
inspecting sensors and motors for functionality.
3. Prepare a Backup Plan:
Sometimes, things don’t go as planned. Prepare a
backup script or pre-recorded video of the robot in
action in case of unexpected technical issues. This
allows you to still demonstrate your work even if
live functionality fails.
4. Explain Key Features and Technical Details:
Prepare a brief overview of your robot’s design, key
features, and underlying technology. Use visuals
like diagrams or photos to illustrate the robot’s
components, wiring, and coding structure.
Be ready to answer questions about the robot’s
sensors, code, and any algorithms used, especially if
presenting to a technical audience.
5. Clean and Aesthetic Presentation:
Ensure your robot is clean, with wires neatly
organized and components firmly attached. A tidy
setup makes the robot look more professional and
easier for the audience to understand.
Use labels or a poster board with diagrams to
explain each component’s function, helping viewers
quickly grasp how your robot works.
Tips for Documenting Your Robot Project and Sharing It with Others
Documentation is essential to showcase your project, whether for a
presentation, portfolio, or online community. Here’s how to document your
robot effectively:
1. Create a Project Overview:
Start with a high-level description of your project,
including its purpose, features, and goals. Explain
why you built this robot and what unique
functionalities it has.
2. Include Technical Details:
Detail the hardware and software used, including
the Raspberry Pi model, sensors, motors, power
sources, and libraries. Include a parts list for easy
reference.
Explain key algorithms or techniques you
implemented, such as obstacle avoidance, object
tracking, or voice control. Diagrams and pseudo-
code can help illustrate complex processes.
3. Step-by-Step Instructions:
Document each step of your build process, from
assembling the hardware to programming the robot.
Include setup and installation instructions for
dependencies, libraries, or other software
requirements.
Capture photos and screenshots of each stage to
create a visual guide. This is especially helpful if
you plan to share your project as an educational
resource.
4. Record Performance Metrics:
Include data on how your robot performs, such as
average speed, obstacle detection range, and battery
life. These metrics provide insights into the robot’s
capabilities and help others replicate or build upon
your work.
5. Highlight Challenges and Solutions:
Document any major challenges you faced and how
you overcame them. This can include debugging
issues, design modifications, or algorithm
adjustments. Sharing problem-solving strategies
adds value to your project and demonstrates critical
thinking.
6. Create a Demonstration Video:
A video is one of the most effective ways to
showcase your project. Record the robot performing
key actions, explain its features as it runs, and
include close-ups of the robot’s components.
Narrate or add captions to guide viewers through
each feature, making it easy to understand even for
those unfamiliar with robotics.
7. Share Your Project Online:
Consider sharing your project on platforms like
GitHub, Hackster.io, or robotics forums. Provide
access to your code and instructions to help others
learn from or replicate your work.
Engage with the community by responding to
questions and sharing updates or improvements to
your robot.
OceanofPDF.com