Raspberry Pi & Python Powered Tank

pi python powered tank

The title pretty much explains this project- it’s a tank, that can shoot BBs – powered by a Raspberry Pi and Python Code.

It’s pretty awesome.

This is part one of a two-parter and handles all of the hardware and wiring and a Python script for test firing the engines.

Click here to see Part 2 of this project where I get a live video stream and buttons to control the tank into a web UI!

pi tank 24

The awesome finished product. I’m going to use the word awesome a lot in this article.

As with my other projects, I’ll try to keep things simple and limit the tools required – in this case, a screwdriver, craft knife, and a soldering iron is all you should need.

Speaking of my other projects, check them out:

Tank Tour

The boxed tank

The boxed tank

This is the remote-controlled tank I will gut and turn into a rolling example of hacking prowess.

You can probably find this exact model on your preferred online marketplace; they seem pretty ubiquitous. This one cost about 15 bucks.

Unboxed tank

Unboxed tank

Here it is unboxed.

Where to load the BBs

Where to load the BBs

Here’s where you can load in some plastic beads for it to shoot.

Thank underside

Thank underside

This is the underside, with a couple of screws holding it together.

Disassembled tank

Disassembled tank

With the screws removed, it disassembles pretty easily. At the front is the gun assembly – a motor is spun to flick plastic beads out.

The original brains of the tank.

The original brains of the tank.

The original brains of the tank are shown above.

Unfortunately, this particular tank seems to have suffered some water damage. The box had fallen apart, and the tank didn’t really respond to the included remote, but eventually, it came to life with a bit of coaxing.

Other materials

In addition to the tank, you’ll need

  • Raspberry Pi
  • Raspberry Pi power supply/battery
  • Soldering Iron
  • Assorted lengths of wire
  • Veroboard
  • L293D chip
  • Either a webcam or Raspberry Pi camera if you want to be able to live stream from the tank

Setting up the Pi

First up, you’ll need to get your Raspberry Pi up and running with an Operating System, connected to your WiFi Network, with a static IP and SSH enabled.

There is a new tool- the Raspberry Pi Imager-  which can be downloaded from:

https://www.raspberrypi.org/software/

Which will set up an SD card with Raspberry Pi OS, ready to go.

I recommend using Raspberry Pi OS Lite as this project doesn’t require a full desktop interface.

We’ve covered the other steps in the below articles:

pi tank 09

Setting up the Pi with an external monitor and keyboard.

Gutting the Tank

Gutted tank

Gutted tank

The existing circuit board was removed, as was any extra plastic mounting for it that might get in the way. Wires were reinforced and extended to make things easier to work with.

Drives are labeled L/R as I kept getting left and right mixed up with I spun the tank around because I’m an idiot.

Early Experiments

Initially, I tried to use some spare bits and pieces to drive the tank from the Pi. I won’t detail what and how, as it’s irrelevant, and someone might try and follow those examples.

Long story short, things either didn’t work or got very, very hot. I don’t want a mobile fire hazard.

Early Experiments

Early Experiments

Early Experiments

Early Experiments

L293D To The Rescue

The correct part for the job is the L293D chip. This chip is specifically designed for driving up to two DC motors. A pack of 5 was a few dollars online.

The chip supports 3v to 18v – the 4 AA batteries in the tank will supply 6v, so it should be spot on.

The L293D chip in all its glory.

The L293D chip in all its glory.

Printed pinouts

Printed pinouts

I’ll usually print out pinouts for whatever hardware I’m wiring up so that I can scribble notes on it. Things can get crowded once all of the wires are in place, so a reference is useful.

L293D wired up

L293D wired up

L293D wired up and ready to roll. See below for how this was done.

L293D wiring

L293D wiring

The gun is now glued into the lid to keep it out of the way.

Everything wired together

Everything wired together

Everything is wired together and ready to close up (sort of).

As the L293D only supports driving two motors, a second chip has been added to deal with the gun.

Pinout

I’ll skip a circuit diagram as it just looks messy – here’s what Raspberry Pi pin is wired to what L293D pin.

L293D Pin Raspberry Pi Pin GPIO Pin Number
en1 22 GPIO 25
in1 18 GPIO 24
in2 16 GPIO 23
# out1 to left motor
# out2 to left motor
en2 23 GPIO 11
in3 21 GPIO 9
in4 19 GPIO 10
#out3 to right motor
#out4 to right motor

I’ve also wired up a second L293D to power the gun:

L293D Pin Raspberry Pi Pin GPIO Pin Number
en1 8 GPIO 14
in1 10 GPIO 15
in2 12 GPIO 18
# out1 to gun motor
# out2 to gun motor

Pin 8 on both L293D chips should run to the tank’s AA battery compartment.

Pins 4, 5, 12, 13 of both L293D chips will be attached to a common ground.

The Pi should also have a ground pin attached to this common ground, as should the AA battery compartment’s ground. Everything should share the same ground!

The wires’ polarity going from the L293D to the motor can be arranged any way – reversing the wires will just make the motor spin in the opposite direction.

Assembly ( It won’t fit )

Pi with the wires and a battery pack attached

Pi with the wires and a battery pack attached

Here’s the Pi with the wires and a battery pack attached. I’ve run the wires through the top of the tank turret where there was a big enough gap.

Battery and Pi secured to the tank

Battery and Pi secured to the tank.

Double-sided tape keeps the battery and Pi secured to the side of the turret.

pi tank 21

And with a bit of squeezing, everything seems to fit. Looks pretty awesome, right?

pi tank 22

USB hub and webcam addition

USB hub and webcam addition

Throw a USB hub and webcam on the back.

The tank is ready!

The tank is ready!

Ready to roll!

Loose connections

Loose connections

…Or not. Only one motor would spin. Squeezing everything inside the tank was just bending pins and making things come loose.

Stripboard to the Rescue!

I needed to reduce the size of the internal circuitry. That blue prototyping board was too chunky, and the wires come loose from it too easily.

The solution? Stripboard!

Stripboard is a circuit board with long rows of copper that you can scratch off to make your own circuit designs.

Stripboard

Stripboard

Here’s mine marked out. The two unbroken rows towards the middle are for the ground pins on the two L293Ds, and I’ve drawn where the middle of the chips will lay on the board so those sections can be removed, creating short rows of solder points for each pin on each chip.

If this makes no sense, hopefully, seeing it in action will.

Prepared stripboard

Prepared stripboard

The easiest way to break the traces is simply to bore out the holes with a knife. Bore enough, and the trace will be completely severed.

Chips and wires mounted and soldered

Chips and wires mounted and soldered.

The chips are mounted on the board and soldered down. Wires can then be soldered to the copper traces attached to each pin, which then run to the Pi and motors.

pi tank 29

More compact and much tidier!

Stripboard underside

Stripboard underside

Here’s a look at the underside, where the wires and pins are soldered. The two rows which are attached to the ground pins are bridged with solder.

Bit of a mess, but it works!

Reassembled (Fits)

Finished tank

Finished tank

Now everything fits, and everything works when closed up.

AA batteries powering the tank's motor

AA batteries powering the tank’s motor

The motors receive their power from AA batteries, not the Pi.

Installing Python Dependencies

With all of that done, power up your Pi and SSH to it. We’ll install the following dependencies using apt:

sudo apt install python3 python3-pip git

Then install the required Python packages using pip:

sudo pip3 install RPi.GPIO

The Python dependencies should be installed using sudo. Eventually, we want to be able to run a web server for remote control from a browser, so they will need to be available to the root user.

Next, set up a directory for the Python code and create a file in it for the test script:

mkdir pi_tank
cd pi_tank

Now we need a Python library to interact with the L293D chips. The most up-to-date code for this library is on Github, so let’s clone the repository and install it from there:

git clone https://github.com/jamesevickery/l293d.git
cd l293d
sudo python3 setup.py install
cd ..

This will install the package and return us to the pi-tank directory.

Python Code

Here’s the python code to set up the GPIO pins and test fire each motor. Create the file tank.py and paste the code in there using the nano text editor:

nano tank.py

Comments in the code should do most of the explaining:

# This script tested for use with Python 3

# Import required libraries
import l293d.driver as l293d

# Documentation for the l293d library
# https://l293d.readthedocs.io/en/latest/

# Use BOARD pin numbering - ie the position of the pin, not the GPIO number.  The L293D doesn't seem to like using BCM numbering
l293d.Config.pin_numbering = 'BOARD'

# Here's a labelled photo of the Pi Zero GPIO Pinout
# https://i.stack.imgur.com/yHddo.png

# Define variables for the pins

en1 = 22 # GPIO 25
in1 = 18 # GPIO 24
in2 = 16 # GPIO 23
# out1 to left motor
# out2 to left motor

en2 = 23 # GPIO 11
in3 = 21 # GPIO 9
in4 = 19 # GPIO 10
#out3 to right motor
#out4 to right motor

#Second l293d for GUN
g_en1 = 8 # GPIO 14
g_in1 = 10 # GPIO 15
g_in2 = 12 # GPIO 18
# out1 to gun motor
# out2 to gun motor

# The following code sets up and tests the l293d drivers

try:
 
   motorLeft = l293d.DC(en1, in1, in2, force_selection=True)
   motorRight = l293d.DC(en2, in3, in4, force_selection=True)
   motorGun = l293d.DC(g_en1, g_in1, g_in2, force_selection=True)

   while True:
        print("Testing left motor...")
        motorLeft.clockwise(duration=3)
        motorLeft.anticlockwise(duration=3)

        print("Testing right motor...")
        motorRight.clockwise(duration=3)
        motorRight.anticlockwise(duration=3)

        print("Testing gun motor...")
        motorGun.clockwise(duration=3)
        motorGun.anticlockwise(duration=3)
  
except:
    # If there is an error, make sure we clean up any pin assignment
    l293d.cleanup()

# Make sure this runs on close so that the GPIO pins are available for re-use
l293d.cleanup()

# End of file

Test Run [With Video]

Let’s get this tank rolling. Run the following on the Pi from the pi_tank directory:

python3 tank.py

Success!

It’s a bit sluggish. I’m chalking this up to the weight of the Pi and the camera, and the previously mentioned water damage, which was probably not healthy for the motors.

Still, it works, and it’s awesome.

In the Next Episode

Powering the tank with the Pi and Python was a success – now to add a web interface with buttons to send commands and a live video stream – I’ll check back with this in a couple of weeks!

Click here to see Part 2 of this project where I get a live video stream and buttons to control the tank into a web UI!

SHARE:
nv-author-image

Brad Morton

I'm Brad, and I'm nearing 20 years of experience with Linux. I've worked in just about every IT role there is before taking the leap into software development. Currently, I'm building desktop and web-based solutions with NodeJS and PHP hosted on Linux infrastructure. Visit my blog or find me on Twitter to see what I'm up to.

Leave a Reply

Your email address will not be published. Required fields are marked *