Raspberry Pi Control of Dual H-Bridge with Software PWM
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.
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 Desktopmkdir 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
...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:
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:
And if all is hooked up right, you'll have a little dancing robot just like in my video.
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.
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.
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: