How to Add Light to a Raspberry Pi Wheeled Robot

In this post, I will show you how to add light to a Raspberry Pi wheeled robot.

Special shout out to Matt Timmons-Brown for this project idea. He is the author of a really good book on Raspberry Pi robotics: (Learn Robotics with Raspberry Pi). Go check it out!

Requirements

Here are the requirements:

  • Add lights to a wheeled robot using the Adafruit NeoPixel Stick with 8 RGB LEDs.

You Will Need

The following components are used in this project. You will need:

Directions

Setting Up the RGB LED Stick

Cut four pins off one of the male pin header connectors with a pair of scissors.

Solder the four pins to the DIN (stands for “data-in”) side of the RGB LED stick.

lights-robot-rpi-1

If you don’t know how to solder, check out my video below.

Connect the 5VDC pin of the RGB LED stick to the positive (red) 5V rail of the solderless breadboard.

lights-robot-rpi-2

Connect the GND (Ground) pin of the RGB LED stick to the blue (negative) rail of the solderless breadboard.

lights-robot-rpi-3

Connect the DIN pin of the RGB LED stick to pin 19 (GPIO 10) of the Raspberry Pi. This is the Master Output Slave Input (MOSI) pin that the Pi uses to send information out via the SPI protocol (more on this in a second).

lights-robot-rpi-4

Mount the RGB LED on the Robot using Velcro. You can mount it anywhere you want.

lights-robot-rpi-5

Power up your Raspberry Pi.

Open a terminal window.

Verify that pip is installed. Pip is a tool that enables you to install and manage libraries that are not a part of Python’s standard library. Type the following commands in the terminal window.

sudo apt-get update
lights-robot-rpi-6
sudo apt-get install python3-pip
Install the rpi_ws 281x library.
sudo pip3 install rpi_ws281x

Make sure the SPI bus is enabled.

SPI is a communication interface built-in to several of the GPIO pins of the Raspberry Pi. It is good to use the SPI bus when you want data to be streamed over short distances, continuously with no interruptions.

Type this terminal command:

sudo raspi-config

Interfacing Options → SPI

lights-robot-rpi-7

Select Yes

Finish

Reboot the Raspberry Pi.

sudo reboot

Wait for the Raspberry Pi to reboot, then open a terminal window again in Raspberry Pi (I’m using Putty).

Modify the Graphics Programming Unit core frequency so that it is 250 MHz.

sudo nano /boot/config.txt

Scroll down, and add this to the bottom of the file.

core_freq = 250
lights-robot-rpi-8

CTRL-X –> Y –> ENTER to save

Reboot the Raspberry Pi.

sudo reboot 

Testing the rpi_ws281x Library

Open IDLE on your Raspberry Pi.

Create a new file.

Save it as rgb_library_test.py

Type the following code:

#!/usr/bin/env python3
# NeoPixel library strandtest example
# Author: Tony DiCola (tony@tonydicola.com)
#
# Direct port of the Arduino NeoPixel library strandtest example.  Showcases
# various animations on a strip of NeoPixels.
# Code source (Matt-Timmons Brown): https://github.com/the-raspberry-pi-guy/raspirobots
# Minor edits by Matt Timmons-Brown for "Learn Robotics with Raspberry Pi"

import time
from rpi_ws281x import *
import argparse

# LED strip configuration:
LED_COUNT      = 8      # Number of LED pixels.
#LED_PIN       = 18      # GPIO pin connected to the pixels (18 uses PWM!).
LED_PIN        = 10      # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
LED_FREQ_HZ    = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA        = 10      # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 255     # Set to 0 for darkest and 255 for brightest
LED_INVERT     = False   # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL    = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53
LED_STRIP      = ws.WS2811_STRIP_GRB # Strip type and color ordering

# Define functions which animate LEDs in various ways.
def colorWipe(strip, color, wait_ms=50):
    """Wipe color across display a pixel at a time."""
    for i in range(strip.numPixels()):
        strip.setPixelColor(i, color)
        strip.show()
        time.sleep(wait_ms/1000.0)

def theaterChase(strip, color, wait_ms=50, iterations=10):
    """Movie theater light style chaser animation."""
    for j in range(iterations):
        for q in range(3):
            for i in range(0, strip.numPixels(), 3):
                strip.setPixelColor(i+q, color)
            strip.show()
            time.sleep(wait_ms/1000.0)
            for i in range(0, strip.numPixels(), 3):
                strip.setPixelColor(i+q, 0)

