trp2.asmAssembly code for the Simple Robot.
In this article, I will present you with all of the details required to successfully build a simple computer-controlled robot, including the sources for obtaining the suggested materials. The robot will be controlled with two hobby-servo motors, will use a Motorola 68HC11 microcontroller as the computer, and will use two bumper switches to allow it to navigate around obstacles. Even if you do not have experience with these devices, don't despair; the required theory and details are included here to get you up and running. I will be using a robot I built about a year ago as a model. I use this BOT as a test-bed for a variety of tasks and uses, including simple mazes, line-following (with an additional sensor), and for a programming platform for a college class I teach. As a test of this article I had my 10-year-old son, Tommy, build a Lego-based robot from the information presented here. His experiences are included at the end of the article.
You will need soldering equipment and skills, basic tools (screwdrivers, drill, wire-cutters, hot glue gun), and a PC for programming. All programs required are public-domain and can be accessed from a variety of sources (see the references at the end of this article), and I include the complete source code for controlling the robot. The most important requirement is the desire and the confidence to accomplish this project.
There are a variety of different pieces of technology we need to pull together to build this robot. We need motors to propel the robot. We need a computer to control it, which will require a computer program to implement our control logic and software to load our program into the computer. We will need power to drive the electronics and sensors to allow the robot to sense its environment. We also need some sort of platform to tie all of these parts together into a working BOT.
Figure 1. My 4"x4"x4" Clear Cube-BOT (CCB).
My trusty little robot is built in a 4"x4"x4" clear plastic cube which I call CCB for Clear-Cube-BOT. It is a simple minimal-system which I use to test a variety of robot-type things. I'm constantly tinkering and trying my latest program ideas with CCB. In Figure 1 you can see the simple layout of the BOT. The BOTBoard is mounted on the back inside wall. A dual AA battery-holder is mounted on each side, each one above a modified hobby-servo motor. In this picture, I have taken off the front bumper and installed an optical sensor, which is used for line-following. I also use larger wheels when line following, which makes CCB faster. Other sensors can also be added to allow CCB to sense light, hear sounds, track infrared signals, and so on.
Figure 2 shows the layout of my robot. This is just a suggested layout. The important aspects are to mount the servo motors low on the robot to allow the wheels to touch the ground and to provide a third ground support. At the Seattle Robotics Society (SRS) we commonly use plastic or metal drawer-pulls as skids. The BOTBoard should be mounted to allow easy access to the 4-pin header which is used to download programs to the BOTBoard from the PC. To mount the different components to the plastic box I used a hot-glue gun, metal PC-board mounts, and small screws. Another common method is to use double-backed tape. When Tommy builds his version of the robot with Legos we will see how he sets up the layout and decides to mount the different components. We are not going to take the Lego purist's approach and only use Lego-supplied parts. (We will be building a Lego platform and connecting it to our standard motors, switches, batteries, and computer.)
Figure 2. Top and side views layout of my 4"x4"x4" clear-cube robot.
The motors we will be using are standard hobby servo motors. They offer low cost, easy control, and good power. What is a servo motor? The kind of servo motor we're using is a motor with a feedback mechanism to sense its position. The control input to a servo motor tells it to be in a certain position, and logic built into the servo motor will position it. A typical servo consists of a DC motor, a gearhead, a potentiometer (pot) for position feedback, and a small circuit to read the pot and position the motor. Physically, servos have limit stops to restrict their range of motion. We'll have to modify a standard hobby-servo to allow continuous rotation of the motor for our robots.
The servo motor I've used in CCB is the Futaba FP-S148. It is found in many radio-controlled vehicles, and is a real workhorse in the hobby field. The S148 is carried by local hobby stores for about $25 each and can also be found through mail-order for about $15. Of course you can find numerous other servos from Futaba, Airtronics, Cox, Royal Titan, and others, as well as "house" brands. Prices range from under $15 to well over $100 each. Variations in size, torque, speed, bearings, and construction (regular versus heavy-duty) account for the wide price range.
Figure 3. PWM signal for servo control.
Before we learn how to modify a servo for continuous motion, let's consider how to use it unmodified. The S148 servo motor has three wires and can turn 180¡. How? Of the three wires, black is ground, red is the motor's voltage, and white is the control line. The voltage is 5 volts. The control line requires a pulse width modulated (PWM) signal. There are two factors when dealing with a PWM signal: frequency and duty cycle. For the S148, the frequency should be about 33 Hz, or 30 mS in width.
True duty cycle is the ratio of high time over total time-- in our example about 20%. However, with servos, the length of the high time is what indicates the servo's position. The actual frequency of the signal is not critical. Tests with the S148 indicate that a minimum high-pulse of about 0.1 mS will turn the servo full to the right, while a high-pulse of 2.3 mS will turn it full to the left. A high-pulse of about 1.2 mS will position the servo in the middle of its range. Full left-to-right movement takes about 3/4 of a second. A high-pulse in between these two times will cause the servo to position itself accordingly.
Figure 4. Servo pulse width to servo position.
Servo motors can be used for a variety of robotic uses as-is. Peter Dilworth's article in issue 1 of TRP talks about a walking biped robot that uses 12 servo motors. I couldn't tell from his photographs if he was using the S148 servos, another smaller model, and/or a model with faster response or higher power. Regardless of the specific servo used, the concepts are the same.
A stock servo can just move back and forth through a 180¡ range-- not good for robot wheels. A servo can be easily modified for continuous rotation. I have a new Futaba FP-S148 on my workbench in front of me, so let's walk through the procedure for modifying it. On the cardboard backing for the S148 I see a complete parts list and also an exploded diagram (Figure 5). I will refer to this during the procedure. Also in the package is the Futaba warranty. This can be discarded since this procedure will, I'm sure, void their warranty.
Figure 5. Exploded S148.
To open the servo, remove the horn (part #17) and screw (part#18) if it is on the servo. Remove the four pan-head truss screws (part #22) with a small Phillips screw-driver. Remove the bottom case (part #3) and also the upper case (#1). The gears are under the upper case, so open it carefully to avoid sending the gears flying across the room. Carefully remove the gears, #13, #12 and #14. Don't wipe off the white grease and don't remove gear #11. Under gear #12 are 2 screws which hold the motor and circuit-board in place. Under gear #14 is the end of the feedback potentiometer (#6). Remove the 2 screws (#10). In my S148, one of these screws is buried in white grease. By pressing the end of the potentiometer (#6) down hard on a table, push the circuit board a little bit out of the middle case. Now, use one of the pan-head truss screws inserted into the screw-hole (#10) to carefully push the motor a little bit of the way out of the middle case. The entire circuit board and motor assembly (#19) can now be easily removed from the middle case. Using a soldering iron, remove the potentiometer (#6). It is connected to the circuit board by three legs. You may want to clip the leads on the pot to make it easier to remove. Be careful not to overheat the circuit board or to damage the circuit board traces. In place of the pot, two 2.2 k-ohm resistors (red-red-red) must be used. The pot on the S148 is 5k. If your pot is a different value, the resistor values to use should be about half the pot value. Connect one resistor from the left hole to the middle hole, and connect the other resistor from the right hole to the middle hole. The pot is used to tell the circuit board what position the axle is in. By using the two resistors we are fooling the circuit into thinking the axle is always in the middle position. You may also want to clip the long leads on the other parts on the bottom of the circuit board. This will ensure that a lead doesn't touch another part and cause a short in the board.
Put the circuit board and motor assembly back into the middle case. Make sure to orient it properly with the motor in the side with the two screw holes. Before replacing the gears, replace the two motor screws (#10, I always forget this). You may have to push on the bottom of the motor to get the screws to grab. Now seat the circuit board and make sure the rubber wire-relief (#21) is in place. Replace gears #12 and #14, then #13. Notice on gear #14 a plastic piece which, when rotated, will run into gear #13. This piece of plastic must be removed to allow full rotation. It can be removed using a small wire-cutter or a cutoff wheel in a Dremel tool. Be careful not to damage the teeth in the gear. When this is done, replace the upper case (#1), then the bottom case (#3), making sure to orient the bottom case with the small slot for the wire (#21). Replace the four pan-head truss screws (#22).
One last modification is needed to work with the BOTBoard. The three wires in the servo's connector are ordered: white, red, and black. The BOTBoard-compatible order is white, black, and red, from close to the HC11 on out. Use a very small slotted screw driver, good eyesight, and a steady hand to lift up the black-plastic tab on top of the silver metal part on the connector, and pull the wire out of the connector. Do this for the black and red wires. Replace them in the connector, swapping their positions.
With a modified servo motor, we can now achieve continuous rotation for a robot wheel. If we send the servo a control signal with a high-pulse less than 1.2 mS, the motor will turn to the right. It will keep turning to the right because the potentiometer has been removed. A high-pulse larger than 1.2 mS will cause continuous rotation to the left-- perfect for a robot.
The software programs (AS11 and PCBUG11) used to program the 68HC11 microcontrollers are free from Motorola, and available on a variety of electronic bulletin boards. I have written two documents, AS11_Primer.txt and PCBUG11_Primer.txt, to outline the programs. They include lessons learned from my students as they have used them. Refer to the references section for sources to obtain these programs and documents. While I strongly recommend you learn the HC11 assembly language (it's really easier than you think), there are C and forth compilers available for the HC11. Also worth mentioning is the effort by Karl Lunt of SRS fame. He is currently writing a BASIC compiler for the HC11 which is looking good in Beta form and should be available when you read this. It will generate assemble code which you then assemble with AS11. Look for it on the SRS web-site.
The 68HC11 is an 8-bit microprocessor with on-chip peripherals including 512 bytes of both EEPROM and RAM, up to 26 bits of digital input, 27 bits of digital output, 8 A/D inputs, and 5 on-board timers. Some of the I/O pins on the HC11 can be configured as either an input or an output. To achieve maximum number of inputs given, some of the outputs will be given up. Likewise for a maximum number of outputs. The HC11 has two 8-bit registers (A and B) and two 16-bit registers (X and Y). The program will be put into the EEPROM in the HC11. Different versions of the HC11 have different memory configurations. The A1 and E1 versions have 512 bytes of EEPROM starting at address $B600 (hexadecimal). The E2 version has 2048 (2k) bytes of EEPROM starting at $F800. The HC11 has RAM memory starting at address $0000. The A1 and E2 version have 256 bytes of RAM while the E1 version has 512 bytes. The various ports and timers of the HC11 are accessed at memory locations from $1000 through $103F. The program given will work as written for the A1 and E1 version of the HC11. For the E2, the ORG statement in the code must be changed from $B600 to $F800.
We will be using assembly language to program our HC11. Other languages can be used, which are then translated or compiled into HC11 assembly language. Assembly language works well for short programs like ours; for more complex logic, higher-level languages are preferred. Let's look at a subset of the HC11 assembly language which we will be the using. The operations can be grouped into functional types. For complete information on HC11 assembly language programming see the Motorola M68HC11 Reference manual (M68HC11RM/AD), also known as the "pink book". The robot program uses only these instructions (Figure 6). Some are not used in our code but are included for completeness:
|LDAA||Load the A register.||INCA||A = A + 1.|
|LDAB||Load the B register.||INCB||B = B + 1.|
|LDX||Load the X register.||DECA||A = A - 1.|
|LDY||Load the Y register.||DECB||B = B - 1.|
|STAA||Store the A register into memory.||ADDA||A = A + number.|
|STAB||Store the B register into memory.||ADDB||B = B + number.|
|STX||Store the X register into memory.||SUBA||A = A - number.|
|STY||Store the Y register into memory.||SUBB||B = B - number.|
|CLRA||Set the A register to zero.|
|CLRB||Set the B register to zero.||Testing:||Description|
|CLR||Set a memory location to zero.||CMPA||Compare A with a number.|
|PSHA||Save the current value of A.||CMPB||Compare B with a number.|
|PSHB||Save the current value of B.||CPX||Compare X with a number.|
|PSHX||Save the current value of X.|
|PSHY||Save the current value of Y.||Branching:||Description|
|PULA||Restore the value of A.||BRA||Branch to a label.|
|PULB||Restore the value of B.||BEQ||Branch if the last operation was 0.|
|PULX||Restore the value of X.||BNE||Branch if the last operation was not 0.|
|PULY||Restore the value of Y.||BSR||Branch to a subroutine.|
|JSR||Jump to a subroutine.|
|Testing & Branching:||Description||RTS||Return from a subroutine.|
|BRSET||Branch if bits are set (equal to 1).|
|BRCLR||Branch if bits are cleared (0).|
Figure 6. Tables of 68HC11 assembly language instructions.
I don't have space here to teach you assembly language programming. My hope is that the information presented here is sufficient to help you get a robot up and running, and to spark your curiosity to want to learn more. Try reading through the robot program. I've placed comments throughout the program to assist you in following the logic. Let me point out a few of the assembly language conventions used:
An asterisk '*' in the left column makes the entire line a comment. Other comments are placed after a semicolon ';'. Numbers used are in decimal (base 10) or, if preceded with a dollar sign '$', the number is a hexadecimal number (base 16) with digits 0-9 and A-F (or a-f, case here is not important). In an instruction, if a number represents an address, then just the number is used. If the number is to be used as a number and not an address, a pound sign '#' is used before the number. I use constants as defined with the 'EQU' operation. This allows me to define a number once and use the name in the program. If I want to change the value, I only have to change it in a single place, and makes the program easier to understand as well. Names are also used for labels. A label indicates a place in the code, and an instruction can then branch or jump to a label. Labels start in column 1 and end in a colon ':'. Labels are case sensitive. Instructions may not start in column 1 (they will be interpreted as a label), so one or more spaces or tabs are used before an instruction. The 'ORG' operation tells the assembler where we want the program to start.
The program presented here will control your robot. When first turned on, it will go forward. If the left bumper is hit, it will back up, turn to the right a little, and then continue forward. If the right bumper is hit, it will back up a bit, turn to the left, then continue forward. This behavior will allow it to work its way around obstacles. I've added two additional behavior features: If stuck in a corner, the robot can hit one bumper, then the other in a back-and-forth manner, which essentially gets the robot stuck in the corner. The program watches for this back-and-forth condition, and after 6 hits the robot will turn around and exit the corner. The other added behavior is to turn a circle every few seconds when nothing is hit. This simple behavior is quite entertaining to watch. My hope is for you to use this program, and then to modify it as you want. Depending on the size of your wheels, the turns will be different angles. The constants defined in the program can be changed to use different turning and backup times (BACK_TIME and TURN_TIME).
The flow diagram (Figure 7) shows the flow of the logic in the main part of the program. The underlying code for the servo motors is not diagrammed here as it is interrupt-driven to generate the PWM signals required to control the servo motors.
The program is structured in a continuous loop. Initializing the servo code, the back-and-forth state (BF) and the straight-time state (ST) takes place, then the program looks at the bumper switches. If they are both off, we then look at the straight-time counter. If this is less than 255 we go back to look at the bumpers. The program spends most of its time in this one loop. When the straight-time gets to equal 255, the robot is bored and we pivot it to the left, then set it forward. We then branch back to the top of the loop where we set BF and ST to zero. The interesting part of the program gets used when the bumpers are on. If both bumpers are not off, we then jump into the bumper logic. I detailed this separately in the flow diagram due to its complexity.
The bumper logic, when a bumper is hit, is to back up, then turn away from the side of the bumper which was hit. If the right bumper switch is on, we will turn to the left. For the left bumper, we turn right. If both bumpers are on we turn far to the left to turn away from the object. The bumper logic section also tracks the condition when the bumpers are hit in a back-and-forth manner. This happens when the robot is stuck pointing into a corner. After 6 of back-and-forth hits, we turn the robot far to the left to point it away from the corner.
Other logic can be used with this robot to allow the robot to do other tasks. For example, if we want the robot to follow a wall to its left, we can move the robot forward with both forward movements and left turns. When the left bumper is hit, pivot to the right, then continue the forward and left movements. This will move the robot in small arcs to the left which will keep it close to the left wall. This is a very simple behavior for maze solving.
Figure 7. Flow diagram of the robot program.
Marvin Green's BOTBoard is a circuit board which is a minimum circuit to get the HC11 running in bootstrap mode. Figure 2-22 in the Motorola M68HC11 Reference Manual gives a similar circuit. Build this circuit or, if using a BOTBoard, follow Marvin's instructions for wiring up the BOTBoard. Tommy has successfully built a number of BOTBoards. Other HC11 boards can also be used. You will also need a communication cable to connect your PC to the BOTBoard. The BOTBoard write-up describes how to do this. I've contacted Christpher Nielsen who is with the Zorin company here in Seattle. They offer complete BOTBoard kits using Marvin's BOTBoard and also have the communications cable and the required Motorola software available-- a good one-stop source.
Attach the wheels to one of the hubs included with the servo motor. I find that using a small hot-glue gun works well. Make sure to have the mounting screw in the hub when you glue it to the wheel, and also make sure you have a hole in the wheel which a small screw driver will fit into to tighten the screw. Having a collection of wheels set up like this enables quick and easy changing of wheels on your BOTs. With the BOTBoard, make sure to configure the servo's cable to be white-black-red from the HC11 on out. Add a skip of the appropriate height to result in a level robot.
You need to use 4 batteries to power the BOTBoard and servos. I use Nicad rechargeable batteries in my robots, either AA or C size. In the long run, they will save money over buying non-rechargeable (regular) batteries. Regular batteries do have an advantage in that they hold a better charge. Many people use the rechargeable batteries for building and testing their robots, but then buy a set of regular batteries for a special competition. Use batteries that are 1.25 volts and watch out for batteries that are 1.5 volts. The HC11 requires 5 volts.
An option in powering your robot is to use separate power for the computer and for the motors. Sometimes the motors introduce noise which can cause problems with the computer. The BOTBoard has a jumper for the power going to the servo. Either jump this to the BOTBoard's power, or connect it to a second pack of four batteries.
I use two micro-switches for the robot's front bumper. These are connected to port A of the HC11. The switch is connected to the port, and the other connection on the switch is connected to ground. The port pin must also be connected to a 10 k½ pull-up resistor (connected to 5 volts). The switches I use are normally closed when the switch is OFF. Normally open switches can also be used, but the program must be changed to read them as OFF. After the "ldaa $1000" instruction, just after the "Loop:" label, insert the instruction "eora #$ff". This will invert the port's bits to work with the normally open switches.
As far as the bumper itself, I use a lightweight foam-core board, available at most drug stores or office supply stores. It can be easily cut using a sharp blade. The hot glue gun comes in handy here to attach the foam-core to the switches.
With the trp2.asm file and the as11 and pcbug11 programs on your PC, the program can be assembled and loaded with the following steps:
C: as11 trp2.asm This generates a file called trp2.s19 Plug the communication cable to the BOTBoard and apply power to the BOTBoard. C: pcbug11 -e port=2 Or port=1. Just typing PCBUG11, you will be prompted for values. >>: EEPROM $B600 $B7FF >>: EEPROM DELAY 12 >>: mm $1035 $1F $00 Enter 00, then hit the
key. >>: LOADS TRP2 >>: quit y
Remove the power from the BOTBoard and unplug the communications cable. Put the jumper on the transmit and receive pins on the BOTBoard; apply power and the robot should be off-and-running.
Given a draft of this article, I sent my son off to build a Lego version of this robot. I must point out that he has been soldering, programming, and helping me work with computers and electronics for years. He has also been a great help with my college classes and labs. (He has more hands-on experience than some of my electronics students.) His first task was to modify two hobby servo motors. Reading the above explanation, he was able to do this in less than an hour. I did have to help him remove the main screws (#22) as they were rather tight. I checked his soldering before he reassembled the servos, and his work was excellent. On the second servo, he also forgot to replace the two motor screws (#10) since he was getting excited to finish. He had a few suggestions about the servo modification instructions to help clarify the procedure, which were incorporated. I tested the servos with CCB to confirm them. So far so good.
Figure 8. Tommy's finished Lego robot.
Figure 9. Front view showing BOTBoard and bumper.
The next step was to create a Lego platform to hold the servos, the BOTBoard, the bumper switches, and the batteries. At first I continued suggesting ways for him to build the base, and then started building it myself. In the end, Tommy took apart everything I had done and built a platform from scratch (good for him). The two servos were sandwiched in the base with a platform built on top. He built an enclosure for the BOTBoard up front, and secured the battery holder on top. The only non-Lego thing we had to do was to mount the two bumper switches, using two small bolts each, by drilling four holes into the front Lego piece. A piece of foam-core was hot-glued onto the switches and he was done.
For the skid-support, he added a two-tier Lego pyramid. This slides well on smooth surfaces such as tables and kitchen floors, but doesn't slide on carpet.
We then took his robot down to the "electronics PC" to program the BOTBoard. He loaded in the program and then we headed off to the kitchen to try out his new BOT. It worked flawlessly as we chased it around the kitchen. The two-inch high bumper does not connect with our kitchen cabinet's four-inch gap below the doors. I added a six-inch high bumper to CCB which navigated the kitchen quite well.
Figure 10. Lego-BOT bottom-side.
Figure 11. Tommy explaining his robot.
Figure 10 is a close-up of the bottom of the Lego robot showing the servo motors. Figures 11 and 12 are two more views of the robot and the proud robot builder. The wheels Tommy used were larger than the wheels I use for CCB with the bumper. The small angle turns I was used to with CCB were about twice as large on Tommy's Lego robot, and the turn to go backwards resulted in a turn of almost exactly 360 degrees. (Not good to get out of a stuck corner!) By changing the constants mentioned above to half their value, Tommy's Lego BOT behaved much better.
Figure 12. The happy robot builder.
With this simple robot up and running, it can now be used as a platform to add additional sensors and, by modifying the program, different behaviors can be achieved. I plan to write a follow-on article for TRP in, which we explore additions to this robot.
I would like to express thanks to my son Tommy for his help and excitement in building a Lego version of my CCB robot. To Karen Klamm and John Piccirillo for helping review the article. Marvin Green for the incredible BOTBoard, and to SRS for their continued inspiration in robotics.
Tom Dickens works for Boeing Computer Services in aerodynamics research, and also teaches evenings.
BOTBoards Marvin Green: email@example.com Zorin HC11 Kits Christpher Nielsen: Zorin (206) 282-6061 firstname.lastname@example.org P.O.Box 30547 Seattle, WA 98103-0547 68HC11E1 chips Beall and Glenn Enterprises Machine Shop (Surplus parts) 1-800-874-4797 Route 1 Box 243 Lacey's Spring, AL 35754 Servo Motors & Wheels Tower Hobbies 1-800-637-4989 (or visit your local hobby shop) Various Electronics Active Electronics 1-800-677-8899 Digi Key Electronics 1-800-344-4539 Mouser Electronics 1-800-346-6873
HC11 MCHC11 Reference Manual (M68HC11RM/AD Rev 3): Reference for entire 68HC11 family of devices. THE source for 68HC11 assembly language. M68HC11 E Series Technical Data (MC68HC11E/D): E series specific hardware and internals reference. Motorola Contact: Motorola Literature Distribution Center 1-800-441-2447 P. O. Box 20924 Phoenix, Arizona, USA 85036-0924 (or visit your local Motorola sales office, check the phone book)
(I use the Miller book in my college class):
Microcomputer Engineering by Gene H. Miller 1993 Prentice Hall ISBN 0-13-584475-4 544 pages Microcontroller Technology The 68HC11 by Peter Spasov. ISBN 0-13-583568-2, library congress number TJ223. M53S63 1993 004.165--dc20 copyright 1993 by Regents/Prentice Hall, Englewood Cliffs, NJ 07632 The 68HC11 Microcontroller By Joseph D. Greenfield (at R.I.T. BTW) Saunders College Publishing, (Harcourt Brace Jovanovich), NY 1992 ISBN:0-03-051588-2
AS11 Motorola's 68HC11 assembler program. Free from Motorola and available from various electronic bulletin boards. Motorola BBS: (512) 891-3733. PCBUG11 Motorola's 68HC11 communications program. Free from Motorola and available from various electronic bulletin boards. Motorola BBS: (512) 891-3733.
AS11_Primer.txt and PCBUG11_Primer.txt: These are documents I have written for my students about the AS11 and PCBUG11 programs.
trp2.asm The HC11 program as published here. (see top of page for the code).