Pi2 Tank with Adafruit MotorHat

Please note:

“PS3, Playstation” is a registered trademark of Sony Computer Entertainment Inc.

PiBorg is a registered trademark of Freeburn Robotics Limited

Adafruit is a registered trademark of Adafruit Industries, LLC

LEGO®is a trademark of the LEGO Group of companies

Dremel is a trademark  of Dremel, a division of Robert Bosch Tool Corporation,

None of the above companies sponsor, authorize or endorse this site.


Images may be “double clicked” for a larger size.

Disclaimer: Let me state that while I have made every effort to be accurate there could be errors so if I cause anyone additional expen$e/lost time let me apologize now.  Proceed at your own discretion and read twice or post questions.


    • Raspberry Pi 2
    • Ubuntu’s Mate OS – for Pi2
    • PS3 Game Controller – optional
    • Bluetooth USB dongle – optional
    • Adafruit DC & Stepper Motor Hat – Stepper Motor Hat here
    • Micro SD Card – 16 Gig or greater rated as Class 10 (a measurement of card’s performance)
    • a Tank chassis with motors (there are many other chassis at this site) – motors must be rated between 6~12 volts (my tank chassis came w/2 motors).  Always inquire into the motor specs when ordering to be sure they are compatible with the HAT.  Some chassis come with 24 volt motors.  Please note that this applications code and drivers do not allow the use of stepper motors.
    • 8 X AA – battery holder – this will provide power to the chassis motors because the PI2 cannot do this
    • wall plug power for Pi2 – used to provide power during static testing
    • wall plug power for motors – used to provide power during static testing
    • various tools/pieces like a soldering iron (Motor Hat requires some soldering)
    • PC Mother Board standoffs (M3 for tank chassis and M2.5 for Pi2 and Hat)  IMG_0306(standoffs are optional),
    • Plexiglas – optional
    • Lego bricks/blocks/baseplate/plates
    • USB camera – I used a Logitech – NOTE:  the small Pi camera is not compatible with the Ubuntu Mate OS
    • Hex Key set – metric
    • hobby file set
    • small wrench set – got one at Sears
    • Dremel drill press – for drilling into Plexiglas  – optional
    • Pi2 templates for drilling holes
    • lock washers – optional if you dare
          • IMG_03411

My tank chassis arrived from the above provided link today.  It took about two weeks from China.  Not bad.  Here is how it looked (some assembly required):


I.  Assembling the tank chassis.

In my case the vendor I purchased the tank chassis from allows so many days in which to file a dispute.  Therefore it becomes imperative that you assemble the crawler as soon as possible to ensure that all the components are there:  screws, wheels, motors etc.  I have assembled this crawler per the steps below and all parts where present.  I did “add” components because I wanted some extra wiggle room to expand the “crawler”.  Most noticeably I added brass M4 standoffs and used them in place of 4 of their nuts.  I will also be adding a Plexiglas platform to give me extra storage on the platform.

Here we go:

This is how the kit arrived.  In “parts”.  No instructions.  Hopefully this post will help you assemble this crawler with minimum fuss. IMG_0296
Assemble the crawler platform:  3 parts.  Use their screws and in my case I used brass standoffs in place of their nuts.  You can see the screws, nuts and the standoffs that I used to the right. IMG_0304


IMG_0305Below an assortment of brass standoffs and screws/nuts.  These are M3s.

Note that because I am going to use the brass standoffs the screws are inserted into the holes from under the frame, the standoff is then screwed onto this screw.  Do this for all 4 rail mounting points.  When done it will look like the last picture in this row.You can add lock washers during this part of the build.  I used the Blue Hawk/Hillman #6 washers here to secure the standoffs to the base plate.  Pictures at right. IMG_0309IMG_0308IMG_0310IMG_0313IMG_03471IMG_03481
Install the Wheels:  The front of the crawler frame has these horizontal holes shown at right.  I believe they are to help with installing the track after the wheels are mounted.  The six wheels are pretty much the same with wheels 7 and 8 being the drive/sprocket wheels.  Aside from the drive/sprocket wheels they all mount the same.  There are round holes drilled into the frame to accept a bolt that is inserted into the wheels and held in place by a nut.  Pay attention to the picture showing 2 wheels installed and NOTE the nut configuration.  There are two nuts installed on each wheel.  The nut closest to the wheel and the nut and lock washer on the other side of the rail which when tightened pinches against the outside nut and holds everything in place.  I added lock washers to these wheel mounts on the inside of the rail to ensure that they do not come loose (this was done on the second built so some pictures may not show them).  We are going to install all BUT the two front wheels, the ones that go into the horizontal/oval holes.  These wheels will be installed during track installation.  Its important to note the single wheel that I am holding.  It shows a bolt inserted through the wheel with a single nut in place.  You Must a.) ensure that this bolt is as far through the wheel as possible, and b.) adjust this single nut to allow a small gap between it and the plastic hub.  This will allow the wheel to not be pinched when the other nut and lock washer are tightened.   Note also that by adjusting the outside nut (the one nearest the wheel) you are able to align each wheel with the previous one.  Yes they must align or the tracks will bind.  And if the nut nearest the wheel does not provide a small gap then the wheel will not turn when the inside nut/lock washer are tightened.  When all wheels are installed we need to install the drive/sprocket wheels. IMG_0314IMG_03512


Install the drive sprocket wheels:  First we need to install the motors and secure them to the side rails.  Use 3 supplied screws to attach the motors using an Allen wrench.  Next attach the drive/sprocket wheels to the motors.  STOP.  You must do the following:
1.  using a Hex wrench (1.5 mm)carefully back out the set screw on each drive/sprocket wheel so it is not protruding into the motor shaft opening.  Also be careful not to loose these small screw or you will be….
2.  Gently slide the drive/sprocket wheel onto each motor shaft paying attention to the location of the set screw and the flat surface on the motor shaft.  The drive/sprocket wheels may not fit onto the motor shafts.  When they drill the holes for the set screw they don’t deburr the inside of the motor shaft.  You will need to get your hobby file kit and gently start to file.  First start at the area where the set screw hole is to knock off any burr then try to side the wheel onto the shaft.  I had to go all the way around on both wheels to get it to slide on.  Proceed slowly.  You can’t make it smaller.  When the drive/sprocket wheels fit the motor shaft gently snug them down with the hex wrench.  Make sure the motors screws and set screws are tight because once the tracks are installed you won’t be able to get to the motor mount screws at all.
Attach the track:  note the track guides(two rows of vertical teeth).  These need to go toward the outside of the crawler.  Drape the track over the sprocket wheel and the two center wheels  Now having made sure the front wheel bolts are fully inserted into each wheel and that there is a gap between the plastic wheel hub and outside screw gently insert/wiggle the front wheels into place.  Adjust the nuts and tighten the two front wheels. It should look like the last picture.  Note the wheel, nut, guide, lock washer, nut arrangement.  Try not to turn/move the track since you will be stressing the motor’s transmission, but do ensure that the center two wheels do not wobble and that they turn freely, i.e. they are not binding due to incorrect adjustment. IMG_0353IMG_0354IMG_0356IMG_0357IMG_0355
And the assembled crawler from various perspectives.  These pictures are from the first build so you will not see the lock washers in place.  That is the only difference. IMG_0331IMG_0332IMG_0333IMG_0334
Adding a platform:  now to add a Plexiglas platform.  I purchased a couple pieces of Plexiglas 8X10 at Lowes.  One piece will mount on the standoffs.  I will use the area below to house cables an 8X double A battery pack to power the motors.  Inverting the crawler onto a piece of 8X10 foam board I gently pressed down to achieve perforations marking the location of the standoffs.  Using a Dremel and Dremel drill press I drilled out these indentations with a 1/8” bit.  I used this foam board to mark a piece of Plexiglas and drilled out the holes in the Plexiglas.  I shortened the length of the Plexiglas to 7 5/8”. IMG_0335IMG_0358IMG_0360
With the short piece of scrap from this piece of Plexiglas I created a Pi2 mount hole template using downloadable/printable templates.  Unfortunately the website providing these templates is no longer available.  You might be able to find similar templates elsewhere. IMG_0361IMG_0364
And this is what we have.  The main Plexiglas deck, with Pi template, with Pi sitting on it.  The is an older Pi and its mount holes are not compatible with this template.  Of course this configuration is subject to change as you will notice later in the build. IMG_0365IMG_0367IMG_0371IMG_0372IMG_0374IMG_0377
So I have decided to go with Lego blocks using a grey baseplate and black,grey, dark grey blocks around the Pi2 mounted in an “open” Pi2 case.  First cut and drill the holes in the base plate to fit the Lexan base.  Yes I went to Lexan as a base because the Plexiglas installed earlier did not seem rigid enough.  Cutting Lexan requires patience.  Drilling was easy with the Dremel drill press IMG_0388IMG_0387
Note the lower right corner.  The way the Lego base plate is attached allows for a row of  “dots” to extend beyond the Lexan base plate.  This is true for all sides (front/rear/left/right).  This will allow me to attach/or not a Lego “skirt” later. IMG_03901IMG_03922
The Lego baseplate was attached using screws that came with the standoffs.  Not that in the first picture the standoff is now a female/female allowing for a male screw to be inserted from the top of the base plate.  Unfortunately the tank chassis was not drilled to match Lego so you need to grind off some of the nipples to allow the screws to enter straight and not at an angle.  Then a bit of clean up is required (not shown here). IMG_03922 IMG_03932IMG_03932 IMG_03953IMG_03901IMG_0396
The idea being to block up around the Pi2.  This pic is not of a Pi2 but off an earlier model. IMG_0397

