Raspberry Pi Robot

August 19, 2017

Intro:

Recently I saw the Pixar movie WALL-E with my son who is almost 6. During the movie I was thinking it would be nice to make a robot my self.
I did some Raspberry Pi projects in the past that are work related, played around with some components, GPIO inputs and outputs.
This got me thinking “would it be possible to make a robot with a Raspberry Pi”. Again I turned to Google to do some research, and found allot of info about building a robot with a Raspberry Pi.
I turned to my son and said: “Lets build a robot together”. He was enthusiast about it but has no clue what it will do or what it is :-) .
Here our version of a Raspberry Pi Robot (Part 1).

What this will do:

I have allot of plans what it should be doing, but don’t know if I can realize it, so this may change if all is finished.
1) It must be able to drive on its own.
2) Detect motion, and do an action (Take a picture, drive towards it …).
3) Do object avoidance.
4) Connect to the wifi network of my home.
5) Take pictures and capture video.
6) Do face recognition. (We will see how this turns out.).
7) Drive to a docking station to charge itself.
This is all in my mind at the moment, have no clue yet how I’m going to do this.

Things you will need:

1x Raspberry Pi 2
1x PIR motion sensor
1x IR Distance sensor
1x Raspberry Pi camera board
1x USB WiFi dongle
1x DC&Stepper motor HAT
1x Set of wires
1x Battery holder
1x USB battery pack
1x SD Card
1x Raspberry Pi 2 case
1x Tank chassis
1x ADC Chip
1x Chip socket

Prepare the Pi:

First of all we need to install Raspbian on the Pi. This is a custom img of Debian Linux.
You can download it from the Raspberry Pi Site. Instructions how to install are there to.
Once all is finished you can connect your Ethernet and boot it up. The Pi will receive a DHCP address from your router, just look for it and connect with SSH. A handy tool for connection to an SSH server is Putty for example.

The Default username and password are:
Username: pi
Password: raspberry
I recommend to change this. Also if you do a

 sudo -s 

You get root access to the Pi, change also this password.
After you changed the password you need to update and upgrade the system.

sudo apt-get update
sudo apt-get upgrade 

After the system is upgraded we can start to do some general configurations.
Enter the following command and go trough the these options:
1-Expand the file-system
4-International options
5-Enable Camera
8-Advanced options
A2- Host-name

sudo raspi-config

When you have made all these changes we can proceed, and set a static IP for better management.
Open your network configuration file and set the correct parameters.

sudo vi /etc/network/interfaces

Start Soldering this HAT:


Insert the 40 pin connector into the board and start soldering.
Afterwards you can solder the blocks to the board. They come with 3x2pins and 2x3pins.
Slide a 2 pin and a 3 pin together to get a total of 5 pin block.
If you don’t know how to solder, check the Adafruit Site.

It has a good explanation on how to tackle this.
I’m pretty satisfied with my result.
 

 

Install those drivers to drive:

For every piece of hardware you connect to the Pi, you have to install the additional drivers.
Boot-up your Pi and log in.
First we need to install the I2C bus, With this your Raspberry can speak to other boards.
To debug and load it to your code later we run the following commands.

sudo apt-get install python-smbus
sudo apt-get install i2c-tools

We also need to enable this in the Raspbian Kernel, this is done by running the Raspberry config script.

sudo raspi-config


Go to The advanced options, and enable the I2C module. Set it to activate and start by default.
Reboot the Pi as suggested by the script, afterwards log in again.

Now we have to do some file editing to make sure everything is loaded correctly.
I use VI for editing files, it’s just a habit I guess.
Here some series of commands that need to be checked:

sudo vi /etc/modulers

Add the following 2 lines to the file:

i2c-bcm2708 
i2c-dev

Go to the following directory and do some more changes:

sudo vi /boot/conf.txt

Add these 2 lines to the config:

dtparam=i2c1=on
dtparam=i2c_arm=on

Reboot the Pi and lets test if we see the board.
Mount your HAT on top of the Raspberry(disconnect the power first), log in and type the following command:

sudo i2cdetect -y 1

As you can see with mine the addresses used are 0x60 and 0x70. The I2C bus is working fine.
Now lets install those drivers and library’s.

Normally GIT should be installed, if not install it the same way you install all the other modules, “sudo apt-get install git”.
We are going to copy some files from the Adafruit git repository. Go to the directory where you want to put the files.
in my case they are in the pi home directory.

git clone https://github.com/adafruit/Adafruit-Motor-HAT-Python-Library.git

Before we install these library’s we need to install the Python development kit.

sudo apt-get install python-dev

after installing this, go to the directory you just cloned from git and install the module.

sudo python setup.py install

Bingo, our motor Hat board is ready to go.
On to the next module.

 

Installing a dongle:

To give our robot access to the network, we give it a WiFi dongle, as simple as that :-)
First of all we need to do some configurations, so don’t plug it in yet.

sudo vi /etc/network/interfaces

Then modify the part where “wlan0” is the following way:

auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
 wpa-ssid "your ssid"
 wpa-psk "your password"
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

Disconnect the power and insert the dongle.
With the following command you can check if your wlan interface has got an ip-address.

ifconfig wlan0

Now your pi has WiFi network connection enabled. GREAT!

 

Connect My eye please:

I think our robot needs the ability to see, So here we are going to connect the Camera.
In Part 1 we already enabled the cam trough rasp-config, so that will be fine.

Plug in the Camera onto the Raspberry pi by opening the camera connector (the one closest to the Ethernet port), and plugging in the cable with the blue side towards the Ethernet port. After this is done you can push down the white lock so it is closed.
Boot up the Pi and lets proceed.
Here a command to test your camera:

raspistill -o image.jpg

Your camera is done and ready to be used.

 

Is that motion I detect?

As you can see on the picture, there are 3 wires.
Red = +
Black = Ground
Yellow = Input

We have to solder some wires together so you can connect your motion sensor onto the Pi.
Take the Wires you bought from Adafruit and cut of the male connector and strip it.
For easy use, take the same colours.

For now we will use these wires to do some testing. Later if we put everything together we have to connect it proper to the motor HAT, as it uses all the pins.
Here a schematic of the pins on the Raspberry Pi2, if you hold your Pi with the Ethernet port facing down, the picture should match.

Connect the Red wire to Pin 02 (5v)
Connect the Black wire to Pin 06 (ground)
Connect Yellow to Pin 26 (GPIO 07)

Put the 3pin connector into the PIR like on the picture:

This should do the trick, now boot up your Pi and log In.

Go to the home folder and make a new directory for testing. Here we will put our testing code.
Open VI and make a new python file with the code below.


#!/usr/bin/python
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)		# Use BCM GPIO references instead of physical pin numbers
GPIO_PIR = 7  			# GPIO7
GPIO.setup(GPIO_PIR,GPIO.IN)	# Set pin as input

Current_State  = 0
Previous_State = 0
 
print "(CTRL-C to exit)"

try:
  # Loop until PIR output is 0
  while GPIO.input(GPIO_PIR)==1:
    Current_State  = 0
 
  print "Ready"
 
  # Loop until users quits with CTRL-C
  while True :
 
    # Read PIR state
    Current_State = GPIO.input(GPIO_PIR)
 
    if Current_State==1 and Previous_State==0:
      # PIR is triggered
      print "Motion detected!"
      # Record previous state
      Previous_State=1
    elif Current_State==0 and Previous_State==1:
      # PIR has returned to ready state
      print "Ready"
      Previous_State=0
 
    # Wait for 10 milliseconds
    time.sleep(0.01)
 
except KeyboardInterrupt:
  print "Quit"
  # Reset GPIO settings
  GPIO.cleanup()

After you saved your file “motion.py” you can run and test it with the following command:

sudo python motion.py

Try to move your hand before the sensor and see if it works.
Your motion sensor is ready.

 

How Far are you?

We have arrived to our final module we will implement, so lets set it up.

The IR distance sensor is an analogue devise so we need the Analogue Digital Converter, the ADC to convert it to a readable value.
The MCP3008 chip is perfect for this. We can connect up to 8 analogue devices to it and read their values. At the moment we only connect our distance sensor.
Place the chip into the bracket and onto a breadboard so we can test how it works.

Make sure the chip is in the middle of the board where the separation is. this way we can connect our pins to the sensor and the Raspberry.
Here A Diagram of the Chip, notice the little cap on one end.

The explanation of the chip pins:
Vdd = Power 3.3V
Vref = Analogue voltage reference (You need to know from witch to witch voltage your analogue device goes.) our case 5V
AGND = analogue ground
CLK = clock
Dout = Data out
Din = Data in.
CS/SHDN = chip select
DGRND = Digital ground
CH0 – 7 = analogue inputs.

Lets connect it to the Raspberry and test some code.
VDD          > 3.3v
Vref           > 5v
AGRND    > GND
CLK           > GPIO 18
Dout          > GPIO 23
Din             > GPIO 24
CS/SHDN > GPIO 25
DGND        > GND

Connect the black wire of the sensor to the GND of the raspberry, the Red to the 5v and the white one to CH0 of the ADC.

Now everything is connected log in to the pi and go to the testing directory.
Here some code to test if it works.
Create the file with:


sudo vi distance.py

 


#!/usr/bin/env python
import time
import os
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
DEBUG = 0

# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
        if ((adcnum > 7) or (adcnum < 0)):
                return -1
        GPIO.output(cspin, True)

        GPIO.output(clockpin, False)  # start clock low
        GPIO.output(cspin, False)     # bring CS low

        commandout = adcnum
        commandout |= 0x18  # start bit + single-ended bit
        commandout <<= 3    # we only need to send 5 bits here
        for i in range(5):
                if (commandout & 0x80):
                        GPIO.output(mosipin, True)
                else:
                        GPIO.output(mosipin, False)
                commandout <<= 1
                GPIO.output(clockpin, True)
                GPIO.output(clockpin, False)

        adcout = 0
        # read in one empty bit, one null bit and 10 ADC bits
        for i in range(12):
                GPIO.output(clockpin, True)
                GPIO.output(clockpin, False)
                adcout <<= 1 if (GPIO.input(misopin)): adcout |= 0x1 GPIO.output(cspin, True) adcout >>= 1       # first bit is 'null' so drop it
        return adcout

SPICLK = 18
SPIMISO = 23
SPIMOSI = 24
SPICS = 25

GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)

# 10k trim pot connected to adc #0
potentiometer_adc = 0;

last_read = 0       # this keeps track of the last potentiometer value
tolerance = 3       # to keep from being jittery we'll only change
                    # volume when the pot has moved more than 5 'counts'

while True:

        # we'll assume that the pot didn't move
        trim_pot_changed = False

        # read the analog pin
        trim_pot = readadc(potentiometer_adc, SPICLK, SPIMOSI, SPIMISO, SPICS)
        # how much has it changed since the last read?
        pot_adjust = abs(trim_pot - last_read)

        if DEBUG:
                print "trim_pot:", trim_pot
                print "pot_adjust:", pot_adjust
                print "last_read", last_read

        if ( pot_adjust > tolerance ):
               trim_pot_changed = True

        if DEBUG:
                print "trim_pot_changed", trim_pot_changed

        if ( trim_pot_changed ):
                set_volume = trim_pot #/ 10.24           # convert 10bit adc0 (0-1024) trim pot read into 0-100 volume level
                set_volume = round(set_volume)          # round out decimal value
                set_volume = int(set_volume)            # cast volume as integer

                print set_volume

                if DEBUG:
                        print "set_volume", set_volume
                        print "tri_pot_changed", set_volume

                # save the potentiometer reading for the next loop
                last_read = trim_pot

        # hang out and do nothing for a half second
        time.sleep(0.5)

run the code with:


sudo python distance.py

Now you should read values from 200 the far to 900 the closest.
Well this is how we connect our distance sensor to the Pi.

 

Unpacking is fun:

When you finally get your package, you notice there are allot of screws and bolts, with metal parts. And there is no plan to assemble it.
So first things first and lets organize everything, part by part, so we get an overview.

There are to many screws, short, long ,thick and thin ones. So Sort them all out on the table.

Use the short screws to attach the metal plate together.

Now, attach the motor’s to the frame, find the correct screw and holes.

Find the metal cylinders and place them over the motor end. Lock them in place with the little bolts.

Assemble all the wheels like on the picture.

Take the long bolts and place them in the wheels. Then screw on a little screw, then the plastic cylinder.
Then you can screw them onto your frame.

Put your frame upside down and put on the tracks, afterwards you can mount the last wheel onto the frame.

Now we have our tank chassis ready to be used.

As last we solder 2 wires onto each motor. There should be a little plate where you can solder your positive and ground wires to it.
Our chassis is ready to be used.