def wheel(pos):
    """Generate rainbow colors across 0-255 positions."""
    if pos < 85:
        return Color(pos * 3, 255 - pos * 3, 0)
    elif pos < 170:
        pos -= 85
        return Color(255 - pos * 3, 0, pos * 3)
    else:
        pos -= 170
        return Color(0, pos * 3, 255 - pos * 3)

def rainbow(strip, wait_ms=20, iterations=1):
    """Draw rainbow that fades across all pixels at once."""
    for j in range(256*iterations):
        for i in range(strip.numPixels()):
            strip.setPixelColor(i, wheel((i+j) & 255))
        strip.show()
        time.sleep(wait_ms/1000.0)

def rainbowCycle(strip, wait_ms=20, iterations=5):
    """Draw rainbow that uniformly distributes itself across all pixels."""
    for j in range(256*iterations):
        for i in range(strip.numPixels()):
            strip.setPixelColor(i, wheel((int(i * 256 / strip.numPixels()) + j) & 255))
        strip.show()
        time.sleep(wait_ms/1000.0)

def theaterChaseRainbow(strip, wait_ms=50):
    """Rainbow movie theater light style chaser animation."""
    for j in range(256):
        for q in range(3):
            for i in range(0, strip.numPixels(), 3):
                strip.setPixelColor(i+q, wheel((i+j) % 255))
            strip.show()
            time.sleep(wait_ms/1000.0)
            for i in range(0, strip.numPixels(), 3):
                strip.setPixelColor(i+q, 0)

# Main program logic follows:
if __name__ == '__main__':
    # Process arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('-c', '--clear', action='store_true', help='clear the display on exit')
    args = parser.parse_args()

    # Create NeoPixel object with appropriate configuration.
    strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
    # Intialize the library (must be called once before other functions).
    strip.begin()

    print ('Press Ctrl-C to quit.')
    if not args.clear:
        print('Use "-c" argument to clear LEDs on exit')

    try:

        while True:
            print ('Color wipe animations.')
            colorWipe(strip, Color(255, 0, 0))  # Red wipe
            colorWipe(strip, Color(0, 255, 0))  # Blue wipe
            colorWipe(strip, Color(0, 0, 255))  # Green wipe
            print ('Theater chase animations.')
            theaterChase(strip, Color(127, 127, 127))  # White theater chase
            theaterChase(strip, Color(127,   0,   0))  # Red theater chase
            theaterChase(strip, Color(  0,   0, 127))  # Blue theater chase
            print ('Rainbow animations.')
            rainbow(strip)
            rainbowCycle(strip)
            theaterChaseRainbow(strip)

    except KeyboardInterrupt:
        if args.clear:
            colorWipe(strip, Color(0,0,0), 10)

Save it.

Open a new terminal window.

Run the test using the following command:

python3 rgb_library_test.py -c

The -c at the end makes sure that the RGB LEDs turn off when you type CTRL-C in the terminal window.

Managing the RGB LEDs Using the Nintendo Wii Remote Control

Now we will create a program to control the LEDs using our Wii remote. Open a new terminal window on your Raspberry Pi, and go to the robot directory.

cd robot

Open a new file in IDLE named rgb_wii_remote.py

Type the following code into the program:

import gpiozero
import cwiid
import time
from rpi_ws281x import *

# Author: Matt Timmons-Brown for "Learn Robotics with Raspberry Pi"
# Description: Enables control of the LED with the Wii Remote
# Minor modifications made by Addison Sears-Collins

robot = gpiozero.Robot(left=(22,27), right=(17,18))

print("Press and hold the 1+2 buttons on your Wiimote simultaneously")
wii = cwiid.Wiimote()
print("Connection established")
wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC

LED_COUNT      = 8
LED_PIN        = 10
LED_FREQ_HZ    = 800000
LED_DMA        = 10
LED_BRIGHTNESS = 150
LED_INVERT     = False
LED_CHANNEL    = 0
LED_STRIP      = ws.WS2811_STRIP_GRB

strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL, LED_STRIP)
strip.begin()

def colorWipe(strip, color, wait_ms=50):
	"""Wipe color across display a pixel at a time."""
	for i in range(strip.numPixels()):
		strip.setPixelColor(i, color)
		strip.show()
		time.sleep(wait_ms/1000.0)

while True:
	buttons = wii.state["buttons"]
	if (buttons & cwiid.BTN_PLUS):
		colorWipe(strip, Color(255, 0, 0))  # Red wipe
	if (buttons & cwiid.BTN_HOME):
        colorWipe(strip, Color(0, 255, 0))  # Blue wipe
	if (buttons & cwiid.BTN_MINUS):
        colorWipe(strip, Color(0, 0, 255))  # Green wipe
	if (buttons & cwiid.BTN_B):
		colorWipe(strip, Color(0, 0, 0)) # Blank

	x = (wii.state["acc"][cwiid.X] - 95) - 25
	y = (wii.state["acc"][cwiid.Y] - 95) - 25

	if x < -25:
		x = -25
	if y < -25:
		y = -25
	if x > 25:
		x = 25
	if y > 25:
		y = 25

	forward_value = (float(x)/50)*2
	turn_value = (float(y)/50)*2

	if (turn_value < 0.3) and (turn_value > -0.3):
		robot.value = (forward_value, forward_value)
	else:
		robot.value = (-turn_value, turn_value)

Save the program.

Place your robot in an open space, and run the following command from inside your Pi’s robot directory.

python3 rgb_wii_remote.py

You can press the home, minus, and plus buttons to activate different lights.

Turn off the lights using the B button, and stop the program by typing CTRL-C.

How to Make an Obstacle Avoiding Robot Using Raspberry Pi

In this tutorial, I will show you how to program a Raspberry Pi-controlled wheeled robot so that it can detect and avoid obstacles autonomously (fancy word for “all by itself”). I have already done this for an Arduino-controlled robot, now let’s do it for our Raspberry Pi-controlled robot.

Special shout out to Matt Timmons-Brown for this project idea. He is the author of a really good book on Raspberry Pi robotics: (Learn Robotics with Raspberry Pi). Go check it out!

Real-world applications of obstacle avoidance in robotics can be seen in devices such as iRobot’s autonomous vacuum cleaner.

roomba_discovery

Video

Here is a video of what we will build in this tutorial.

Requirements

Here are the requirements:

  • Configure a wheeled robot so that it can detect and avoid obstacles autonomously.

You Will Need

obstacle-avoiding-robot-2-1

The following components are used in this project. You will need:

Directions

How Distance to an Object is Calculated

In order to give our robot the ability to “see” obstacles in front of it, we need to connect it up to a sensor. We will use the HC-SR04 ultrasonic sensor, a popular sensor in the do-it-yourself robotics world.

The HC-SR04 has a transmitter and a receiver. The transmitter sends out a 10 microsecond sound wave that is beyond the range of what humans are able to hear. The receiver waits for that sound wave to reflect back. The distance to the object is calculated based on the duration of the echoed sound wave, which is directly proportional to the duration the sound wave traveled (from transmitter to object to receiver).

How-ultrasonic-sensor-works-1

Image Source: Random Nerd Tutorials

hc-sr04-timing-diagram

Image Source: MCU on Eclipse

The distance is calculated based on our knowledge of the speed of sound in dry air at 20°C, which is 343 meters per second (1 mile in 4.7 seconds).

Distance in meters = Speed in meters per second x [(Time in seconds) / 2]

We divide the time by 2 because the sound wave traveled from the HC-SR04 sensor to the object and then back to the sensor. We only want to know the one-way distance from the sensor to the object, not the roundtrip distance. Therefore, in our distance calculation, time is divided by 2.

Determining What Resistors You Need

The Raspberry Pi’s GPIO pins have a working voltage of 3.3V. The HC-SR04 operates on 5V logic. If you connect the HC-SR04 directly to the Raspberry Pi, you might break your Raspberry Pi. This is because when the Echo pin (the receiver) of the HC-SR04 receives the sound wave that was originally emitted by the Trigger pin (the transmitter), the Echo pin will go from LOW (0V) to HIGH (5V). This HIGH signal is then sent to one of the GPIO pins on the Raspberry Pi. But since the GPIO pins can only handle 3.3V, you will overload the Raspberry Pi with voltage.

We must reduce the voltage produced by the ECHO pin (5V) to a level that the Raspberry Pi can handle (3.3V). In order to transform a larger voltage into a smaller voltage, we need to make a circuit known as a voltage divider. The output voltage of a voltage divider is a fraction of the input voltage.

A voltage divider uses two resistors to divide a single voltage into two smaller voltages. The voltage drop across a resistor in a series circuit is directly proportional to the size of the resistor because of a famous law, known as Ohm’s Law (V = IR; Voltage = Current x Resistance).

So, what do we need in order to build a voltage divider? All that is needed are two resistors connected in series (one right after the other) from the input voltage (the voltage you want to reduce) to the ground. You also need a jumper wire to insert in between the two resistors. This jumper wire is the output (target) voltage of the voltage divider and connects to the GPIO pin of the Raspberry Pi.

Here is a diagram of a voltage divider:

voltage-divider

Image Source: Ohms Law Calculator

The output voltage (which we want to be 3.3V) is related to the input voltage (5V in our case) via the following mathematical expression:

VoltageOut = VoltageIn x [(Resistor 2)/(Resistor 1 + Resistor 2)]         

Notice that the output voltage is the proportion of the input voltage that drops across Resistor 2.

Let’s work with some actual numbers.

  • VoltageOut = Vout = 3.3V   (This is the target voltage; the voltage we desire.)
  • VoltageIn = Vin = 5V   (This is the voltage emitted by the ECHO pin; the voltage we need to reduce)
  • Resistor 1 = R1 = 1000 Ω   (I picked this number; you can choose any reasonable number)
  • Resistor 2 = R2 = ?   (This is what we need to solve for)

Plug these number into the equation. You can work out the algebra with me by hand on a scratch piece of paper. I’ll show my work, step-by-step.

3.3 = 5 x [(R2)/(1000 + R2)]
3.3/5 = R2/(1000 + R2)          Divide both sides by 5
(3.3/5)(1000 + R2) = R2          Multiply (1000 + R2) on both sides   
(3.3/5)(1000) + (3.3/5)R2 = R2               Distributive Property
(3.3/5)(1000) = [1 - (3.3/5)]R2          Gather similar terms 
[(3.3/5)(1000)]/[1 - (3.3/5)] = R2           Divide by [1 - (3.3/5)]
1941.176 Ω = R2 

1941 Ω resistors don’t exist, but we do have a 2000 Ω (2kΩ) resistor. Let’s see what the output voltage is in this case:

  • R1 = 1000 Ω
  • R2 = 2000 Ω
  • Vin = 5V
  • Vout = ?

Remember the voltage divider equation:

Let’s solve for Vout

Vout = 5 x [2000/(1000 + 2000)]
Vout = 5 x [2000/3000]
Vout = 3.3333...        which is close enough to our target voltage

What would have happened if we used a 3000 Ω resistor instead?

Vout = 5 x [3000/(1000 + 3000)]
Vout = 5 x (3000/4000)
Vout = 3.75V       which is >3.3V and will break the Raspberry Pi

Therefore, it is always good to use a resistor for R2 that has a little bit less resistance than what you calculate mathematically. That way you protect your Raspberry Pi from damage.

Connect the HC-SR04

Make sure the Raspberry Pi is turned OFF.

Grab two long female-to-male jumper wires.

Connect the VCC pin of the HC-SR04 to the red (positive) rail of the solderless breadboard (the one connected to the Raspberry Pi).

obstacle-avoiding-robot-1-1

Connect the GND pin of the HC-SR04 to the blue (negative) rail of the solderless breadboard (the one connected to your Raspberry Pi).

obstacle-avoiding-robot-3-1

Here is the Raspberry Pi pin diagram:

rpi_pin_diagram_2-1

Using a female-to-female jumper wire, connect the Trigger (labeled Trig) pin of the HC-SR04 to pin 16 (GPIO 23) of the Raspberry Pi.

obstacle-avoiding-robot-4

Connect the Echo pin of the HC-SR04 to an empty row on the solderless breadboard. I connected it to e26.

obstacle-avoiding-robot-5

Connect a 1 kΩ resistor from a hole on the same row as the jumper wire (connected to the Echo pin) to an empty row on the solderless breadboard. I connected it from d26 to d22.

obstacle-avoiding-robot-6

Connect a jumper wire from the 1 kΩ resistor to pin 18 (GPIO 24) of the Raspberry Pi. I connected it to c22.

obstacle-avoiding-robot-7

Connect a 2 kΩ resistor from the same row as the pin 18 jumper wire (you just inserted) to the blue (negative) ground rail of the solderless breadboard. I put the resistor in cell b22 of the breadboard.

obstacle-avoiding-robot-8

Write the Python Program

Now we need to write some code so that the Raspberry Pi can use the HC-SR04 sensor.

Power up the Raspberry Pi.

Open a terminal window.

Navigate to the robot directory

cd robot

Create a new program in the Nano Text Editor, We will name it test_ultrasonic_sensor.py.

nano  test_ultrasonic_sensor.py

Here is the code.

import gpiozero  # GPIO Zero library
import time  # Time library

# File name: test_ultrasonic_sensor.py
# Code source (Matt-Timmons Brown): https://github.com/the-raspberry-pi-guy/raspirobots
# Date created: 5/28/2019
# Python version: 3.5.3
# Description: Test the HC-SR04 ultrasonic
# distance sensor

# Assign the GPIO pin number to these variables.
TRIG = 23
ECHO = 24

# This sends out the signal to the object
trigger = gpiozero.OutputDevice(TRIG)

# This variable is an input that receives
# the signal reflected by the object
echo = gpiozero.DigitalInputDevice(ECHO)

