I volunteered to turn a friend of mine's Warhammer 40K Imperial Rhino personel carrier into a remote controlled item. Little did I understand the undertaking that I had agreed on! My requirements for this project were that the transmitter and receiver had to be a single chip design, done all in software. I succeeded. The receiver chip uses a Panasonic 4602 38KHz receiver and that's it for external components. It has the serial input (GP3) , two RC hobby servo outputs (GP0/GP1) and three digital outputs (GP2,4,5). Here is the code for the receiver chip. It is a bit of a specialty in that the digital outputs are actually "momentary contact" type outputs because I only needed a pulse to go out to trigger a cheap sound board I got from a $6 toy! I don't even use the GP2 output in this design. The receiver uses 4 NiCd 115MAH cells, the largest set I could fit into the Rhino! The transmitter chip uses 5 pullup resistors and an IR LED powered through a 330 resistor - quite a bit of power I think. To keep things simple, I used a 78L05 to power the PIC so I could use a 9V battery and keep the whole project box size small. It will run fine on 3 alkaline cells, or, from 4.5 to 5.5V. The transmitter reads the status of the 5 momentary contact buttons and decides what messages to send to the receiver. Here, I give priority by bit value, just so there needs to be no encoding and it keeps the code simple. Also, when a direction command is given (forward, reverse, left, right) I also give the 'go' command and the 'motor noise' commands. If a button is pressed and immediately released, the transmitter waits a couple seconds and sends the 'stop' command. This allows you to hold a button down, issue a series of commands continuously but still stop nicely. The transmitter issues a constant stream of 'stop' commands when no button is pressed. This is a nice troubleshooting method as well as insuring that the unit doesn't just take off! Here is the code for the IR transmitter.
Building the Rhino was a challenge. It is about 5 inches long and about 3.5 inches wide and about 2 inches tall. Into that I needed to put a battery pack, two motors, two motor drivers, the IR receiver board and actual drive wheels and wiring with a sound board and speaker. Wow. I used two LEGO micro motors for the drive motors, they were connected to two LEGO medium pulleys via rubber bands and held in place using two-stud LEGO axels through a two stud Technic rail - If you know LEGO, you know what I mean by that. I drove the motors by connecting them to the "guts" of two old hobby servos. This gave me two small bi-directional motor drivers that I only needed a single I/O line to control. The receiver board was about 1 inch by 1.5 inches and had the IR receiver sticking out the top of the model. The 4 cell 115MAH NiCd pack was about 1 inch x 2 inch by 0.5 inch, very small! I used "tank" steering and mounted a pivot ball near the back of the tank to lower friction. Below are the schematics for the transmitter and receiver sections including the battery and motor/driver setups as I installed them. I only needed to make a couple of smalll internal mods to get all of the stuff to fit.
We all have need of that last line of defense when the SONAR glitches, the IRPD doesn't and our bot is on a collision course with a table leg. That last defense against re-kitting is a bumper. I have made a few from microswitches, miniswitches and other things - usually they work, sometimes they need too much force to work and "ugh" collision. This example is another type of sensor that doesn't use a switch, its parts are super cheap and it works just great. Its a "whisker" bumper. Here are the parts you need to build one too.
Let me show you some pictures and describe what is going on, a picture is worth a thousand words in this kind of game. Click on the images to make them bigger.
|This is the top of the PC board with mounting holes drilled. Note centering of the two Berg headers and the whiskers so they go directly between the leads. This side of the board is NON conductive! It is about 1.5cm between the point where the wire goes through the board and the Berg headers. I pulled the plastic separator off to install the whiskers then put is back on loosely, mostly for looks I guess.|
|I have carved out two places for the contacts and then shorted the two of them together with a wire. You could have two different inputs here if that is needed. The wires each have a 'Z' bend in them where they are soldered to the large conductive surface, this gives better support than just running the wires through.|
|Here is the whole thing with all the bends and wires showing. If you have trouble soldering the whiskers to the board, gouge out a smaller area in the board to solder them to and buff the wires with some sand paper so the solder will stick well.|
It doesn't take much to make these and all of the parts are really cheap. They look cool, work reliably and are cheap - What more could you want?
Sometimes you want a simple solution to a problem and you don't mind if your main controller has to do the work. This IRPD requires the main robot processor to choose which side to look at, and requires it to "debounce" the results for reliably operation. But, it still works really well without any complex program code.
'Basic Stamp II Freq Counter O555 con 7 freq var word Loop: count O555,100,freq debug dec5 freq*10,cr goto Loop
The NAND gate is a standard 74LS00 that you can get anywhere - even Radio Shack, same with the 555, IR detector (RS Everlight or Sharp GP1U58Y) and IR LEDs can also be gotten at Radio Shack. Parts are easy to find and simple to connect. This does not require any fancy wiring or parts placement. Make sure that you use a .1uf bypass cap next to the 555 and next to the IR demodulator. Tweak the 2K pot until you have 38KHz, if you have a 'scope, this is a 1/38,000 period, or about 26.3us. If you are using a Parallax Basic Stamp II for your robotic controller, you can feed the output of the 555 in an I/O port and measure the frequency very easily. The code to do this is in the text box to the right. It assumes that you are using port 7 as the 555 input port.
One of the nifty things that make the 555 circuit fun to use is that you can use it to do IR communications with other devices that read IR at 38KHz! If you run pin 4 of the 555 to a Stamp II port instead of just tying it high, you can use the serout Stamp II command to modulate the IR in such a fashion that other IR demodulator equiped devices can read it! I've done it, it works - Have fun.
I have decided to move up from using hacked servos as my drive motors, I wanted more powerful drive motors! To do this you really need PWM. Pulse Width Modulation is the process by which you vary the duty cycle of the drive signal to a motor, without changing the frequency. Basically, if you have your PWM set to 10% of the total possible "on" time then the motor runs at 10% speed, at 75% it runs at 75% of max speed, and so on. In fact however it usually takes more of a "punch" to get a motor to start than it takes to keep it going, but I'm not going to worry about that right now... Anyway, I decided to use as much from a previous project that used a PIC 12C508 to control hobby servos. Hmm, in fact this only really used the serial receive section, the rest was quite different. For one thing, this project needed to run MUCH FASTER. My PIC runs at 4MZ, the best I could get a smooth PWM response out of it was 1KHz. I would rather have gotten to 2KHz, but at 2KHz, the progression wasn't as smooth because there just wasn't enough time to do it all! Another minor problem is that timing is much tighter on 9600 baud than it was on 2400 baud and I had to be very conservative about when I sampled the serial data stream - there is very little room for slop.
The most commonly used motor driver chips out there are the L293 and the L298. In the L298 there are two lines, forward and reverse that determined the direction a motor channel. With this in mind, and because I like elegant solutions that use the minimum of connection wires, I designed this chip to take 128 speed steps and be able to latch the direction pins too. So, if you send a number from 0-127, it will be multiplied by two and used as the speed setting (0 to 254) for the PWM. If you send it a number greater than 127 (bit 7 set) then bits 0 and 1 are treated as the "forward" and "reverse" line settings. In this way you can take care of all of the speed and directional data for a single motor using a single data line! If you are using one of the less-expensive and potentially SUPER high current options like an FET to PWM and a relay to set direction, you only need to fiddle with one of the direction lines. For you DIY types, here is the source code for my TTT serial PWM controller chip. It works by sending it numbers from 0-127 for speed settings and 128-131 to set forward and reverse pins. The baud rate is 9600 baud. Here is some Basic Stamp II code that tests it out. Here is the PDF documentation file for using this chip.
As usual, if you have any questions, praise, criticisms or suggestions for me, Contact me and let me know. If you don't have a PIC programmer and want one or more of these, $8 per chip + $1 for shipping (total) will convince me to make them up for you.
|This kit uses either the Panasonic 4612 or 4614 IR demodulator.|
This project is inspired by the DPRG IRPROX project. They have a pretty good PCB layout and idea. I would like to thank them for posting their project for all of us to see and learn from, I wouldn't have started PIC programming without them, or at least not nearly as quickly come up to speed! The pinout on my board allows either a five-wire or a four-wire connection to be made the former uses a disable line if desired. You can also put in a resistor or use a trimpot to adjust range. The trimpot locations are very generic, most pots will fit. Be careful not to adjust pot to 0 ohms!
The IR proximity detector works very well, even in a brightly lit "noisy" environment. Instead of modulating the IR LED for 600us and then looking for a detection, I now look for a detection after every on/off cycle of an IR LED and count the number of hits that I get. I also look during the 'off' cycle when none of the IR LEDs are on and count the number of false hits that I get there. If I get more good hits than false hits then I say its a true detection. I then increment a counter as a sort of timer, when it passes a certain threshold, I notify a hit. At this time I check to make sure that a minimum number of good hits has been attained. At the same time I keep track via another time-out counter of noise hits. When this counter passes a certain threshold it then removes any detection that has been set. I fiddled a lot with the various threshold values for minimum number of good hits, time-out values and divisors for updating the false hit counts, and finally settled on the ones that currently used. I'm calling it a success and moving on to other projects! Here is the source code for the, uhm, DLC IR proximity detector. Here is the PDF documentation for this kit.
I am now selling the complete kit, it was brought up to me that the exorbitant shipping costs from some distributors makes a full kit a real value added. So, here it is. The board, PIC, LEDs IR components and resistors as well as instructions are for sale. . I will make this in either 38KHz or 56.7KHz models. Contact me if you areinterested. Bulk buys of 10 or more or robotics clubs get discounts!
Eventually we all want to know just where our robot is, so we can choose an absolute direction. Usually this type of device is quite expensive. However to our rescue comes Dinsmore with low-cost electronic compass module. It outputs the four cardinal points and combinations thereof that will give eight directions. I decided that combining this with tilt sensors (the Dinsmore compass will only work if not tilted more than 12 degrees) would be a cool project. I am using a PIC 12C508 to do the dirty work and return an 8 bit number with the directional and tilt data all included. Here is the schemo that I am working with, I haven't yet found tilt sensors that I like so only the compass part has been implemented. Here is the PIC source code for the 12C508 that will return the direction as a number from 0 to 7 in a single byte number at 2400 baud when the trigger line is cycled from a 1 to a 0 and back to a 1. Here is a Parallax Basic Stamp II program written to test the compass. It has the compass connected to Port 2 and an LED connected to Port 0.
The compass works by sensing the active low reactions of the Hall Effect sensors and arranging them arbitrarily on the "map". The "<<" on my PC boards is the direction of the front of the robot, when THIS part of the board is facing North, the compass will return a 0; 1 through 7 are returned as you go around the compass to the East, South, West, etc. in 45 degree increments. So, your main controller can just multiply the number returned by 45 to get the compass points in degrees. The PIC takes two readings 1/3 of a second apart, if these readings differ it means that the compass hasn't settled yet. It will set bit 6 of the returned byte to show this along with the number of the last reading taken. For instance, if you are transitioning from North to North East, it will return 0x41, if you have settled on North East, it will return 0x01.
The nice part about this design is that a single line is used to start the reading and then read back the results! Very convenient, in my opinion. Below is the schematic, the PC board layout and a picture of how it looks.
Electronic Compass Circuit
This is a lot harder than you would initially think. Its a bit of real-time programming on a controller that is only running a 4MHz clock. Not great for servos in my opinion. I send a single byte where the upper two bits defines the servo, 0-3 and the lower 6 bits defines the position. On the PIC I then multiply the 6 bit number by 4 giving numbers from 0 to 252 in increments of 4. I have the TMR0 timer setup to get a tic every 8 cycles so that 250 tics=2ms of time (convenient huh?). This works out well as I have timed the loop to check all four servos every 4 TMR0 tics, if there is a new byte coming in this could be stretched out to 8 tics, hence, jitter in a 4ms window, not too bad. But there are no interrupts on this chip, so I have to compare values constantly and when not comparing, look for an incoming byte. All this works finally! This code checks for framing errors and is about as tuned as you can get. Just make sure that you don't send bytes back-to-back very often, this can cause jitter.
Lots of interesting stuff is going on here, the timer is being used lots of code interleaving, counting cycles in the delays for the serial reads and so on. Here is the code. I have implemented checks for framing errors in the serial receive section and have optimized to eliminate jitter from the code in this current revision. As always, if you like my stuff and use it, let everyone know you used my stuff, and Contact me so that you can stroke my ego. I have copyrighted it all, so that I retain rights to it, but I don't care if others use it, you just can't sell it without my permission. That's all. For those without PIC programmers, I am selling the programmed chips with an instruction sheet for $8.00 + $1.00 shipping. Here is the PDF documentation for this project.
My most recent code has some new features. It is tuned specifically for the hobby roboticist now! Anyone that has built a robot with the "hacked" RC servo motors knows that these things "drift" over time and what is a dead stop five minutes ago now creeps forward or in a circle or whatever. Not anymore with these controllers. If you write a 0 to servo 0 then servos 0 and 1 will be disabled, they will stop rolling as they are no longer getting a signal, they can be moved too but this isn't a problem with a wheel. In the meantime the other two servos can be controlled normally, and you can write new positions/speeds to servos 0 and 1 too, they just won't do anything yet. If you write a 0 to any other servo, it re-activates servos 0 and 1 and they will continue on with the last value that was written to them.
Long have I wanted to get a better proximity detector for my Mindstorms robots, now I have one. When I found the Lite-On IR modules and the new Sharp IS1U60's it looked like a match made in heaven. However, these newer, smaller units are more sensitive and far more picky. I had to re-write my code to get them to work well and try to cut down on their sensitivity. The PIC program I used for this project has the exact same code as that in my IRPD project above, it just requires more "hits" to go over the sense threshhold because this IR demodulator is so much more sensitive. I also needed a different power line filter for them that was much more exacting. But it was worth the effort! It runs off of power from a sensor input and can give a left/right/both/neither indication all while leaving two sensor ports free! You use it like a light sensor and check for the values returned. I have tested the unit with the standard Mindstorms programming environment, the NQC one and a VB program using the Spirit.ocx, it works well in all of them. The RCX IRPD will only pull about 2.5ma of current. The schematic below shows how everything hooked up and what values I used for the resistors. The detector will get flaky when the batteries get low and will run fine the rest of the time. The small sized IR detectors have a pretty tight spec limit. The board is quite small, it should fit into a 4x5x2-high package with a little effort.
Here is the assembly manual (PDF) for the kits that I have put together in the past, the schematic in the PDF is incorrect, the correct schematic is pictured below. This is the parts list with the Digikey part numbers that I used. All that I have available right now is the programmed PIC if you want to build your own using the schematic below.
|RCX IRPD Schematic|
|RCX IRPD Pictures|
When I ran the RCX connected to the really cool program NQC Command Center and polled the sensor inputs I got the following readings with older batteries and freshly charged Rayovac Renewal rechargeable alkalines.
|Older batteries||Fresh Batteries|
As you can see, these are very useful values for programming our little robot! Each unit will have some variance, you will have to calibrate your system when using this device. However, staying with the percentage, not the raw value will give you more repeatable numbers I think. I have written an NQC program to run the RCX IRPD in obstacle avoidance mode with a separate task that reacts to running into something with its front bumper. This code illustrates two things, multiple running threads and signalling between threads. Its a snappy little guy and runs quite well. You will know when the batteries are getting low because it will stop detecting anything at all and just crash. Some obvious improvements to the program would be a light seeker addition and a bumper switch for when it misses something and runs into it, thereby smashing all of the stuff that is up front! I have found that an RCX robot with this sensor is far more responsive than any of my other robots that use them. Perhaps I should put together a multitasking environment for my other 'bots too! Contact me with ideas or suggestions!