Let's Make Robots!

Raspberry Pi Control of Dual H-Bridge with Software PWM

AttachmentSize
softPwmHbridgeTest.c2.11 KB
softPwmHbridgeTest.tar10 KB

It seems like I've seen several LMRians who've finally gotten ahold of their RaspPi say something along the lines of "I'm planning on using it to run a robot using my Arduino for the I/O." The Pi only comes with one hardware PWM channel, and that doesn't work if you're using the audio out, so if you want to drive motors it actually sounds like a pretty good idea.

The only problem is that it's wasteful. Think about it: the whole point of the Raspberry Pi is to provide a Linux computer for under $35 US-if you're adding an Arduino to handle the I/O then you're roughly doubling the price. It kind of defeats the purpose.

There are various hardware solutions to help overcome this problem. Adafruit has dedicated ADC and servo control units that work over the Inter-integrated Circuit (aka I2C) protocol, but there isn't much out there for a simple h-bridge driver yet. Luckily, smarter people than me have applied themselves to the problem.

In a web link I posted here a while ago, another walkthrough pointed viewers to Gordon Henderson's site. Gordon has created a library called wiringPi.h that essentially makes the transition from the Arduino IDE to C/Linux on the Pi a lot more familiar.  I'm going to show you how to install the library and use it to control a standard dual-H-bridge.

First, the hardware.  It should look pretty familiar.  The important thing here is getting the lines out of the Raspberry Pi's GPIO header connected correctly to the H-bridge.  You can assign the software PWM to most of the GPIO pins, but here's what I went with.

RaspPi and H-Bridge

We're using pins 12 and 22 for the enables and 8&10 and 24&26 for our input pairs.  Pin 6 is ground.  The header has an odd layout as far as GPIO goes, and Gordon's library uses a still different pin out.  You can refer to this page for a graphical representation of the layout.  The initial pins are the wiringPi library and the mouse-over ones are the GPIO/SPI/etc.

I'm going to assume you're using the "Wheezy" distribution here.  I prefer Adafruit's Occidentalis v2.0 version-it has SPI and I2C built in along with lots of other bells and whistles.  

We'll start with the basics.  Find a directory that you want to use for your projects.  I made one on the desktop called robots (duh.) Open a terminal window and get to work:

 

cd ~
cd Desktop
mkdir robots

 

 

Next you need to download and un archive the library.  You could download it to anywhere, but it makes sense to keep it where you're going to work:

 

wget http://project-downloads.drogon.net/files/wiringPi.tgz

tar xfz wiringPi.tgz
cd wiringPi/wiringPi
make
sudo make install
cd ../gpio
make
sudo make install

 ...and your library is installed.  Next, we're going to make sure you have the softwarePWM library installed.  To do this, we're going to run the "build" script that Gordon kindly included with the wiringPi library:

 

 

cd ..
sudo ./build

This backs you out one level and runs the script.  It should take a few minutes to unpack everything.  If you want to see what it's going to do before you run it, type

 

 

nano build

...and the script will open in the nano editor.  We'll be using that a lot more.  You can think of it as kind of analogous to the editing window in the Arduino IDE.  If you examine the script, let yourself out of the editor by hitting Ctrl+X.

 

Next, we're going to write the program.  Or load it.  I don't care.  I've attached it.  The easiest thing would probably be to download it from the Midori browser and then move it into your working directory.  In any case, we're going to act like you created a new file and copied the text into it:

 

nano softPwmHbridgeTest.c

Either way the result will be the same: an new c file goes into your working directory and you fill it with code.  If you downloaded it, it will just open the downloaded file.

I'm assuming that you're familiar with Arduino here so let's look at select parts of the code.  First, make sure you include all the right headers:

#include <wiringPi.h>...
#include <softPwm.h>

The wiringPi.h file is a set of functions and pin assignments that make everything seem more Arduinish, and the softPwm.h file is just two functions that "blink" a digital pin at a sufficient speed to acheive modulation of electronic signal pulses at a specified width (Pulse Width Modulation, or PWM-just like on the ~ pins on your Arduino.)

Next, you'll notice there's no setup function.  It's not necessary here.  All variables are declared in the main and all the setup is in the beginning of the main function.  Look at:

softPwmCreate (enableB, 0, 255);
pinMode (h1, OUTPUT);

The pinMode is exactly what you'd expect from Arduino, but notice that softPwmCreate has three arguments.  This would be as if you were assigning an output pin exclusively as an analogWrite only pin here.  The first arg is the pin number, the second is the initial value and the third is the maximum value.  Essentially, it maps the PWM level from nothing to your determined max.

Skip ahead to:

softPwmWrite (enableB, 255);
digitalWrite (h1, 1);

Again, digitalWrite is a copy of Arduino except that you use 1 and 0 in place of HIGH and LOW, and if you've got any experience programming an L293/298/SN754410 then this ought to look pretty familiar.  (I went ahead and used all four digital control pins, but you could always use Bird/Fizikus' inverter trick to cut two pins out of the mix.)  What's interesting in this line is softPwmWrite.  It's the replacement for analogWrite.  I think that the reason that it isn't just analogWrite is because you can't get quite the control over it that you would need to say, control a servo.  It is just fine for controlling an H-bridge though.

While you're still in the nano editor, have a look at the ctrl function list across the bottom.  If you make any changes-say to pin assignments or if you just get funky and program your own scratch-then you want to "write-out" (ctrl+o) the changes, which in any other program would be "Save."  Then you have to exit the nano editor, as above, with ctrl+x.

The next step is to compile the program.  You need a special set of arguments to get this to work:

cc -o softPwmHbridgeTest softPwmHbridgeTest.c -L/usr/local/lib -lwiringPi -lpthread

Essentially what you're doing here is telling the compiler, cc, to save an executable program from your c file using the wiringPi and lpthread flags.  It needs both of these arguments to do its special magic.  Once the program compiles without errors, all you have to do is run it:

sudo ./softPwmHbridgeTest

And if all is hooked up right, you'll have a little dancing robot just like in my video.

Troubleshooting: 

Chances are if something went wrong, it was in the installation of the libraries.  If you're interested in working with this further, check out Gordon Henderson's site:https://projects.drogon.net/.  He's a genius and he answers metric tonnes of questions about the implementation of his software in the comments sections.  If everything compiles and nothing happens, check your wiring. Add capacitors across the motors.  Make sure you're grounded, make sure you have enough power and separate power for the motor and micro.  Make sure you have a Rev. B. Pi or else the libraries might be funky.

Afterthoughts:

Allthough I love my little microMagician chassis and it serves the puprose at hand perfectly, you'd have to be intellectually disabled (as we now say in Iowa) to think it was a good idea to put all the power of a Raspberry Pi into a desktop robot.  It's like sandblasting a worm-excessive power and no real reason.  Think about it-you need to be tethered to a monitor, or to put a small enough monitor on the bot that you can't read command lines and oh yeah, you'd have to follow it around with a keyboard and so on and so on.  For a medium to larger robot it might make sense-think the popular trend we've seen on the front page lately of using a Jazzy wheelchair base.  (In that case, you damn sure want to use at least the L298, if not a custom MOSFET h-bridge or more possibly a set of relays.)  Also, another limitation of the Pi against what you're used to with Arduino is the lack of ADCs.  No big deal if you want to use an HC-SR0x sensor, but if you want to use an analog IR sensor, you need an outboard ADC.  I've been playing with using an AT-Tiny and I2C for this purpose, but maybe that will be another walk-through some day.  In any case, the point I'm making is that the Pi is an amazing piece of equipment, but it's too much for an SHR and probably too much for a beginner.  It is a wonderful learning board though.  It has made me fall in love with programming and the Bash all over again.

Update 10/27/2012

I've added a tar of the build file as Tanga requested.  I'd like to add a line from an email that TinHead sent me that I think is very important for beginners in Linux:

As long as you do not mess with /boot, /bin, /lib, /usr/bin, /sbin, /usr/sbin, /usr/lib, /etc you can't really mess up anything :-)

You'll notice that in compiling the program we do flag some of those directories, but we are not changing anything within them.  This is really good advice.

Also, Bird pointed out that once you've built a program you don't necessarily need to "sudo" it to run it.  In this case you do because of the wiringPi lib.  He includes these useful tips for Linux users:

  • Linux is case sensitive; desktop != Desktop. Also, a shortcut, many distros have TAB autocomplete. I know Win7 has this in the command prompt now, not so sure about the older Windows versions. 
  • You may need/want to point out the password for sudo. 
  • cc --help or cc /? or cc -h (I really don't know the switch) will get you a help of cc and tell you what flags are available. man cc should also do a more indepth job, or, jump online and read it in a browser window via a search for man cc, if that is more comfortable. 

Okay, I've added enough content tonight that I don't feel like I did this just to bump myself to the top again ;-) 

Thanks to Bird, TinHead and Mogul for their help.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I just dun effed up.

 

Can someone post the contents of the build file?  I just managed to delete it all.  :( - oops.  Sorry.

Maxhirez's picture

I've updated the attachments for you.

When things quieten down at the end of this week I'll be giving this a go.
6677's picture

You should submit this to the pi blog, they need guest bloggers over the next few days.

 

Details:

http://www.raspberrypi.org/archives/2255

Maxhirez's picture

I actually just signed up there last night and linked two pages to this.  Thanks!

NilsB's picture

As a Pi is on it's way to me this article if of great interest for me. Thank you Jason for putting that all together.

Maxhirez's picture

I'll bet you'll really enjoy your rPi!  I can't wait to see what you do with it.

Maxhirez's picture

We really need a "code format button" in rich text. I couldn't make heads or tails of the CSS and look at the wrap failure. Ugh. Also, sorry about the "uhms" in the video.

I've fixed the CSS as of the time stamp at the bottom of the add.

mogul's picture

Yeah, we definitely need a stronger markup system for writing here on LMR. Personally  I would vote on some kind of a wiki markup language like creole I used here http://letsmakerobots.com/node/31379

Maxhirez's picture

That one was the mother of all tips/walkthroughs, too.  Is it difficult to use?  If you have to go through and look at each tag in the html editor, your head starts to melt.  Mine is killing me right now.