# Send out a 10 microsecond pulse (ping)
# from the trasmitter (TRIG)
trigger.on()
time.sleep(0.00001)
trigger.off()

# Start timer as soon as the reflected sound
# wave is "heard" by the receiver (echo)
while echo.is_active == False:
	pulse_start = time.time() # Time of last LOW reading

# Stop the timer one the reflected sound wave
# is done pushing through the receiver (ECHO)
# Wave duration is proportional to duration of travel
# of the original pulse.
while echo.is_active == True:
	pulse_end = time.time() # Time of last HIGH reading

pulse_duration = pulse_end - pulse_start

# 34300 cm/s is the speed of sound
distance = 34300 * (pulse_duration/2)

# Round to two decimal places
round_distance = round(distance,2)

# Display the distance
print("Distance: ", round_distance)

You can place an object a certain distance away from the sensor to check its accuracy. Let’s do 12 cm, and see what distance reading we get printed out on the terminal window.

Run the program by typing:

python3 test_ultrasonic_sensor.py
obstacle-avoiding-robot-9

If you get a reasonable reading, move on to the next section below.

Mounting the HC-SR04 Ultrasonic Sensor

Mount the ultrasonic sensor to the front of the robot using VELCRO or permanent mounting tape.

Let’s program our robot so that it avoids any objects that are less than 15 cm away from it.

Since this program will be somewhat lengthy, I will open IDLE, an Integrated Development Environment that makes developing and debugging Python code a whole lot easier than using Nano, the Linux command line text editor.

Open VNC Viewer to access your Raspberry Pi.

Click the Raspberry Pi icon in the upper left part of the screen, and go to Programming -> Python 3 (IDLE).

Go to File → New File

Here is the code for the program.

import gpiozero  # GPIO Zero library
import time  # Time library

# File name: obstacle_avoiding_robot.py
# Code source (Matt-Timmons Brown): https://github.com/the-raspberry-pi-guy/raspirobots
# Date created: 5/28/2019
# Python version: 3.5.3
# Description: A robot that avoids objects
# using an HC-SR04 ultrasonic distance sensor.

# Assign the GPIO pin number to these variables.
TRIG = 23
ECHO = 24

# This sends out the signal to the object
trigger = gpiozero.OutputDevice(TRIG)

# This variable is an input that receives
# the signal reflected by the object
echo = gpiozero.DigitalInputDevice(ECHO)

# Create a Robot object that is attached to 
# GPIO pins 17, 18, 22, and 27 of the 
# Raspberry Pi. These pins are inputs for the
# L293D motor controller.
# Objects have data and behavior that is 
# predefined by the Robot class (i.e. blueprint) 
# declared inside the GPIO Zero library.
# Change the order of the numbers inside
# the parentheses until you get the desired 
# behavior.
robot = gpiozero.Robot(left=(22,27), right=(17,18))

# Get the distance to the object
def get_distance(trigger, echo):

  # Send out a 10 microsecond pulse (ping)
  # from the trasmitter (TRIG)
  trigger.on()
  time.sleep(0.00001)
  trigger.off()

  # Start timer as soon as the reflected sound
  # wave is "heard" by the receiver (echo)
  while echo.is_active == False:
    pulse_start = time.time() # Time of last LOW reading

  # Stop the timer one the reflected sound wave
  # is done pushing through the receiver (ECHO)
  # Wave duration is proportional to duration of travel
  # of the original pulse.
  while echo.is_active == True:
    pulse_end = time.time() # Time of last HIGH reading

  pulse_duration = pulse_end - pulse_start

  # 34300 cm/s is the speed of sound
  distance = 34300 * (pulse_duration/2)

  # Round distance to two decimal places
  round_distance = round(distance,2)

  return(round_distance)

while True:
  distance_to_object = get_distance(trigger,echo)
  
  # Avoid objects less than 15 cm away
  if distance_to_object <= 15:
    robot.right() # Right for
    time.sleep(0.25) # 0.25 seconds
  else:
    robot.forward() # Forward for
    time.sleep(0.1) # 0.1 seconds
	

Save the file as obstacle_avoiding_robot.py.

Exit IDLE.

When you are ready to run the program, place your robot on the floor in a large open space.

Open a terminal window on the Raspberry Pi and type:

python3 obstacle_avoiding_robot.py

Congratulations! You have developed an autonomous robot that can avoid running into objects all on its own.

When you are done watching your robot avoid obstacles, stop running your program by typing CTRL-C.

Potential Improvements to the Robot

Right now, our robot has only one ultrasonic sensor. We could add more HC-SR04 sensors to make our robot more robust. This would require only small modifications to our original code.

How to Make a Remote Controlled Robot Using Raspberry Pi

In this post, I will show you how to make a remote-controlled robot using Raspberry Pi.

Special shout out to Matt Timmons-Brown for this project idea. He is the author of a really good book on Raspberry Pi robotics: (Learn Robotics with Raspberry Pi). Go check it out!

Video

Here is a video of what we will build in this tutorial.

Requirements

Here are the requirements:

  • Make a remote-controlled robot using Raspberry Pi and the Bluetooth-ready Nintendo Wii remote control.

You Will Need

The following components are used in this project. You will need:

Directions

Familiarizing Yourself with the L293D H-Bridge Motor Driver

You may recall in my post where we constructed the robot’s body that we had four input pins on the L293D motor controller (two for each motor). These input pins control the direction of the motors. For example, for the motor attached to the side of the motor controller connected to Inputs 3 and 4 of the L293D, we have:

Input 3Input 4Motor
HIGHHIGHOFF
HIGHLOWRotation in one direction
LOWHIGHRotation in the other direction
LOWLOWOFF

HIGH = voltage applied; LOW = voltage not applied

The four input pins set their signals from the Raspberry Pi’s GPIO (General Purpose Input/Output) pins.

To make all of this work, under the hood of the L293D motor controller, there is an H-bridge circuit. An H-bridge circuit enables a motor to be driven both forwards and backwards. It is a useful circuit in robotics.

Here is what an H bridge looks like:

h-bridge_diagramPNG

Image Source: Practical and Experimental Robotics

An H-bridge is made from electronically-controlled switches (rather than finger-controlled, such as the wall light switch in your bedroom) known as transistors.

Switch 1 and Switch 2 as well as Switch 3 and Switch 4 can never be closed at the same time. Otherwise, a bad short circuit would be created.

If Switch 3 and Switch 2 close at the same time, the motor spins in one direction. If Switch 1 and Switch 4 are closed (and Switch 2 and Switch 3 remain open), the motor will spin in the other direction because of the change in the path of the electric current.

Testing Your Robot to See If It Can Move

We need to verify that the robot can move properly. We will create a basic program in Python that will make the robot move in a box-shaped pattern three times.

First, power up the Raspberry Pi by connecting it to a wall outlet. Best practice is to connect your Raspberry Pi to a wall outlet (rather than the battery pack) when you are programming it.

Connect to your Raspberry Pi either through Putty or VNC Viewer. I’ll do VNC Viewer.

Open a terminal window. Move to the directory where you are saving your robotics projects.

remote-control-robot-1PNG

In my case, I type:

cd robot
remote-control-robot-2PNG

I then create a program in Python by typing:

nano box_bot.py
remote-control-robot-3PNG

I called the program box_bot.py because the robot will move in a shape that looks like a box.

Here is the Python code for the program:

import gpiozero  # GPIO Zero library
import time  # Time library

# File name: box_bot.py
# Author: Addison Sears-Collins
# Date created: 5/27/2019
# Python version: 3.5.3
# Description: Makes a wheeled robot move in a
# shape that looks like a box.

# Create a Robot object that is attached to 
# GPIO pins 17, 18, 22, and 27 of the 
# Raspberry Pi. These pins are inputs for the
# L293D motor controller.
# Objects have data and behavior that is 
# predefined by the Robot class (i.e. blueprint) 
# declared inside the GPIO Zero library.
# Change the order of the numbers inside
# the parentheses until you get the desired 
# behavior.
robot = gpiozero.Robot(left=(22,27), right=(17,18))

# Repeat this loop three times.
# Robot will make three boxes.
for i in range(3):
  robot.forward() # Move forward for
  time.sleep(1.0) # 1 second
  robot.right()   # Move right for 
  time.sleep(0.4) # 0.4 second
  robot.forward() # Move forward for
  time.sleep(1.0) # 1 second
  robot.right()   # Move right for
  time.sleep(0.4) # 0.4 second
  print("Box completed") # Box completed
remote-control-robot-4PNG-1

Exit the program editor by pressing CTRL-X. Make sure to save it, so press Y, then press ENTER to write (i.e. save) the file to the directory.

Shutdown your Raspberry Pi by typing:

sudo shutdown -h now
remote-control-robot-5PNG

Wait 5 seconds (or when you see the tiny green light on the Raspberry Pi is no longer illuminated), and unplug your Raspberry Pi from the wall.

Now, turn on the 4xAA battery holder.

Connect the Raspberry Pi battery pack to the Raspberry Pi.