II. Configuring the SD card.

See  Installing Ubuntu’s Mate on Pi2

III.  Soldering and mounting the Stepper Motor Hat

How to solder video.  Very instructive if you have not soldered before.  Its actually fairly easy.

Plug the 2X20 header that came with the Motor Hat onto the Pi2 – shown here. IMG_0400
This step is not necessary but if you do not do it then you need to be sure that the Hat is parallel to the Pi2 board.  There are online instructions which I basically followed but added this step to ensure that both boards would be parallel to each other.  I am going to use two standoffs with screws.  NOW PAY ATTENTION.  The second picture is correct.  You want the “chip side” UP.  So it looks like the 3rd picture.  If you are not careful you can solder the 2X20 header to the wrong side of the board so check your work. IMG_0410IMG_0411IMG_0412
Start soldering the header first.  Done. IMG_0413IMG_0416
Now join the terminal blocks to look like this picture.  And tape them onto the Hat. IMG_04171
Solder the terminal blocks to the Hat.  Yes.  This is my first time soldering. IMG_0420IMG_0421


IV.  Mounting the Pi2 and MotorHat on the tank chassis


Added Lego base plate to the first level on the crawler to help secure a battery pack.  This level will house the battery pack that supplies power to the track motors.  I used 4 Lego 9 degree blocks to keep the battery pack from sliding around.  For now they are just snapped in place but I might decide to glue them later.
The second picture is the battery pack for the motors.  8 rechargeable NiMH rated at 2600 mAh.
Building up the top Level which houses the Pi2, and its Power Pack.   The white block to the right of the Pi2 is what will supply power to the Pi2.  It comes with two USB cables.  This allows you to plug it into a Power source for recharging or the Pi2. IMG_0473IMG_0475IMG_0476IMG_0478
Final wiring using 18AWG stranded wire.  It is a bit too rigid so a smaller guage 22AWG stranded might be a better choice. IMG_0481IMG_0480
Glued the baseplate and bricks together. IMG_0494
Because I could not get a large enough plate for the camera mount/base,  I settled on 4 plates to fashion one that was large enough.  Two of the 4 plates were used to connect two plates together and the smaller 4th one prevented too much flex by resting on top of the Pi. IMG_0496IMG_0497IMG_0498IMG_0499IMG_0500
This is the camera mount plate.  The camera fits into the narrow section (bottom of pic) and the USB cord is stored in the large rectangular area with a “cut out” to drape the cord down the back and connect to the Pi. IMG_0513IMG_0515IMG_0530
All dressed up and no where to go.  “Curb weight” – around 3.5 lbs.  Even so this thing will run at a high ground speed.  I am most impressed with these geared motors.  The batter pack providing power to the MotorHat controller and the motors has provided about thus far about 2 hours of useful driving, with more to come.  The Powerpack for the Pi has had to be charged 3 times.  I attribute this to the USB camera’s demand and the wireless NIC.  Overall a very interesting project. IMG_05361


V. Software/applications prerequisites on the Pi2

I have removed this section of instructions from this page and replaced it with this software procedure.  It is a copy of what was here but modified to streamline the installation procedure.  Also it applies to any build utilizing the PS3 Game Controller.  Support for both Adafruit and PiBorg hardware is/will be provided.  Currently PiBorg build procedure is not done but can be acquired from the PiBorg site.

VI.  Static Testing

7/12/15 Completed the control interface/logic using PygTK (python TK).  It looks like the following (double click on the image for greater detail):


This robotic control interface is written in pygtk.  The window shown above gives the Title:  “Tank Control” and is an 8X8 table with cells being assigned/filled buttons, sliders, progress bars and video.  While the two progress bars in the lower right indicate “RPM” they actually represent a “value” being issued to both electric motors between 0 (no power) and 255.  This value is then scaled on the slider as a percentage, i.e., ground_speed (set by slider) divided  by 255.

Button logic is like this:

Forward:   applies equal power to both motors, so if the slider is set for 50 then both motors operate at 50.

Left: press and hold:   this causes the right track operating at 50  to have the “rate of turn” slider value of 5  added to itself  so that the right track is turning at 55, causing the crawler to turn left.  Until I can test this off of the PVC jacks I won’t know how effective this will be.  It might result in an extremely wide turn.  When the button is released the right motor will return to its original set speed of 50 as per this example.  Because the “turn buttons” are press and hold the rate of turn cannot be adjusted while in a turn.    Based upon testing this logic had to be re-done.  Here is how it works now:  If the forward speed is 50 then a left turn will add the rate of turn value to the right track AND and subtract it from the left track.  This makes for a more responsive turn.  Before the turn radius was wide and a turn command resulted in the tank accelerating in the turn only to slow when the turn button was release.  Addition code was required so that the reduction on the “inside track” did not go negative.  You could have a forward speed of 50 with a rate of turn at 80.  The would reduce the inside track rate to –30.  I have no idea what effect this would have on the motor.

Right:  Press and hold:    Same logic as for Left

Reverse:  Same logic as for Forward

This crawler as configured in the following video is heavy ~ 3.5lbs. now that two batteries and Lego bricks have been added.  In the video I have attempted to capture two perspectives:  one from the control side and the other from the operators side – what the operator sees.  The video presents a control sequence followed by the equivalent of actual tank movement from the operator’s perspective.  I am not sure how successful the video is but the crawler seems to be very much in command.  Be sure to watch in “full screen” mode or the video will be unreadable.  Here goes:


And a better way to control a robotic tank/crawler using a PS3 GameController with the Adafruit MotorHat as seen in the two videos below.  Some observations:  1.  the video from the tank’s “eye” is actually smooth but I was forced to do some editing (its amazing what the camera “sees” at ground level), 2.  the PS3 GameControllers range is between -1 and +1 on both the forward/backward and left/right axis.  The range for the Adafruit MotorHat is 0-255.  I need to polish the algorithm for motor control.  At current weight a motor value of 30 is not sufficient to move/break inertia of the tank.  I might look at adjusting the range to 35~190 and making appropriate adjustments before handoff to the motors through the MotorHat.

VII.  Code

8/8/15  I have completed work on modifying code from the PiBorg website under their license agreement to allow control of the tank with a PS3 gamecontroller and a USB Bluetooth dongle.    I am testing and I will post here when completed.  I would like to point out that PiBorg also makes motor controllers and that they have a new one capable of supporting higher power levels than does the one I used here from Adafruit.  You can see PiBorg’s big tank here – scroll down for videos.

The following downloads of code are provided as is without warranties of any kind.  Please read the header of the downloaded file(s) for more specifics.  You only need one file:  the pygtk interface or the joystick interface (of course you may download both).

This is the download for the pygtk interface:

Download “tank control with slider control” controltank.py_.gz – Downloaded 187 times – 5 KB

This is the download for the joystick interface:

Download “PS3 Tank with "motion"” joytank.py_.gz – Downloaded 147 times – 3 KB

Installation instructions for both software downloads follow:

1.  controltank.py:

This is a compressed file using gzip.  Uncompress it (see below) and place the file in the $HOME/Adafruit-Motor-HAT-Python-Library/examples/tank directory.  Make sure that it is executable:

-rwxrwxr-x 1 user user 16443 Jul 28 13:44 controltank.py

execute the script:

to execute the script you need to remotely log into the Pi2 from another PC.  This PC must let you login using X11.  I suggest that you use the free product Putty (make sure it is configured for X11).

once logged into the Pi2 remoteley, cd to the directory above in step 1

sudo controltank.py &

this should launch the graphical pygtk interface and allow you to control the tank.  Remember that motion must be running or this will fail.

2.  joytank.py

This is a compressed file using gzip.  Uncompress it (see below) and place the file in the $HOME/Adafruit-Motor-HAT-Python-Library/joyborg directory.  Make sure it is executable.

execute the script:

here is the logic for a game controller:

a.  it must first be bound to the Pi2 – so bind it now if you have not already done so.  Remember that a PS3 can only be bound when connected to he Pi2 with a USB calbe. You cannot bind wirelessly. Period.  Manually bind like this:  sudo ./sixpair

Now remove the usb cable from Pi2 and PS3 GameControllerj

b.  sixad must be running.  It should have started on boot but if it did not then manually start it:  sudo sixad –start &

c.  Press the PS3 GameController “PS” button.  It should vibrate and you are ready to go.

login to the Pi2 (plain ssh is fine you don’t need X11)  and cd to:   $HOME/Adafruit-Motor-HAT-Python-Library/joyborg

sudo joytank.py &

Pickup your PS3 Game controller.  Drive tank.

NOTE:  By using the PS3 GameController you might think that you loose the “tank’s eye” – video cameras.  Because motion supplies its own mini http server you can launch any browser (IE might be an issue) and type in the following:


this will display the Pi2’s eye on a webpage.  Not the url.  It uses a “.local” which is a way to address a PC on your network that is receiving a DHCP address.  So if your Pi2’s name is dogbone then http://dogbone.local:8081 should work.

Points of interest:

  1. this is a compressed file using gzip, so to uncompress do:  gzip -d controltank.py.gz
  2. there is absolutely no error checking done in controltank.py so if a piece is not loaded/operational then the app will fail to run.  For example, the Linux app “motion” is required.  If it is not running then the script will fail.  Make sure to configure “motion” to run a boot.  I have detailed how to do this above.
  3. With respect to both programs I have modified the code to accommodate my tank with respect to its weight, types of motors etc., so when using for the first time start at a slow speeds and workup.  It would be a shame to set the highest speed and have you tank run into the wall and disintegrate.  You may have to change some settings in either of the files to accommodate your tank’s behavior with respect to straight line/turning speed.  It is easy to do.  The code is fairly well documented.

10 comments on “Pi2 Tank with Adafruit MotorHat”

  1. Ron Reply

    Dave, Thanks. I am hoping to have a Playstation 3 game controller interface ready in a couple of more days.

  2. Alec Reply

    very nice !!
    I’d hate to ask, but could you perhaps make a script for an xbox 360 controller to function with it? I don’t have a ps3 controller :c

  3. ron Reply

    Sorry I do not have an XBOX 360 controller so I am not familiar with how they function. Maybe you can find a used PS3 at a cheap price.

    Its also worth noting again that I modified a code segment written for another motor controller (while honoring their license agreement) to work with an AdafruitMotor Hat so I did not write the original joystick/button logic in the code. That might have to be rewritten to accommodate an XBOX 360 controller.

  4. Johann Kindlein Reply

    Hi Ron,
    I’m using the Adafruit Raspberry Pi HAT Product ID 2348 and I found your tank project.
    I’m using a Raspberry Pi 3 with the HAT and stepper motors and all the tests scripts included in the Adafruit Library are running without problems, including the Threat tests.
    I downloaded your program controltank.py and testet it with the my configuration but without camera.
    Very nice project. Congratulation.

    What I did changed :
    1. line to import from Adafruit-MotorHat adding Adafruit_StepperMotor
    2. Class VideoThread : in def __init commented the two lines with MYSTREAM_URL

    The program is starting, with the Motor Control Buttons and the sliders and progress bars.
    No error message !

    But motors are not turning when pushing the Buttons !

    Also there are the respective printouts on the screen.
    Do you have an idea what is the reason ?
    Could you please help ?

    Thank you very much.

  5. ron Reply

    I moved your comment here because this is the program I believe you are trying to use.

    OK. There are two computers needed here:

    Computer A: lets say this is the PI on the tank and it has the program and drivers installed
    Computer B: lets say this is a laptop that you will use to log into Computer A.

    You must use an application on Computer B which allows X11 or the graphics will not work. To do this you would ssh to Computer A using Putty (Putty must be configured to allow X11). cd to where the controltank.py program is and sudo controltank.py .

    You say that the test scripts from Adafruit work. the DCTest.py script expects to control a single motor on the M3 terminal block. If you can successfully run this script then I would think that my program would also be successful except that it is expecting the motors to be connected to the M1 and M2 terminal blocks. Make sure that your motor’s wiring is to M1 and M2 (or change my application’s code to the motor blocks for your setup) or my app will not have the desired effect

  6. Johann Kindlein Reply

    Hi Ron,
    thank you for your replay.
    I did installed Putty with x11 configuration. Started controltank.py from the PC with Putty connection.
    Control window with camera image and buttons and sliders are there .
    When I push the Forward button I can here a whistle which is stops when I push the Stop button.
    Motors are not running.

    I’m using STEPPER Motors and they are correctly connected because I did runned the Adafruit Threat Test with them.


    • ron Reply

      I think your problem might be with “stepper motors”. I did not use stepper motors but 6 Volt DC brushed motors like this: https://www.pololu.com/product/1575 (without the encoder).

      If your have a similar type of motor (does not need to have the gear box) wire it to the motor HAT and see if it can be controlled using my app. If I am correct stepper motors require more than two wires and while the HAT can drive stepper motors the code and drivers I am using are not designed for use with stepper motors but two wire DC motors w/gearbox. Again trying hooking up a DC motor like the type I reference above.

  7. Johann Kindlein Reply

    Hi Ron,
    I just looked more in detail to the Adafruit HAT library and have seen that for the stepper motor there is no “run” instruction which is only for DC motors.
    Sorry for the misunderstanding .
    I will go forward also with DC motors.

    Thank you again for your support.

    Best regards

    • ron Reply


      ok. Maybe I should be more clear in the write up that this is for DC motors and not stepper motors. I will make such a correction. Hope it works out for you.


Leave A Reply

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


Bad Behavior has blocked 449 access attempts in the last 7 days.