Place the robot on a smooth floor in a wide open flat space, away from any object. You could also hold the body in your hand. Grip it by the back of the robot, being careful to keep your hands away from the wheels.

remote-control-robot-1-1
remote-control-robot-2-1

Run the box_bot.py program by opening a terminal window, going to your robot directory (or whatever directory your program is saved in) and typing:

python3 box_bot.py
remote-control-robot-6PNG

Your robot likely won’t make perfect boxes and might not even make fewer than three boxes (due to the weight the motors are pulling). That is fine. The key to this exercise is to just make sure the robot can go forwards and make a right turn.

If you need to stop the robot at any time, you can press CTRL-C.

If you see that your robot is not moving like it should, switch the order of the numbers inside the parentheses on this line:

robot = gpiozero.Robot(left=(22,27), right(17,18))

You can also edit the sleep time in your program. Also check to make sure the wiring is exactly like I indicated in my wheeled robot post.

If your robot isn’t moving at all, don’t worry, robots rarely work as they should the first time around. Keep tinkering with the code until you get the desired result. Take your time. No need to hurry.

Setting up the Nintendo Wii Remote Control

remote-control-robot-3-1

Power up your Raspberry Pi.

Open a terminal window. Type in the following command, and wait while it updates:

sudo apt-get update

The Raspberry Pi has a list of all the software to packages that are available for installation. If you don’t run sudo apt-get update before installing a new software package, you might end up with an outdated piece of software.

Install the Bluetooth package.

Bluetooth is a wireless technology that enables data to be sent back and forth over short distances using radio waves.

sudo apt-get install bluetooth
remote-control-robot-7PNG

Bluetooth might already be installed on your Raspberry Pi. If it is, you will get a message saying so.

Download the open source cwiid Python library that enables the Raspberry Pi to receive information from the remote control.

Type this in the terminal window:

git clone https://github.com/azzra/python3-wiimote
remote-control-robot-8PNG

Install four additional software packages:

sudo apt-get install bison flex automake libbluetooth-dev
remote-control-robot-9PNG

Type Y and press ENTER to continue. Wait while the software installs on your Raspberry Pi.

Move to the python3-wiimote directory.

cd python3-wiimote

Compile the python3-wiimote source code by typing in these commands, one by one in order:

remote-control-robot-10PNG
aclocal
autoconf
./configure
make 
sudo make install

The cwiid library is now installed on your Raspberry Pi.

Move to the robot directory:

cd
cd robot

Create a new Python program.

This program enables the Nintendo Wii remote control to make the robot move forwards (UP button), backwards (DOWN button), to the right (RIGHT button), to the left (LEFT button), and stop (B button).

nano wii_remote.py

Here is the Python code:

import gpiozero  # GPIO Zero library
import cwiid  # Wii library

# File name: wii_remote.py
# Date created: 5/27/2019
# Python version: 3.5.3
# Code source (Matt-Timmons Brown): https://github.com/the-raspberry-pi-guy/raspirobots
# Description: This program enables the
# Nintendo Wii remote control to make a robot
# move forwards (UP), backwards (DOWN), to the
# right (RIGHT), to the left (LEFT), and stop
# (B).

# Create a Robot object that is attached to 
# GPIO pins 17, 18, 22, and 27 of the 
# Raspberry Pi. These pins are inputs for the
# L293D motor controller.
robot = gpiozero.Robot(left=(22,27), right=(17,18))

print("Press down and hold buttons 1 and 2 on",
      " the Nintendo Wii remote.")
print(" ")
print("Hold down until you see a success message.")
print("If unsuccessful, try again.")

# Create a Wiimote object and assign it to the
# variable named wii. Bluetooth handshake
# is performed between the Wii remote
# and the Raspberry Pi
wii = cwiid.Wiimote()

print("Wiimote is Ready!")

# Turn on Wiimote reporting to enable the Python
# code to receive input from the Wiimote.
wii.rpt_mode = cwiid.RPT_BTN

while True:
  # Save the value of the button that was pressed
  # into a variable named buttons
  buttons = wii.state["buttons"]

  # Bit-wise AND operation. Returns 1 in each
  # bit position for which buttons and
  # cwiid.BTN_XXXX are ones.
  if (buttons & cwiid.BTN_LEFT):
      robot.left()
  if (buttons & cwiid.BTN_RIGHT):
      robot.right()
  if (buttons & cwiid.BTN_UP):
      robot.forward()
  if (buttons & cwiid.BTN_DOWN):
      robot.backward()
  if (buttons & cwiid.BTN_B):
      robot.stop() 

Press CTRL-X and save the program.

Run the Program

Make sure you Wii remote control has AA batteries in it.

Turn on the Wii remote control by pressing the Power button.

Power up your Raspberry Pi, and go to a terminal window. Open the robot directory:

cd robot

Run the wii_remote.py program.

python3 wii_remote.py

Press down the 1 and 2 buttons on the Wii remote at the same time and hold until you get a message that a Bluetooth connection has been made between the Raspberry Pi and the Wii remote control.

Bluetooth can be tricky to deal with on the Raspberry Pi, so if you fail to make the Bluetooth connection immediately, try again. Try to press and hold down 1 and 2 as soon as you run the code.

Once a connection has been made and assuming your robot is on the floor, press the arrow buttons on the remote control to drive your robot around.

The B button (trigger finger) enables you to stop the robot.

Typing CTRL – C in the terminal window stops the program.

Typing sudo shutdown – h now shuts off the Raspberry Pi. It is good practice to wait five seconds after you type this command before disconnecting the Rapberry Pi’s power.

To restart the Raspberry Pi, you just need to plug it into a power supply again.

Controlling the Speed of the Robot

You can control the speed of the robot by entering a number between 0 and 1 in the parentheses of the code I presented in the previous section. 0.50, for example, means 50% of full speed.

robot.forward(0.50)

GPIO pins in the Raspberry Pi can only be in two states, ON (+3.3 V) or OFF (0 V). By using a procedure known as pulse-width modulation (PWM), the GPIO pins switch ON and OFF so fast that the motor only perceives the average voltage. This technique enables the motor to have variable speeds as opposed to just two speeds (full speed and no speed at all).

We can also use the accelerometers of the Nintendo Wii remote to control the speed and direction of the robot. An accelerometer measures acceleration. And since the robot moves on only one plane, the x-y plane, we can move the Nintendo Wii remote forwards and backwards, and get the robot to respond to those actions.

For example, we can pitch the Wii remote forward (in the positive x-direction) to get the robot to move faster in the forward direction.

To make this happen, write the following program on your Raspberry Pi, and save it to your robot directory. You can name it wii_remote_variable.py.

import gpiozero  # GPIO Zero library
import cwiid  # Wii library

# File name: wii_remote_variable.py
# Code source (Matt-Timmons Brown): https://github.com/the-raspberry-pi-guy/raspirobots
# Date created: 5/27/2019
# Python version: 3.5.3
# Description: This program enables the
# Nintendo Wii remote control to make a robot
# move forwards, backwards, to the
# right, to the left using the accelerometer.

# Create a Robot object that is attached to 
# GPIO pins 17, 18, 22, and 27 of the 
# Raspberry Pi. These pins are inputs for the
# L293D motor controller.
robot = gpiozero.Robot(left=(22,27), right=(17,18))

print("Press down and hold buttons 1 and 2 on",
      " the Nintendo Wii remote.")
print(" ")
print("Hold down until you see a success message.")
print("If unsuccessful, try again.")

# Create a Wiimote object and assign it to the
# variable named wii. Bluetooth handshake
# is performed between the Wii remote
# and the Raspberry Pi
wii = cwiid.Wiimote()

print("Wiimote is Ready!")

# Turn on Wiimote reporting to enable the Python
# code to receive input from the Wiimote.
wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC

while True:
  # Store the x and y values of the accelerometer
  # into variables and scale to a number between
  # 95 and 145 and then -25 and 25. Negative
  # numbers mean backwards movement.
  x = (wii.state["acc"][cwiid.X] - 95) - 25
  y = (wii.state["acc"][cwiid.Y] - 95) - 25

  # Error checking to keep values in the interval
  # -25 to 25
  if x < -25:
    x = -25
  if y < -25:
    y = -25
  if x > 25:
    x = 25
  if y > 25:
    y = 25

  # Calculate a forward and turn value between -1
  # and 1
  forward_value = (float(x)/50)*2
  turn_value = (float(y)/50)*2

  # This code ensures the robot is not impacted
  # by slight movements in the remote control
  if (turn_value < 0.3) and (turn_value > -0.3):
    robot.value = (forward_value, forward_value)
  else:
    robot.value = (-turn_value, turn_value)

By holding the remote control sideways, with the Nintendo Wii’s direction pad (the cross on the remote) on your left, you can tilt and pitch the robot to move like you want it to.

Run the program (make sure the Raspberry Pi is not plugged in to a wall outlet, but rather the battery pack) by typing in the following command while inside your Raspberry Pi’s robot directory:

python3 wii_remote_variable.py

That’s it! At this point, your robot should be responding to your actions on the remote control. Move it forward, pitch it backward, and observe how your robot responds!

Press CTRL-C at any time in the terminal to stop the program.