This is a rather dated document I authored somewhere in 2002 when working on one of my earliest robots. Because of the significant drops in prices of many types of motors, microcontrollers, and so forth, and the advances in MCU design, it is mostly of historical interest today. You may want to have a look at this guide, instead: * http://www.societyofrobots.com/step_by_step_robot.shtml Other robot stuff on my homepage: * http://lcamtuf.coredump.cx/tinybot/ - my most recent design * http://lcamtuf.coredump.cx/guerrilla_cnc1.shtml - CNC robotics guide, p. 1 * http://lcamtuf.coredump.cx/guerrilla_cnc2.shtml - CNC robotics guide, p. 2 * http://lcamtuf.coredump.cx/electronics/ - concise electronics for geeks If you want to continue with this doc, be expected to bear with some atrocious grammar. You have been warned. Building a fully featured, smart robot with sight, hearing, radar and many other nice features, when you only have $50. Copyright (C) 2002 by Michal Zalewski 1) Introduction - why and how? ============================== I decided to build a robot. This is something I wanted to do for a longer while, so the decision just happened. Since you are here, chances are, you are or were thinking about it, too. Long before making up my mind, I looked over many amateur design options - this translates to anything you can build for less than $10,000 and without a CAD/CAM system or other expensive equipment (both on the net and in several books) - and, well, I wasn't particularly thrilled with what I found. Almost every single book or tutorial starts with a simple robot with one or two bump sensors or photocells that drive a very trivial circuit: run toward the light or avoids walls. Its design usually relies on pretty expensive components, varying from $100 to $300 ("Mobile Robots" by Jones, Seiger and Flynn). There are some variants that are fairly cheap, but all of them are essentially single-purpose toys. Somewhat more advanced designs follow. Those typically reuse the old design - a photocell and a bump sensor - but add a microcontroller, so you can actually program it to avoid or to follow light, or any combination thereof. This can be a bit more exciting if you plan on having few robots and programming them to interact with each other, but these designs typically go closer to $400 - a typical ready-made microcontroller board costs around $70, and so forth. Finally, some projects involve robots that can see and move around in creative ways, have an MCU capable of storing and executing a reasonably large program, etc - but the entry bar is pretty high: the mechanical components need to be custom-made; or if they can be ordered, be expected to go over $1,000 for a complete kit. Because of that, I decided to design my robot from scratch. The design described here is probably not for people who want results fast, have enough money, and want a cool-looking, futuristic robot that can bark, roll over and take family photos. It is probably good if you want a decent test platform for artificial life simulations, and like to spend time on something creative. Of course, there's no magic here. There are some things that are legitimately expensive. Don't expect to build a 6 feet tall biped for $50. My design is based on a mid-size wheel platform that can be extended to handle some gee-whiz features like a robotic hand or any other thing you can think of, but some of them will cost you more. You can argue that $50 is pushing it, but yes, I believe you can build a decent fobot for this amount of money. Technical comments: first, I'm not a native English speaker, so please accept my apologies for all the horrible grammar. Next, I'm not a robotics or electronics pro. I'm a computer guy with few other hobbies, but I don't have very strong background in either of these two. I bet there are some things that shouldn't work and worked only because I wasn't aware of this fact; feel free to point out mistakes, or suggest improvements. 2) Feature summary ================== The robot is expected to have the following features and capabilities: - Cost: $50 - sight: grayscale, roughly 64x256 in 256 shades of gray; adaptive sensitivity to accommodate low-light and daylight conditions - hearing: stereo, directional, high sensitivity - should be able to pick up whispering in the same room - up to around (16 kHz+) - speech: one-channel voice and sound output (16 kHz+) - distance sensing: precise obstacle detection with 2D radar (horizontal plane imaging) capabilities - motion: powerful motor, high ground clearance - traction control: navigation aid, pitfall and obstacle detection - extensive programming, debugging and control capabilities - some amusement features, like LEDs - highly expandable digital output and analog / digital input channels; dozens of new I/O devices can be attached with no problems. Component prices should not exceed $50. There are some optional features I will discuss here, but are not included in the base price estimate: - night vision - adds around $5 - basic robotic arm gripper - adds around $15-$20 - digital compass for precise navigation - adds around $15 (or less if you build it on your own), - constant image and radar acquisition - adds around $4 (initial design is "on demand", requiring robot to stop for a second to gather data) Plus, because the design is fairly flexible, you can add anything you find useful, or modify the design in almost any way, with very little effort. For example, if you are interested in world domination, and need a robot equipped with rotating blades and a high power laser... err, OK, never mind, I don't need any competition. Note that the $50 estimate is not the lowest price. There are some things that can be done for less, but I decided the amount of extra work needed is not worth the savings. If you really really really want to make it cheap, you can. 3) General notes ================ The instructions here are supposed to provide some general guidance, you don't really have to follow them step by step. I often do not provide exact diagrams and schematics. I almost always discuss possible alternative designs and improvements, and suggest how to handle such cases. Feel free to point out any other enhancements I've missed, and to ask any questions if you encounter problems with this design. This document used to have photographs and such, but I got tired of maintaining it as I changed the design over and over again, so no bonus. If you have problems understanding my explanations, feel free to mail me. As soon as you are done, be sure to send me a photo and a story of your robot. I will include in a gallery I'm going to start if there are people actually following this text. If you made any substantial modifications, such as altering robot's circuitry, drivetrain or software, be sure to tell me why you think it was a good idea and how well it performs :-) Make sure to read all descriptions before you start your work. I'm pretty chaotic in some places, so you need to get the picture before trying to assemble anything. I strongly encourage you to obtain and read specsheets for all IC devices we're using. You can get them easily, it's typically one of first hits you get with Google when looking for part number. It really pays, and you will learn how those things are done (open collector output?), and what features they have. I can't guarantee you good results. Heck, I can't guarantee you any results at all. You will need some knowledge about electronics, some common sense and a considerable amount of patience to get somewhere, and I can't be held responsible for any physical or moral damage, including but not limited to destroyed computers, glue vapor addiction, electrical fires, flooding, earthquakes and insanity caused by trying to build this robot. No, I'm serious. 4) Shopping for parts ===================== No, RadioShack is not a good idea. While scavenging for parts is the best method if you're on a budget, it can be also pretty frustrating and will take lots of time, so I do not recommend you to do that. Luckily, there are several places to shop for cheap electronics. First, get a phone book and look for local surplus retailers. This, unless you live far from any civilization, will save you some money on shipping. If you're out of luck, try one of the following: http://www.allelectronics.com - a good place to get some analog electronics; they have fairly cheap general purpose parts, motors, some basic ICs. They are not necessarily the cheapest place, but have good customer service, a decent web page, and a neat selection plus some good deals. http://sales.goldmine-elec.com - this is a cheaper alternative to AllElectronics, but it is also more lousy; they have not so good customer service and a really awful web page. They also have some exceptionally good prices on certain things. Another places you might want to check out that are similar to those two are http://www.mpja.com, http://www.web-tronics.com, http://www.jameco.com, but I have no experience with any of those. As far as I know, they are all fairly good. If you need some less popular IC chips, be sure to check out places like http://www.oselectronics.com and http://www.partsonsale.com first. The latter site is a bit scary, I wouldn't order from them; both sites have decent prices on some 74LS chips we'll be using a lot. Note that you don't have to buy all chips for this robot. For your first prototype, you can order samples of certain ICs for free - for example, we're going to use D/A and A/D converters from Texas Instruments. Of course, be courteous, if you order samples, consider using those in the future if they met your expectations. For purely robotic parts, be sure to check out http://www.imagesco.com. They aren't particularly cheap, but have a selection of sensors and other parts you won't get anywhere else, such as flex sensors, compass sensors, cheap robotic hand assembly, etc. But be careful, many "robotic" sites are typically a rip-off, they tend to drastically overprice otherwise cheap stuff - this is your last resort. Of relatively decent places, http://www.acroname.com also carries some sensors, but typically for few bucks more than others. With surplus stores like AllElectronics, the main problem is that they typically carry what they got from others, and what they think would sell. If you need less popular devices, or a very specific type of a chip, sensor, etc, you should go to a regular supplier. My (and everyone else's) favorite is http://www.digikey.com - they are fast, have a very good in-stock selection, and also carry components like Sharp distance sensors for less. Another good choice is http://www.mouser.com. But be careful - they both sell brand name devices. You can get 74LS154, line decoder, from Ocean State Electronics for $1.29 (no-name chip), or from Mouser, for around $5, Fairchild. Unless you are a snob, it does not really matter what brand name imprinted on the chip, and how well it sticks with its specs, or what is MTBF for this chip, is not that important for this application. You can buy cheap ones. As you can see, there's no one-stop source for all your needs. You have to decide what exactly you want to have in your robot, then shop around, noting component prices, shipping and handling fees, etc. Since it is painfully difficult to do it on-line - especially with places like Mouser (those guys tend not to have any descriptions on many items, or even list resistors by their color codes, not resistance, so searching and choosing is a mess) - you will be better off ordering a free catalog from each supplier. Of course, there's a catch. While some places are pretty fast - for example, I got my DigiKey catalog two days after requesting it - some suppliers apparently don't want you to do comparison shopping, and send catalogs after a month or so, which is probably more than you'd like to wait for it. Finally, if you are a bargain hunter, you can use eBay (http://www.ebay.com) to look for cheap components. There, all depends on your luck. The project described here does not rely on getting cheap components from eBay, but it can save you money. Also, while http://google.com is a powerful way of finding cheap stores in your area or on the web, be extra careful, there are some places that will try to rip you off big time. For example: http://www.cyberbound.com tries to charge close to $35 for Dinsmore 1490 digital compass sensor - while manufacturer price is $15, and some places sell it for even less. Since those devices are pretty rare and difficult to get, and Cyberbound pops up in Google search for this sensor, many people most likely end up paying too much. For each component that has a fixed cost and is essential for the design, I will mark the approximate price in square brackets. If you can find it for less, you win and save, if you got it for more, you lose. Note that non-fixed costs (batteries, etc), construction costs (solder, glue, wire) or basic equipment (soldering iron, multimeter) are not covered by the total cost estimate, of course. In some cases, common household components - like an empty yogurt container - can be used. I will not cover those either - you had a tasty yogurt, so don't complain. Shipping costs are not included. You may have to mail order some of the components, and in this case, you will have to spend more. Consequently, if you play with electronics, you will most likely have to spend less, because you already have a bunch of components - transistors, resistors, capacitors. Also, if you buy more devices to cover your future projects as well, you can make significant savings by purchasing larger quantities. Typically, discounts start around 10 pieces or more. If you are a newbie, prepare to spend more just to get your workplace in a shape. You will most likely ruin some components if this is your first larger project. Righty-o, let's discuss the design. 5) Chassis and drivetrain ========================= -- What is going to be built? We are going to use a trivial design with two independent motors in a rear-drive system to deliver stable speed and to make turns. The platform will be optimized for mild off-roading - going over bumps, carpets, grass. We're also going to provide power supply for the whole robot. My robot has overall dimensions around 12x9x9" (30x22x22 cm). -- What can you change or add? This is where you can show your invention. Your first choice is to decide how big your robot should be. You can build anything from a mid-size to very tiny bot in almost any shape. If you are going to use solderable perforated boards, I believe that around 5x7x2" (12x17x5 cm) or 4x4x4" (10x10x10 cm) is the limit for miniaturization. If you are ordering or etching your own PCB, you can pack more elements together and provide more connections. Your own PCB plus surface mount components will result in the smallest, most packed circuit, so you can probably make the robot something like 3x3x1" (7x7x2) or such, but - obviously - I don't recommend it for now. This is because you will need an exact project, which, without building a prototype, can be problematic, and because you will have very little space for any modifications and additions. Also, since surplus retailers typically don't have many SMDs, you will have to buy new brand name chips and spend a bit more. You can use a different drivetrain mechanism (say, treads), too. You can save money if you put together your own gear assembly or if your robot does not weight much and can be driven by a 6V DC motor directly. -- Design details First and most important choice are motors. You need to look around for a motor that matches your design. For example, if you want to build a relatively lightweight robot with smaller wheels, you can use a tiny and extremely cheap DC motor to directly power your wheels. Same if you can build your own gearhead assembly, or have retrieved it from a toy car or other device (people at comp.robotics.misc will advise you as to which cheap toys are particularly useful for this ;). If you don't feel like doing it, and your robot is going to weight a bit, you need to get a suitable gearhead motor. This is a DC motor with gear assembly already implanted inside, so that high RPM work with low torque is converted to a stable, high torque low RPM output. Higher torque is needed to provide a stable ride in various conditions, especially for robots with large wheels. If you want a plain DC motor and plan to attach it directly, try to find one that delivers less RPMs. For example, if your choice is a motor that delivers 14,000 RPM and a motor that delivers 1,200, I'd pick the latter. Those are typically quieter, need less power, emit less heat, and may have more torque. Slower motors are typically found in cassette players and similar devices, and are also carried by many surplus retailers. If you used DC motors, you've just saved around $10, and you can subtract it from the overall price. Gearhead motors are typically much more expensive, but there are exceptions. For example, Goldmine Electronics sells a gearhead DC motor that has a bridge rectifier, and, because of this, works in only one direction. They had them on sale for dirt cheap, $0.99 or such. You could either get two of those and try to get rid of the additional circuitry, or get four and install them so that each motor drives one wheel in one direction, and two opposing motors are attached per wheel. There are two things to look at when choosing a gearhead motor: its output RPMs and required voltage. For a high torque motor, you can assume that robot's top speed will be as follows: 3.14 * D * R Vmax = ------------ in/sec 70 Where 3.14 is pi, roughly, D is wheel diameter in inches, R is RPMs, and 70 is a bit more than 60 (number of seconds per minute) ;-) This "a bit more" is to compensate for the fact that RPMs are calculated in a no-load configuration, and resulting speed will be around 15% less with a medium load. Thus, if you're using 4" (10 cm) wheels and a motor that delivers 25 RPM, you should expect speeds around 4.5" (11 cm) per second, which is fairly good. You probably don't want to go below 2" per second, otherwise your robot will crawl very slowly. If you want a really fast robot, or are going to use tiny wheels, get a motor that can do 50-100 RPM. For plain DC motors with no gears, there's no better way than to just test. Their no load ratings alone are pretty meaningless, so unless you can get a full spec, it's hopeless. Another factor is, of course, required voltage. You DO NOT want to get a motor that requires 120V or such. Tops is 24V, I guess. I would suggest you to stick with 12 or 6V if possible. Ok, so you need two identical motors. I am lazy, and got myself two more expensive, reversible gearhead motors, mostly because I really suck in mechanical stuff, and my gearhead assembly would fall apart immediately. I paid around $7 for each, which is not very cheap, and most likely not the best deal. Murray McKay (check out his site at http://home.midsouth.rr.com/mmckay) pointed out that you can get cheap gearhead motors for $5.75 from http://www.solarbotics.com [$11.50]. Also, if you want to shop for something on eBay, motors are your best pick. Having motors, it is good to think about wheels. I wanted a mid size robot that can go places, so I used fairly large, 4" wheels from a baby stroller. Yes, you heard me right. Avoid so-called robot wheels, what is being sold under this name are typically grossly overpriced wheels taken from toy cars and such. If you need tiny wheels, definitely look for cheap toys, or visit one of places like Goldmine Electronics or AllElectronics, they will have some. For larger (4" ;-) wheels, it is best to go to your or your friend's basement, look for old strollers, broken lawn mowers, etc. If you can't find anything, you can always buy wheels, they go for something around $1 each [$4]. Note that you need two matching pairs. It is not necessary to have four identical wheels. You can also use a three-wheel construction, in this case, you will be better off with a swivel action front wheel like those used for furniture and such. AllElectronics have them for cheap. Getting one instead of two "fixed" wheels is a better idea for longer wheelbase designs, by the way, and I regret not doing that. Overall price shouldn't change, as you're saving $2, and this new wheel is going to cost something around this amount of money, I guess. Once you have your wheels, pick two larger ones (if you have two different pairs) or two "fixed" wheels (if you want three-wheel setup) and figure a way to attach them to your motors. If you got gearhead motors, this is just a matter of adjusting the hole size, you can do it with a drill or hot nail if the opening is too small. If it is too big, well, you're in more trouble, but don't despair - you can put some epoxy glue that is left to fix and then drilled thru to get a desired size, or you can use a million other methods, such as inserting pieces of rubber, plastic or metal to make it fit. Once your wheel fits, just glue it to the motor shaft. Note that it would be wonderful if you can do it so that the wheel is centered and balanced, at least roughly =) A note on gluing: to put the chassis together, and for some other things, you will need epoxy glues. Those are pretty nasty in handling, but perform much better than "instant" glues or cyanoacrylates. If you think you can glue heavy, vibrating gearhead motors to a metal panel with instant glue, you are wrong. There are, however, some rules that have to be observed to get good results. First, always clean the surface with some acetone or other solvent, then treat it with sanding paper. Most glue manufacturers advise you to clean the surface, but it rarely does matter if the surface "looks clean". Well, for epoxy glues, it really does matter, so don't ignore this advice. Also, those glues do not stick to well to perfectly smooth surfaces (metal panels, plastic), that's why a bit of sanding is essential. Of course, you can also mount motors in more professional way, drill holes and mount them, but many people don't have a decent workshop in their apartments, so... If you're not using gearhead motors, you have to figure a way to install your mechanism to the platform, so postpone this for next few paragraphs. Once you have wheels and motors, it would be good to get some platform to attach them to. This, I imagine, will be different for each robot - depends on the size of your robot and how good it is supposed to look. I just decided for an open design, with two $0.30 metal panels making the platform [$0.60], and all circuit boards installed on the top with full access. It does not look sexy, but is good for prototyping and gives the impression the robot is pretty complex ;-) Other ideas would include using a transparent box to house all circuitry, attaching motors directly to circuit board (hey, that's free, you just saved sixty cents) or using only very basic support like two sticks / pencils / whatever. Side note: a cheap way to get a transparent box is to use two empty containers for cotton swabs or other household stuff - some items are being sold in hard plastic boxes that are transparent. You can then put two larger pieces of both containers together and form one bigger case. Or you can just spend more, heck, pay for aesthetics ;-) Now, the robot will be rear wheel drive. There is a good reason for that - it saves us some money on "pitfall" detection. If you do not particularly care whether or not the robot will be able to detect and recover from getting to an edge of your desk or stairs, or if you don't mind spending few bucks on an extra sensor, use whatever layout your prefer. You can even use a cross-drive, where one motor controls front right wheel, and other motor controls rear left wheel. This has its advantages when turning, unless you decided to use a three wheel design. Anyway, I decided to stick with rear wheel drive. Since my motors were pretty big - roughly 4" in length - I decided to put them next to each other, in parallel, like that: _ | .-------------. | _ | motor 1 |=| | `-------------' | | .-------------. |_ |=| motor 2 | | `-------------' _| This will make the robot look a bit funky, but is actually an interesting accent. If your motors are smaller, or robot is bigger, you can use other layouts, including more conventional in-line. I glued both motors underneath one of the panels, near its shorter (rear) edge. Next step was to assemble the front panel. If you want to have a shorter robot, you can just front wheel(s) on the same panel, but I decided to use another. I attached front wheels close to the wider edge of the front panel (yes, rear panel will be longer than wider, and front panel will be wider than longer) using some nails and pads from Home Depot as an improvised "mount axle". What now? As you probably notice, there is a difference in levels of both panels, because front panel is roughly at the height of 1/2 wheel diameter, while rear panel is at 1/2 (wheel diameter + motor diameter). To compensate for it, use some padding when connecting both panels. It can be anything from few stacked coins to rubber feet. Put it in two or three places, so this joint has enough strength not to break under some load. Use enough padding to keep both panels level, this is pretty important. There's one more important component. As I mentioned, rear drive system allows the robot to recover from dangerous conditions such as stairs. This will be done by monitoring front wheel rotation. You need to add a tab, roughly the same size as motors, somewhere between front and rear wheels underneath the robot. This tab will stop robot from falling down once front wheels have no contact with any surface - since most weight is in the rear. You can use almost anything, a piece of hard plastic, metal, wood, foam. The thing you want to watch for is not to limit ground clearance more than it is already limited by motors - otherwise, it will affect off-roading capabilities. Now, let's think batteries. You can use heavy duty rechargeable cells, but I don't think this makes any sense, your robot will have fairly low power consumption, and added weight will be a problem. You can use small rechargeable batteries, of course. Unless you are severely constrained by robot's dimensions, you probably want to avoid tiny 12V and 6V batteries as well - those are pretty expensive and usually do not last for long (with some notable and really expensive exceptions). Of course, getting cheap 6V 150 mAh batteries can be a good deal for other reasons ;-) Radioshack sells such batteries for around $3.80 (stock number 23-469), and if you open one, you'll find that it is made of four A76 button cells that cost over $4 _each_. Neat, no?;) For motors that need 12 or 24V, I suggest getting two or three 9V batteries. Exceeding specifications a bit shouldn't cause any damage to motors, but if you're afraid, you might want to limit the voltage one way or another. Of course, 9V batteries will last for less than a bunch of AAs (1.5V), but carrying 16 AA batteries just for motors is probably a stupid idea. If your motors only needs 6V, AAs are just fine, but again, keep in mind that your robot probably wouldn't have to run for weeks, and there's no need to have extra load. For digital electronics, you need between 4.5 and 6V. Your best bet are AA cells. Digital electronics will not consume too much power, but this source will also drive some LEDs, a speaker, and such. Under no circumstances you want to use a shared power source for digital chips and motors. Motors generate enough electrical noise to cause some serious havoc in other places. Last power source you need is for analog sensors. Many of those devices will deliver very weak signal that is later amplified with high gain. Even a weak noise coming from the digital circuit would be needlessly amplified and would affect the quality of your robot's "senses". Since the power consumption will be marginal in this circuit, you may as well use a cheap 150 mAh 6V battery, but AA cells are pretty good as well. You need somewhere between 4.5 and 6V in this circuit. You may want to consider rechargeable batteries, that will save you money in the long run. All batteries should be placed in the rear. This is because the robot is rear wheel drive, and thus this is where most of its load should be located, to improve contact with ground. You may need some battery holders as well, but it depends on what batteries you use. 9V cells are economical, only a clip is needed, and if you don't have it, it is trivial to solder wires to battery terminals. AA cells definitely need holders. I guess it should take not more than $2 total [$2] - one AA battery holder costs around $0.50. Also add some 9V clips, probably for around [$0.50]. You're almost done. You need to test your platform - attach both motors, in parallel, to the designated power supply, reverse the polarity of one motor, so that the platform goes forward. Observe the platform. If it tends to drift in one direction over time, it seems that motor performance isn't exactly the same in both directions. You will need to compensate for it by adding a resistor later in a circuit that enables each motor to go in the direction in which it seems to work better (clockwise or counterclockwise). You can also compensate in software, but why bother... Use a potentiometer to determine the impedance needed for the motor on the side opposite to the direction of observed drift, measure its resistance with a multimeter when the robot starts going in a straight line. Note, however, that for gearhead motors, it is fairly uncommon to misbehave this way. Well done! Your total cost, if you followed my design, is $18-$19 or such. 6) Computer control and basic output ==================================== -- What is going to be built? What we need next is a way for the device to talk to the computer. I will discuss the connection, memory registers, show how to connect basic output devices, such as LEDs and motors. The robot will be controlled by a computer in the basic design. Virtually any computer, regardless of its operating system and age, should be suitable for this task. This is, of course, not as sexy as having a fully self-contained robot, but I'm not doing it to stay in the budget. As a matter of fact, converting current design to work fine with a cheap microcontroller (without A/Ds, D/As, UARTs and other magic) is more than trivial. There is another reason for that, which is that you most likely have a computer that will deliver unmatched programming, data gathering and processing capabilities, while greatly simplifying debugging and prototyping. It will be pretty painful to develop a software that performs image recognition on a cheap microcontroller without actually seeing the data gathered. You will need some extra equipment, such as an oscilloscope, to do some of the stuff for this project. With a computer, this all goes away. That said, once you have your device prototyped, it should be very easy to hook up any microcontroller with only one requirement, at least 8 input lines and 6 output lines - or at least 8 bidirectional lines - right where the signal from your computer was coming from - this is, of course, only if you want to do that. Your microcontroller wouldn't need any extra devices mentioned earlier. -- What can you change or add? You can extend the number of output lines easily. This does not make much sense in most cases, since the existing design already has numerous spare lines, but perhaps there are designs when you need to control more. You can convert the link to a wireless radio frequency relay, which should increase autonomy and range of the robot while maintaining a link to the computer. I don't have any particular suggestions in this direction as of today, feel free to suggest some cheap solutions for relaying digital signal. You can look at Maxim IC RF transceivers (and get samples for free at http://www.maxim-ic.com. I will be working on the remote control in near future, and if you're interested in co-designing it, please let me know. And, of course, you can switch to any cheap microcontroller, as described above, for example, some 8 MHz Zilog Z8s ($2.50-$3.50 or such). -- Design details First, this is not particularly challenging to build a robot by attaching wheels to your super-duper Pentium VII 5GHz computer, and sticking a cheap web cam you got with your DSL subscription on the top, but this is not what we want to achieve. The system has to be OS-independent, independent of any additional equipment, sound cards, cameras, not depending on your CPU speed, and - last but not least - easily convertible to a cheapest microcontroller. We will use the parallel port for communications, mostly because it is easy to connect to, is found in almost every computer, offers excellent transfer speeds and can be easily replaced with a microcontroller (in that lines are hooked up to a microcontroller instead of the cable). RS232 is a tempting alternative because of longer possible cable length, but it also offers lower speeds and requires a specialized chip (UART) to handle its transfer protocol. LPT is pretty much protocol-less, you can just set and read individual pins, which is very nice. We will use the port in a traditional manner, without taking any advantage of bidirectional transfers, ECP/EPP, etc. I prototyped this device with the port set to EPP, mostly because this is the default on my and most other modern systems - see BIOS setup for details, and ports that use "standard" mode may have a bit different impedance and such, so you might want to use additional resistors and open collector buffers or inverters. But first, try this circuit just as-is, and only if you're getting unexpected behavior of the device, try modifying it. If you have problems, mail me. Parallel port pinout is as follows: Pin | Name | Purpose -----+-----------+------------------------ 1 | -Strobe | Control output bit 0 2 | D0 | Data output bit 0 3 | D1 | Data output bit 1 4 | D2 | Data output bit 2 5 | D3 | Data output bit 3 6 | D4 | Data output bit 4 7 | D5 | Data output bit 5 8 | D6 | Data output bit 6 9 | D7 | Data output bit 7 10 | -Ack | Status input bit 2 11 | Busy | Status input bit 3 12 | PaperOut | Status input bit 1 13 | SelectIn | Status input bit 0 14 | -Autofeed | Control output bit 1 15 | -Error | Status input (unused) 16 | -Init | Control output bit 2 17 | -Select | Control output bit 3 18 | GND | Ground 19 | GND | Ground 20 | GND | Ground 21 | GND | Ground 22 | GND | Ground 23 | GND | Ground 24 | GND | Ground 25 | GND | Ground This port, unlike RS232, uses 0 and 5V TTL-compatible voltage levels. Note that "-" marks inverted lines. This means that the value you write to the port from software will be negated on the pin. We will use a total of 14 lines. Eight of them, data lines, are output only, and will be used to store data in control registers of the robot. This is so we can have as many output devices in the robot as we need. We will select the register we want to update and write a value there, and the value will be stored for as long as needed. Two or four control lines will be used to select a single register to be updated now. Control lines will also have other purposes, such as controlling the data sampling process, but we'll talk about it later. We're also going to use four status lines to send data back to the computer. There are five, but we're only going to use four, so that every byte sent to the computer is being delivered in two portions. This is called a nibble mode, and is much more reliable than trying to exploit specific characteristics of this or other port configuration, see excellent article by Craig Peacock: http://www.beyondlogic.org/spp/parallel.htm . I am not going to dive into this right now, just take it into account when you decide what cable you need to connect the robot. Two additional lines will go to ground pins in LPT port. Why? LPT has several pins that are always grounded. What if you run your 0V (-) from the battery to one of those pins, and then pick it up later on other ground pin, and run this new signal as a new ground for all chips? Well, the circuit would be open when LPT plug (male DB25 [$0.50]) is not plugged to a computer, and will be closed when it is plugged, thus turning your robot on automatically when it has to be turned on. I think this is a good idea to do this, saves you on a switch ;-) Of course, you can just have a conventional switch as well. You most likely want to run all pins (minus ground) from the computer thru a resistor, something around 220-470 ohm, to provide more stable operation. Resistors will cost 1.5 cents per piece if you get a bunch [$0.21], and you also need a perforated board for the main project [$1.50, but really depends on size and type, cheapest boards are around $0.60]. If you want to, you can also stick a LED connected via something like 1-4k resistor between +5v and ground (necessary impedance depends greatly on the type of this LED, you want a relatively dim light that does not consume too much power) to indicate the circuit is on. NOTE: While it may be not necessary to add resistors for output lines (output from the computer), some LPT ports will sink too much current on input ports, causing abnormal behavior and "reboots" of your robot. So at the very minimum, use resistors on all status lines. Speaking of perforated board... It may be a good idea to buy some sockets for each IC to avoid damage and simplify eventual replacement procedures. It may be a good idea to use connectors instead of soldering sensor cables directly to the board, so you can test and diagnose components with less effort. It's all optional, but pretty cheap, so why not? In my design, there will be a number of 8-bit parallel registers that can be updated asynchronously (so that you do not have to refresh all registers just to store a new value in one, which saves you time). The default design uses only two control lines to select the register - this is because you most likely don't need more than 32 independent control lines. If it turns out you need more, you can hook up two remaining control lines and address up to 16 registers, or 128 individual lines. If you need more than that, it is possible to extend this even more by introducing slow registers (that are selected by a data from other register), allowing you to extend the system almost without limits, but, of course, this does not make much sense. As a matter of fact, current design uses around 18 output lines. This is because some lines are later connected to a line decoder and used to, for example, select a sensor, so that five output lines can be used to select one of 32 input devices. This is pretty economical, and I don't expect you will need more than the default four register setup, even if you plan on adding many new things to your robot - mostly because doubling the number of sensors only needs one extra bit to be taken from the poll. Output devices are more expensive in that regard. For registers, I used several octal flip-flops, 74LS377. This chip updates its output when its clock signal raises from 0 to 1. For all other cases - 0, 1, or clock signal falling, output remains constant. The basic design calls for only three registers [$2.70], but adding new ones will be extremely trivial - you need to get new 74LS377, connect its clock to a unused output from the line decoder chip I'll talk about next. All other inputs are common for all flip-flops, and its output can be used as-is. What you need to do first is to get as many registers as you want, solder ground and +5V for each chip to where it belongs, then run D0 thru D7 from LPT to inputs of each register. Outputs form something I'll refer to as the control bus. Also, be sure to connect -E (chip enable) to the ground, so the chip is always active. IMPORTANT: input pins that are not connected to the ground or to anything else will look "high" to the chip. Always ground pins that are supposed to be low. 74LS377 (top view) _________ -E -| \_/ |- Vcc o0 -| |- o7 i0 -| |- i7 i1 -| |- i6 o1 -| |- o6 o2 -| |- o5 i2 -| |- i5 i3 -| |- i4 o3 -| |- o4 GND -|_________|- CLK Where I lines are inputs, and O lines are outputs. Pinout is a bit annoying (definitely not PCB-friendly), so pay extra attention. Note that I used 74LSxx chips for my design. They are fast enough and consume very little power, while still being cheap. You can also use any other compatible devices, from old 74xx, to 74HCTxx, but I recommend 74LS, since 74HCT are more fragile and stand only much lower loads on their outputs. Using 74xx is not necessarily a good idea because of power consumption and lower switching speeds, but it's up to you. You can even stick with CMOS series 4000. Now, you need to find a way to address registers. Get 74LS42 [$0.49], 4-to-10 line decoder, a chip that translates four input lines to signal on only one of its 10 output lines (so that 0000 sets line 0, 0001 sets line 1, 0010 sets line 2, 0011 sets line 3, etc). Of course, four lines decode to 16 states, so four combinations will result in no output line being selected at all - and will allow you to address only 10 registers, but unless you were seriously thinking about having over 80 output devices for your robot, this should be just fine, and this chip is much smaller than its full 16 line cousin, 74LS154. If you want your 128 outputs, buy 74LS154, it should be few cents more expensive, and is very similar to 74LS42. 74LS42 _________ o0 -| \_/ |- Vcc o1 -| |- i0 o2 -| |- i1 o3 -| |- i2 o4 -| |- i3 o5 -| |- o9 o6 -| |- o8 GND -|_________|- o7 Wire GND and Vcc, and ground i2 and i3 temporarily (or permanently, if you don't want to use more than four registers). Even more temporarily, connect ground to two remaining pins, and attach four LEDs to outputs o0 thru o3. Note that all LEDs should be connected by their _negative_ (shorter) lead, and positive leads should all go to +5V. Turn on your circuit - just plug it to the computer, if you decided to use an automatic on-off feature - and observe LEDs. The one attached to o0 should be lit up. Now disconnect ground from i0 and connect it to +5V. Next LED should turn on, and previous one should go down. Disconnect +5V from i0, move ground from i1 to i0, connect i1 to +5V; third LED should turn on; Finally, wire both inputs to +5V. Last LED should go on. Now, just connect two or four control lines (once again, depending on your preference as to the max. number of registers) to input pins, and connect as many registers as you have to outputs of this chip (so that o0 goes to CLK on register 1, o1 goes to CLK on register 2, etc). Note: control lines are inverted. Setting them to zero in software wouldn't select the first bank. Remember this when you try to access banks. Now, the computer should be able to select registers and store data. As you probably noticed, we hooked up LEDs to +5V instead of 0V. This mean that LEDs should light up when the pin goes down - to 0V - so that there can be a current flow. Otherwise, voltage on both terminals of the LED is roughly the same. So why weren't all LEDs on and one off? The trick is, all outputs of 74LS42, as well as 74LS154, are inverted. So, in order to update a register, we have to select it, write a value to data pins, and then, deselect it. Deselecting would make the signal to high for this pin, and would trigger flip-flops. Data is NOT stored on selection of a certain block, and data is not passed to outputs while the register is selected. The data is updated ONLY when you "leave" the register. You can now test your robot by connecting LEDs to outputs of each flip-flop block. Please refer to the software section to get the idea how to program LPT port and how to update registers. Note that it really pays to test the robot step by step, and never just assume a new chip is going to work. It will save you hours on trying to diagnose something you've missed long time ago. Of course, this is not suitable for more than driving few dim LEDs. Next, we're going to find a way to drive motors, sensors and a put some more life in LEDs and alike. In general, those chips can take much more current when they act as a "ground", just the way we connected our LEDs, but this means we will be effectively inverting the output - low value will turn the device on. If - and only if - you want to avoid this, you may add an inverter for each line that is supposed to power an output device. This is purely cosmetics, you can as well simply write inverted data to the register that controls whatever you want to turn on at the time. Having inverters is probably better, as it decreases confusion, plus, if your parallel port is uninitialized and you plug the robot in (thus setting all registers to 0), the robot may go berserk... Well, you get the idea. Moreover, by using open collector inverters, you're getting rid of some marginal but sometimes problematic voltage differences between logic "1" voltage and positive battery lead voltage - those can and will be slightly different, and may cause some devices to misbehave (for example, some LEDs may emit very dim light). They work by producing 0V output when 1 is present on the input, or "floating" (having very high impedance) when 0 is present. I used a hex open-collector inverter - 74LS05 - in the circuit. Those things are very cheap - around $0.20 [$0.20]. 74LS05 _________ i0 -| \_/ |- Vcc o0 -| |- i3 i1 -| |- o3 o1 -| |- i4 i2 -| |- o4 o2 -| |- i5 GND -|_________|- o5 First thing I did was getting a bunch of cheap LEDs (you can have a bag of assorted LEDs for $1 [$1]), and, using some silicone and old IC packaging, built a two-color display on the top of the robot. This is fairly useful, believe me, for diagnostics, expressing "moods", etc. It also looks pretty cool, if you put some effort in building it. Of course, LEDs were hooked in between inverter outputs and +5V, but before +5V, I placed a small 2k trimpot. You can just use a fixed 470 ohm resistor [$0.015], just be sure to put something there... Of course, all inputs of the inverter should be wired to outputs from a register of your choice, leaving two bits of the register free for future use. Once again, please refer to the software section for hints how to test LEDs. Also, if your robot can be turned on without being plugged to the computer, it is normal that all LEDs go on. This is because input pins of all registers are now suddenly high (not connected), and this value is stored immediately after power-up. You may solve this problem by adding some pull-down resistors (10-47k, the more the better) on each line, but I wouldn't bother, after all, it is supposed to be plugged in. LEDs are nice, but what about motors? Of course! You can't drive motors via 74LS05, unless you want to kill it and/or introduce so much noise to the circuit nothing would work as expected - that is, unless you're using some low-noise, low-power motor in a very tiny robot. I used huge and ugly motors, so this was out of question. There are several ways to drive motors while maintaining separation of both circuits, of which the easiest one is to use DPDT PCB mount low-power relays. Those can be driven directly from 74LS05. I got NEC UC-2 relays that worked like a charm, and were relatively quiet. Each relay costs something around $0.60 [$2.40]. Note that relays have polarity, and even if it is not clearly marked on the package. If they do not work, try changing swapping cables ;-) WARNING: do not place relays too close to each other. Leave some space or add some insulation to prevent one relay from triggering another. Also, place relays so that input from the inverter goes possibly the shortest way, without crossing any higher current lines that power motors. If you encounter strange "misfirings", reboots, random LEDs turning on and off when you try to use motors, you may have a problem here. Connect all relays to +5V via a resistor around 100 ohm [$0.015]. Every relay needs to have three contacts, so that one circuit is normally open, and another is normally closed. Wire first lead of the first motor to the middle (switched) contact of first relay, and wire second lead to the middle contact of second relay. Do the same for second motor with third and fourth relay. Murray suggested that many relays can draw too much current for a 74 series chip, and generate a significant current spike when de-energized. While UC-2 relays seem to work fine, if you face any problems, follow the following advice: Run the 74LS377 output through a resistor and into the base of a transistor switching the control voltage. Connect the emitter to GND via a current limiting resistor, and wire the collector to the annode of a diode and to one of the relay coil terminals. Connect the cathode of the diode and the other relay coil terminal to control power. The transistor will increase the current through the relay coil, while the diode will shunt the current induced by the collapsing magnetic field in the coil away from the 74LS377 output. Added cost = $0.23 per relay. .----|<------o o------o +5V to 74LS377 | /` relay o---------------/\/\/\/----|<` | `\| ~`---/\/\/\/--o GND Now, to the normally closed node of each relay, lead the positive voltage from your motor power supply, and to the normally open node, lead the negative. Or vice versa, just be consistent. Now, when both switches for the same motor are in the same state, there is no voltage difference, and motor is steady. When switches are in different states, there is a difference, and motor moves in one direction or another, depending on which relay is on. Note that the design I used in my prototype was slightly different, but it allowed combinations that would led to short-wiring the power supply, so I think this is a better idea. You should be able to use exactly the same software you used for LEDs to test motors. Well done! Your cost for this section is around $9. And you probably still have few LEDs left, no?;-) 7) Audio output =============== -- What is going to be built? We're going to wire a simple analog output device, which is a speaker, so the robot can make sounds and, behold, speak. -- What can you change or add? Not much; the only thing that is worth mentioning is that you can extend the design to drive more analog output devices. I can't really think of any other general purpose devices that need analog signal, so I limited the design to only one. You can also build D/A converter on your own, instead of ordering a component, but this does not make much sense, as you can have the component for free. -- Design details It may be an interesting exercise to build your own D/A converter working in voltage mode, something that can be done with a bunch of resistors, but I don't think this is particularly fascinating, plus there's a good chance that without lots of careful measuring, you'll get a crappy converter. We are going to use TLC7524, a 8-bit D/A from Texas Instruments. It is a decent and simple chip that supports only one output line, etc, etc, but is fast, accepts parallel input, wide range of single supply voltages, and is more than enough for generating sounds. You can order a sample from Texas Instruments for free [$0], or get it from other place for something around $2 (I'm making a wild guess here). We are going to use it in the voltage mode, where you can control the output voltage by writing a specific value to the converter. Then, we'll amplify the signal and drive a speaker (this is a CMOS chip and can cough up just few microamps). Well... TLC7524 _________ out1 -| \_/ |- Rfb out2 -| |- REF GND -| |- Vdd d7 -| |- -WR d6 -| |- -CS d5 -| |- d0 d4 -| |- d1 d3 -|_________|- d2 We will ignore most of its features, such as internal latches. I encourage you once again to look at the datasheet (find it at http://www.ti.com). For now, you just want to tie -CD and -WR to the ground (so that data just flows thru the converter as-is), connect data inputs to any register (I strongly suggest you to use a whole single register and skip two remaining bits in the first register. Of course, also connect GND and Vdd. The voltage mode operation is achieved by connecting out2 to the ground, out1 to a fixed input voltage (just a regular +5V is fine). Rfb should be not connected (and NOT grounded), and REF acts as the output. Now, get any cheap low-power NPN transistor - 2N3904 or such [$0.10], and a PCB-mount 40-100 kohm trimpot [$0.09]. Connect the collector of this transistor to +5V, base to REF via the potentiometer, and emitter to any cheap speaker [$0.30]. Second lead of the speaker connect to 0V. Turn the potentiometer to lowest resistance, and... well, you should be all set! Refer to the software section to see a simple program to play sound files, emit beeps, etc. .----o +5V Rvol | /` REF o-------------/\/\/\/----|<` | `\| ___ ~`------| |----o GND /~~~~~\ ~~~~~~~~~ Note: all schematics are optimized for console fonts. Default Courier New used by a webbrowser may make transistors look a bit silly ;-) This circuit, taking LPT transfer speeds in account, should be able to easily reproduce around 200,000 samples per second (200 kHz), with the limit for what a cheap speaker can reproduce and for what you can hear being probably around 20 kHz, and around 8 kHz being sufficient to reproduce sounds in a decent way that is expected from a robot, not a hi-fi set. Fair enough. This analog output circuit supports only one output device, a speaker. I can't really think of anything else that would need high resolution analog output and wouldn't work fine with, say, pulsing. But if you plan on attaching multiple devices that need analog input, that's not a big deal. You need to get some "sample and hold" devices, such as LF398, that are selected by another 74LS42 or 74LS154 connected to one of registers. Or, you can be better off getting some other TI D/A converter - for example, TLC7225 supports four output channels. But once again, I fail to see any application for this, and if you found this circuit useful for your robot, please let me know :-) Also, if you plan to use many analog input and output devices, especially for high sample rate tasks such as sound, you might be interested in compression. There are some chips that would implement some basic compression for you in the fly, and you most likely can get a sample for free, again. Texas Instruments, Analog Devices, Motorola and other big guys are your best guesses. Your costs are marginal, $0.50 or such. 8) Data acquisition =================== -- What is going to be built? I'm going to discuss how to add the ability to probe analog sensors, such as microphones, photosensors, distance sensors and, in general, all input devices a robot could have. Note that there will be no separate circuit for digital input, this is because it is actually easier to sample those signals as analog - plus, you can compress several digital signals into one analog, if you use distinct resistances for each composite line. We will exercise this design when connecting the compass sensor. I will also discuss possible scenarios for connecting sensors that have to work constantly or have low output impedance when off. -- What can you change or add? You might want to sample more input lines. This can be achieved easily. And, of course, you can attach pretty much any device you want once you get this circuit working. -- Design details Once again, we're on the mercy of Texas Instruments. A/D converters are much more complex than A/D, and I wouldn't recommend trying on your own. I decided to use TLV571, a parallel, fast 8-bit converter with one input. It is a simple converter, but has some advantages, for example, can configure self and has an internal 10 MHz clock. You can look for another chip that suits your needs better, for example, you might need 10- or 12- bit resolution, but be sure to get one with a parallel output - it is much easier to interface it to the circuit. For my design, it was most important to get a circuit that needs single supply, is fairly tolerant, has a parallel interface with output latches, and, in general, is fast and simple to use. 8-bit resolution was more than enough - two most demanding applications are sound gathering, where 8 bit gives decent results, and picture grabbing, where 256 shades of gray are a very good result. The only fault of TLV571 is that it is not really suitable for sampling data from a separate circuit. It works much better when both circuits have a common ground. This requires some extra work on relaying signfla from one circuit to another. If you want to make it simpler, feel free to look for another A/D converter with better characteristics in this regard. Your first TLV571 comes free of charge [$0], and, in general, I think it costs around $3. Here's its pinout: TLV571 _________ -CS -| \_/ |- n/c -WR -| |- AIN -RD -| |- AVdd CLK -| |- AGND DGND -| |- REFM DVdd -| |- REFP EOC -| |- -CStart DGND -| |- d7 DGND -| |- d6 d0 -| |- d5 d1 -| |- d4 d2 -|_________|- d3 First, you want to connect power. Wire -CS and -WR to the ground, leave CLK and n/c not connected and not grounded. Connect all DGND, AGND and REFM lines together to the ground (be sure to short them close to the chip!). Wire AVdd and DVdd to +5V. In this configuration, the device will configure itself upon power on for 10 MHz operation with hardware control (this chip can be also software-controlled, see the specsheet, this is not what you want). AIN will be the analog input, and to avoid random noise from being sampled when the line has very high impedance, use a pull down resistor, approximately 68k [$0.015], if I recall correctly. We will discuss what to do with d0 to d7 in a moment. Now, the sampling procedure is as follows: - Sampling starts on the falling edge of CStart, - Sampling stops and conversion starts on the raising edge of CStart, - Conversion takes 16 clock cycles and is finished by setting EOC to high, - Falling edge of RD enables reading of the converted value on d0 to d7. The internal clock is fast enough not to require us to observe EOC - we can just add a minimal delay and be sure that next read will return the converted value. This approach proved to work pretty well. So, what about CStart and RD? I wired -CStart to -Strobe from the computer, and -RD to -Autofeed. This way, the computer can control sampling directly, shortest path. Of course, changing -Strobe or -RD also changes current register, but all it takes is a simple code that remembers what should be in a register and always makes sure the right value is available on the port before changing those values. It is important to realize that falling edge of -RD actually stores data in output register of TLV571. Thus, even if we mess with -Strobe afterward, the value is safe until next -RD fall. Alright. So, how can we read data from the sensor? As I mentioned earlier, we're going to implement "nibble mode" in a clever way that allows us to read the data as fast as possible. First, you need 74LS175, 8:4 line multiplexer [$0.45]. Well, as a matter of fact, this chip consists of four 2:1 multiplexers ;-) It looks this way: 74LS175 _________ A/B -| \_/ |- Vcc A0 -| |- -E B0 -| |- A2 o0 -| |- B2 A1 -| |- o2 B1 -| |- A3 o1 -| |- B3 GND -|_________|- o3 What this chip does is that on o0-o3, it outputs a0-a3 if line "A/B" is low, and b0-b3 if line "A/B" is high. Thus, if you connect eight lines from TLV571 so that first four bits go to a0 to a3, and next four bits go to b0 to b3, you can get high or low nibble of the byte on the output. Wire the chip this way, connect +5V to Vcc, tie -E to the ground, and, of course, wire GND itself. Now, what can we use for nibble selection? Well... we have -Strobe. As mentioned above, once -RD stored output data in TLV571 and enabled reading of this information, changing -Strobe wouldn't affect the value in there. So, for as long as -Autofeed is low (software port has Autofeed set to 1), we can switch -Strobe to get two parts of the sampled data and assemble them... And how can we get output from 74LS175 to the computer? Simply, hook all four lines to four status read-back lines we have ready for this purpose... And now, it becomes obvious what is the dramatic [;-)] advantage of this method as compared to using a register to control TLV571. This is the complete sampling cycle (starting point: -Strobe and -RD hardware high): 1) set -Strobe to hardware low, sampling starts 2) set -Strobe to hardware high, conversion starts 3) set -RD to hardware low. Read the high nibble. 4) set -Strobe to hardware low. Read the low nibble. Note that sampling started. Go to 2. So, sampling of a single sensor can be executed in a three-step loop that has very few middlemen, and thus, very low latency. Not that this is that important, but I like it. Note that nibbles are not "pure", as some lines are inverted. Fix this in software. Now, go to the software section, look up the oscilloscope code. That's right, oscilloscope. From now on, you can monitor noise and signal in various places by attaching AIN (thru an appropriate potentiometer) wherever you want. This will be pretty helpful later, for now, you just want to make sure that: - TLV571 is not getting hot when working (if not, you screwed up with reference voltages or such, don't run it hot, it will break), - oscilloscope code gives you a perfectly flat line when AIN is not attached to anything else than pull-down resistor. If it isn't, try adjusting 68k resistor you put next to AIN earlier; pick the highest resistance that does not cause noise to show up; if the resistance is less than 48k, or you get flat non-zero reading, there's something wrong with the way TLV571 is wired up); note that touching the circuit or "cable soup" can contribute to noise as well; if you are getting a constant non-zero value that is a power of two, one of lines to/from 74LS175 is most likely shorted or not soldered properly. - when the oscilloscope is running, try touching AIN with one hand, and +5V with other. By changing pressure you apply, you should be able to smoothly increase and decrease readings in the range 255 to 0; alternatively, for more precision and less noise, you can use 1M potentiometer; if you get 'jerky' changes, check cabling; if changes are not smooth, you probably have input or output lines to/from 74LS175 in wrong order. Note that you can compensate for this in software. If you are getting max. readings significantly below 255, you are using too small resistor for AIN pull down, or one of lines to/from 74LS175 is not connected / shorted. - temporarily connect +5V to AIN via 220 ohm; observe the temperature of TLV571; it should not get hot. NOTE: if you are getting sudden "holes" or peaks on the oscilloscope - ones that look pretty much like this: _ _______ | | ____ ___ | | || | | | | || | | |__| || |_| But definitely not like this: |\ |\ ~-. | |/ | .-~-.- ~' \/ I.e. if observed noise has rectangular shapes, sharp edges and tends to go "jump" between extreme values - as opposed to regular electrical noise - you are most likely experiencing problems caused by your computer sucking too much current via status lines. Consider increasing resistor values, or, if that does not help, using open collector buffers or inverters on those lines. If you can't get rid of some noise, as long as it is below 2% or such, you can live with it, but it is a clear sign of something wrong with the circuit. Passed? Congratulations! No, that's not the end. This would enable you to read one sensor, and we want to have dozens ;-) First, we need a way to address sensors. The most obvious way would be to take a number of output lines from the control bus and call it a day, but this is awfully not economical. Let's take our old friend, 74LS154 [$1.29], connect it to four bits or control bus, and kaboom - we're able to address 16 devices. 74LS154 looks this way: 74LS174 _________ o0 -| \_/ |- Vcc o1 -| |- A o2 -| |- B o3 -| |- C o4 -| |- D o5 -| |- -G2 o6 -| |- -G1 o7 -| |- o15 o8 -| |- o14 o9 -| |- o13 o10 -| |- o12 GND -|_________|- o11 The question is what to do when you need more sensors? Obvious answer would be - let's take four more lines. But that's not particularly smart - 74LS174 has two "enable" lines, G1 and G2. If one is high, the chip is not active, if both are low, it is active. So, you can hook up another 74LS174 without wasting four lines, just use one line to select one chip or another (you will need a single inverter or PNP transistor for this purpose). 32 sensors is quite a lot, but if you need more, it is doable. For more than two, replace inverters with something like 74LS42, 4-to-10 decoder, this way, you should be able to hook up up to 160 sensors without any modifications and using only eight lines (one full register). Ok, so you have a sensor selector - a number of lines, of which one is low. You need to hook up a device and take readings... There are several hook up strategies: 1) non-amplified sensor that can be powered on demand; example: compass The most basic set up for devices that do not have outputs by default pulled down to GND or pulled up to +5V, you just need to control positive voltage supply for the sensor by switching it with a cheap PNP transistor, such as 2N4402 / 03. Attach +5V to its emitter, positive voltage pin of the sensor connect to the collector, and select signal (low voltage for device enable) goes to its base. You typically don't need extra pull down resistors for the base, but if you experience problems, try adding some. o +5V | | /` E sensor select (inv) o-----|<` (PNP) | `\ C | - | + GND o----- sensor >---------------o AIN (all sensors) Some digital sensors, such as Hall effect switches, may have open collector output - "0" or high impedance. Since there's no difference for the A/D converter between "0" and high impedance, you need to use a pull up resistor (10-30 kohm) to sensor's +5V input. But now, when the sensor is not used, while the transistor is in high impedance state and there's no +5V signal there, you can expect the sensor itself will have fairly low +5V to GND resistance, and your pull up resistor will effectively act as a pull down resistor. Ooops. You can prevent this by adding a small, low voltage fast switching diode to prevent flow from AIN to to +5V lead, and only allow +5V to AIN to pull up the signal: o +5V | | /' E sensor select (inv) o-----|<` (PNP) | `\ C | .-----------------+----' 16 k (pull up) | o GND `------------/\/\/\-. | | .-------------------' + - | open col. sensor > --+--------->|-------o AIN (all sensors) Some sensors may have pull down resistors. In this case, it is not enough to control power supply for the sensor, as its output is connected thru a resistor to GND, thus pulling down readings from all other sensors. There are two strategies, one is to control 0V instead of +5V, another is to enable or disable its output in addition to enabling or disabling +5V. The latter can be done in two ways - via any NPN transistor (+5V to the collector, emitter is the output, sensor output goes to base, a some resistors are used), but this method does not work well when linearity of the sensor output has to be preserved; or using a bilateral switch. Bilateral switch is essentially a device that opens or closes a circuit just like a relay, except that it is controlled by CMOS or TTL levels and is extremely fast and needs very little power. This works like a charm. o +5V | o GND | /' E | sensor select (inv) o-----|<` (PNP) | | `\ C optional pull-down | | | .-----------------+----' - - - - - - ----/\/\/\/--' | o GND | 22 k | | `--------. Ctl + - .------+--------. pull down sensor >-----| bilat. switch |----o AIN (all sensors) `---------------' Bilateral switch I used seemed to ignore the fact it is getting "1" or high resistance input (both should correspond to the same logic state), but this may be because GND to +5V resistance of the sensor was pretty low. Note that this does not have to be true for all semiconductor devices, and you may need to add a high impedance pull down for this line (few dozen kohm?). 2) non-amplified sensor that needs constant power; example: any sensor that has a considerable warm-up or acquisition time. This case may be even simpler, but definitely requires a bilateral switch. The sensor is wired to regular power supply. We don't have such sensors at the time, but I imagine that most of ready-made complex sensor devices - sonars, gyros, etc - would fall into this category. You simply enable or disable the switch using an inverted line select signal. o +5V | o GND | /' E | sensor select (inv) o-----|<` (PNP) | | `\ C optional pull-down | | | +5V | - - - - - - ----/\/\/\/--' o o GND | 22 k | | `---. Ctl + - .------+--------. pull down sensor >-----| bilat. switch |----o AIN (all sensors) `---------------' Note that you can't have particularly noisy sensors connected this way. For example, Sharp sensor mentioned earlier needs a short while to catch up after powering up, so it would be better off in here, but it also generates some awful and difficult to eliminate high frequency noise everywhere. This could affect other sensors in categories 1 and 2. Of course, you can put some filters before each sensor if you really have to. 3) amplified sensor that can be powered on demand; example: uhmm... must be some... photodiodes? This is pretty much the situation described in category 1, except that the base sensor signal itself is too weak to be used directly, and must have an amplifier. The sensor plus the amplifier is referenced to as an "amplified sensor" in this text. Simple high gain amplifiers may pick up low frequency noise present in the digital section of the circuit (coming, for example, from the computer) and amplify it beyond acceptable limits. You have to run several tests - most likely, many amplified sensors will work just fine when treated exactly the same way as non-amplified ones. But for some, you may have problems. In general, if some low-frequency noise of amplitude over 5% of the value appears in readings from a sensor, you're in trouble. Note that just sticking a huge capacitor to eliminate low frequency noise is not the answer for many devices that are powered on demand (and, thus, can be switched on and off several hundred times every second). To solve this issue, I used a separate power supply for sensitive sensors and created a completely shielded "safe zone" with no physical connections with the outside world. Unfortunately, TLV571 showed its weakness being not able to handle fully separate analog circuit properly - some other converters can do this well, as long as they have ground signal for the analog circuit provided. TLV571 is no good in that, which is confirmed by the specsheet, where it is strongly recommended to use common ground for both circuits. Because of that, I had to add several bilateral switches to relay "sensor select" signals in one direction, to the safe zone, and one optocoupler to relay analog readings from a selected sensor back. .----------. sensor select (inv) o---| inverter |----------. Ctl `----------' .-------+-------. +5V o--| bilat. switch |---. (safe) `---------------' | | .----------------------------' | GND (safe) | o | + | - amplified sensor >--. | optocoupled AIN o (for all amp. sensors) .----------------. | AIN o----| << optocplr << |-\/\/\/---' `----------------' Ropt | | +5V GND (safe) Note that an extra inverter is necessary. Use 74LS04. You will need a phototransistor optocoupler. Other optocouplers are not suitable for the task. Phototransistor optocouplers are not particularly linear, but for a typical amplified sensor, this does not matter that much ;-) You can use Ropt, an optional resistor, or pull down / pull up resistors to make optocoupler transmission to AIN as close to 1:1 as possible. You can also get a precision linear optocoupler, some places will send you a free sample, but I doubt it makes any sense in this circuit. 4) amplified sensor that needs constant power; example: microphone amplifier This design uses signal relaying exactly as in sensor class 3 described above. Devices are powered constantly from a separate "sensor" power source. Note that those have to be low noise devices. The only thing that is being switched is the output signal, this can be done with a bilateral switch. .----------. sensor select (inv) o----| inverter |-------------------. `----------' | Ctl (safe) .------+--------. +5V GND .-| bilat. switch |-. o o | `---------------' | | + | - | | amplified sensor >-' | optocoupled AIN o (for all amp. sensors) | .----------------. | AIN o----| << optocplr << |-\/\/\/----------------------' `----------------' Ropt | | +5V GND (safe) Ok, enough theory, let's try hooking up several basic and not so basic sensors and see what happens. Your total cost for this section: $1.76 9) Traction control =================== -- What is going to be built? We're going to equip the robot with a simple wheel rotation sensor to be installed on a front wheel. This will be used to determine whether the robot is actually moving (as opposed to being stuck), and at what rate it is happening. It can be also used to alert the system when front wheels have slipped from an edge, so the robot can retreat and avoid damage. -- What can you change or add? You can play with various methods of implementing this. You can use a slotted photosensor, or a Hall effect sensor (or, more precisely, Hall effect switch, this is not a linear sensor, and uses a comparator to output two logic states). -- Design details This is a good example of class 1 sensor. What you're looking for is a method to detect a number of special markings placed on the inside of your front wheel. I made the mistake of using a slotted (optical interrupted) sensor, but quite frankly, it is pretty annoying. Problems: you have to build a cover, because slot sensors can become useless in with too much ambient light; and tabs are difficult to position and will eventually fall off. It is much wiser to get a Hall effect switch [$0.45] and grab one of those flexible fridge magnet advertisements you're most likely getting with your phone book and on other occasions. If you don't have any, you can just buy magnetic tape - I have no clue how much does it cost, but I don't expect this to be too much. Place eight tiny pieces of this tape or any other permanent magnet in equal distance on the the wheel, as far from center as possible, and install Hall effect sensor so that it detects magnets (profound sentence). What now? Get a PNP transistor like 2N4403 [$0.08], hook it up as discussed for sensor class 1 - to turn +5V for the sensor on and off. Assuming the sensor is a digital open-collector device, add a pull up resistor to its +5V supply pin (NOT to the global +5V) [$0.015], and a fast switching diode [$0.08]. But check out the specsheet for your switch, as it may use a different design, better safe than sorry. o +5V | | /' E sensor select (inv) o-----|<` (PNP) | `\ C | .-----------------+----' 16 k | o GND `------------/\/\/\-. | | .-------------------' + - | Hall effect switch > --+--------->|-------o AIN (all sensors) The computer (or microcontroller) should be able to sample the sensor from time to time - for example, if wheel rotate at the speed of 4" per second, magnetic tab size is 0.3", and magnets are close to the edge of the wheel, it makes sense to sample this sensor around 30 times per second not to miss any tab (this includes a wiiide safety margin). Note that you want to keep Hall effect sensor, speaker, motors, and, in future, compass sensor, possibly far away from each other. Strong magnets will interfere with sensors when placed too close. Price for this: $0.66 (+magnetic tape?) 10) Distance sensing ==================== -- What is going to be built? We're going to attach a basic distance sensing device. -- What can you change or add? You can turn it into a full-time 2D radar (initially, it works as a line-of-sight ranger, with "radar" scans on demand); you can use a different type of sensor to get different ranges; you can attach more sensors of this kind on sides of the robot. -- Design details We're going to use Sharp GP2D12 [$9], a device that contains a tiny chip and accurately measures distance from 4 to 30" (10-75 cm). If you are willing to spend a bit more and your robot is not tiny, you can get GP2Y0A02YK instead - it works for 8 to 60" (20-150 cm). This will enable the robot to get information about problems earlier, and to get more impressive scans of its surroundings. Note that this is one of few cases where we use a prepackaged sensor. This is because it works like a charm, and it would be extremely difficult to construct your own - it uses precise optics and data analysis circuit. The device is not particularly sensitive to ambient light, texture or reflectivity. Sharp did some good work on this one. Wiring the sensor is pretty straightforward. First, hook up its +5V line exactly the way described before for class 2 sensors, via a PNP transistor [$0.08]. Hook up 0V directly to the ground, and use a bilateral switch - such as a quad combo called CD4066 [$0.30] to control output signal _with the output from PNP transistor_. Do not control the switch directly with sensor select signal, because this signal is inverted and... well ;-) Note that three switches from CD4066 are still unused. CD4066 looks this way: CD4066 _________ In A -| \_/ |- Vcc Out A -| |- Control A In C -| |- Control B Out C -| |- In B Control C -| |- Out B Control D -| |- In D GND -|_________|- Out D Since, as name suggest, the switch is bilateral, polarity of each input-output pair does not matter, it works well in both directions. Signal on Control A closes In A <-> Out A switch, signal on Control B closes In B <-> Out B, etc. In all cases, bilateral switches in this circuit are powered from the same source as all other digital circuits, and not from safe noise-free supply. Test the sensor. It should give a flat line readings that depend on the distance (non-linear) within the operational range (and fall down sharply when you're too close). My sensor has tiny one-cycle peaks on the oscilloscope from time to time, which, I believe, can be contributed to the fact of outputs being refreshed, with apparently no output latches, but if you take several samples in a row and eliminate any single-sample irregularities, you should get a very accurate reading. This is how those peaks looks like: ________________________/\______________________/\______________ There should be no visible analog noise (sinusoidal signal, irregular noise, etc). The sensor itself does produce some considerable noise returned to the circuit, there's a chance you'll be able to hear it if you listen to the speaker carefully. It does not seem to have any negative effects on the circuit itself, but will have some effect on other sensors, that is why we don't want it to be powered constantly. This device warms up for a while, but since it does not have to be sampled too often, it is ok to waste few microseconds from time to time ;-) Now, I mentioned 2D radar-alike pictures? Yes. It is possible to acquire a 2D distance map, similar to what you could see from a radar. This is essentially a plane that is perpendicular to sensor lenses, something very different from sight. There are several applications. First, this information is much more useful to a robot in recognizing places and situations than sight. Then, it can be used in conjunction with visual data to separate objects and perform 3D analysis more easily. So, how to do it? Simply put, the sensor has to rotate. There are two ways to implement it - one is "on-demand" sensing, where the robot makes a slight turn in one direction and back, while driving or stopped, to scan its environment. This is the cheap method. Another method is to use a motorized, synchronized platform that is constantly in motion - this adds few bucks for a cheap DC motor and a stable platform assembly, and we'll go back to it later. On-demand scanning gives surprisingly good results and is really simple to implement. For many purposes, this is sufficient to synthesize a map of immediate surroundings, and, for as long as robot stays in known surroundings, only rely on frontal sensor to detect movement, and confirm its position by measuring distance to known objects. Yes, this is a programming challenge, but it is not that difficult. As a matter of fact, this can be a great navigation aid. Depending on the application, you may make your robot to follow a "snake trail", swinging a bit sideways to "sniff" its environment with the sensor. You can also have more than one sensor, two sensors that are pointed 45 degrees to each side would be a very valuable addition, providing constant 2D information about passed objects, and, also, about distance to walls, etc. Sensor should be placed fairly high to have an unobstructed view. Be sure to run software channel monitoring tests to verify there's no signal snooping in any other channel than the one used for the sensor. Total cost for this: less than $10 11) Hearing =========== -- What is going to be built? Microphones are least challenging part of this. But since the dawn of dynamic carbon microphones, amplifying the signal, especially for the purpose of digital sampling, is not necessarily the most trivial thing ever. So, we're going to focus on the amplifier. Also, we're going to build two directional microphone circuits to be able to locate sound source in the room. Note that with two microphones, certain signals will be ambiguous - for example, it is not possible to tell a sound coming right from above from a sound coming from behind or from the front. This can be, however, resolved immediately by making a slight turn if the signal is considered important. -- What can you change or add? If you have some old carbon microphones (old audio equipment; old phones), you can save lots of time and some money. If you don't need the ability to locate sounds, you can use a single microphone. -- Design details First, you will need two electret microphones [$0.80]. You need to build "ears" - I used two caps from orange juice bottles, right after emptying them ;-) You can make your ears from paper or any other material, the idea is to get rid of at least some signal coming from behind, and pick up most of the stuff going on in the front. Place them on both sides of the robot, in some distance from motors. That was easy - now the fun part, a two-stage amplifier for each channel. Forget about amplifying this signal in a reliable and simple way using only transistors. Your best choice are op-amps, and LM324 is probably a good idea. Why? Because it operates from a single 5V supply, while many other op-amps need two supplies. One LM324 is enough, because it is, in fact, a four-pack [$0.50]. This is the design for first stage amplifier: +5V 100k 10k | .---\/\/\/--. .---\/\/\/--+----------|----. | | 10 uF | 220 | | \| | + +----)|-----|--\/\/\/--+-|- \ | o----' `-/\/\/\-. | >---+-+-----o to stage 2 mic 100k |---|+ / | o----. .-\/\/\/--+ | /| | - | 10uF +--|(-----' | 4.7k | +----------+----------------+-\/\/\/-' | GND And this is stage 2 (Rvar is a trimpot up to around 68k): +5V 100k Rvar | .---\/\/\/--. .---\/\/\/--+----------|----. | | 10 uF | 220 | | \| | +----)|-----|--\/\/\/--+-|- \ | o----' `-/\/\/\-. | >---+-+--\/\/\/---o output signal from stage 1 100k |---|+ / | Rout .-\/\/\/--+ | /| | 10uF +--|(-----' | 4.7k | |----------------+-\/\/\/-' | GND Note that this design isn't mine. I got it from somewhere, but I don't remember what place it was :/ It was only slightly modified to use components I had. If you have any clue who authored this circuit, please let me know. Both resistors hooked up directly to non-inverting input of each op-amp are 100k (marked only once on this schematics). Each circuit has to be built in two copies. Since we already have four op-amps, your costs are fairly low, maybe [$0.20] for resistors and [$0.80] for capacitors. Rout should be adjusted individually. It controls amplifier gain. Initially, adjust it to get some uniform, not overamplified, ambient noise, and fine-tune it to pick as much as you need (it is possible to set up this circuit to pick any whispering in the same room). In my case, required Rout was at around 100 kohm, but it will vary. Note that this circuit has to be connected in the safe zone, requiring a stable voltage and no noise. Run two select signals thru two inverters - a part of a single hex inverter IC [$0.20] - and two bilateral switches (you have some spare after hooking up the distance sensor). Both switches should essentially relay the signal directly to the output optocoupler [$0.12]. A typical optocoupler would look like this: 4N27 _____ LED- -| \_/ |- B or n/c LED+ -| |- C n/c -|_____|- E LED- should be wired to the safe ground, LED+ will be from now on referred to as "optocoupled AIN" and should be connected only to the output from two bilateral switches mentioned earlier - at least for now. E should be connected to the unsafe, regular ground in the digital circuit, and C should be connected to AIN at A/D converter. B can be pulled up and down to adjust sensitivity, but it's typically not necessary. Now it's the time to adjust Rout with an oscilloscope running. Also adjust Rvar to get a decent level of amplification (there will be fairly small window with any reasonable results). Refer to the software section for more info on recording sound. Also, be sure to run channel monitoring test to determine there's no visible snooping in other channels than two channels designated to this sensor. Your cost for this: $3.50 or such. 12) (Night) vision ================== -- What is going to be built? Something fancy :-) The basic idea is to develop a cheap vision system that can capture images of a fairly decent resolution, sufficient to perform basic recognition of places and objects. Pictures will be in 256 shades of gray, around 64x128 - it is possible to have more, but I doubt it makes much sense. The default configuration implements on-demand pictures, where only basic visual information is available while the robot is moving, and detailed pictures can be captured when robot stops. I will discuss how to implement the ability for the robot to automatically adjust to significantly different light conditions. -- What can you change or add? You can achieve higher or lower resolutions, and implement a constant image capture system capable of handling few frames per second regardless of what the robot is doing. Finally, you can use cheap CCD or CMOS line sensors if you can get one and know how to build the circuit. I will discuss a trivial night vision system as an option. I don't think it is particularly useful, but you might enjoy being followed to the bathroom by your fellow robot ;-) -- Design details The idea here is fairly simple. Since both CMOS and CCD sensors are pretty expensive and not always easy to interface, we are going to build our own photosensitive element. But, of course, even if one photodiode costs only ten cents, building, say, 32x32 matrix would cost over $100... hmm, ok, not a good deal ;-) So what can be done? We're going to use pretty much the same design as used in flatbed (and some other) scanners - there will be a photosensitive "bar" that moves ahead and scans the scene. So, to get, say, 32x128 resolution, all we need is 32 photosensors and a clever mechanism. We can also step down to roughly half the number of photosensors, and take two separate scans where existing sensors are slightly realigned to scan lines between those scanned in the previous run. Then, with software interpolation, it is possible to get even better resolution - in general, you can use as low as 10 to 16 sensors to get pictures between 40xN and 64xN, where N is pretty much arbitrary, but it does not make sense to go much over 128 or such. You can also take more than two "shifted" pictures and get even better results, but I doubt that higher resolutions are particularly useful for the robot (remember that all pictures will be 8-bit grayscale, so there will be a considerable amount of brightness information carried, more than for a typical cheap robot camera circuit). On a side note, I've seen an interesting IC - a chip with a matrix of 32x32 photosensors, and a mechanism to address the matrix and get pixel value. The chip seemed to be exceptionally easy to interface and overall pretty interesting, but its price is a bit prohibitive for this robot - over $20. Of course, there are several issues to be solved: how to build the sensor to get a row of highly directional photosensors; how to amplify and control the signal; and how to implement scanning motion. Hm... First, the sensor. It is possible to build it using phototransistors or photodiodes, but there are some problems with it. Phototransistors have fairly poor dynamic range. This is not necessarily suitable for applications with light levels that change significantly. Once phototransistor is saturated, it is saturated. There are some more expensive three-pin phototransistors that can have internal photodiode pulled up and down, but it is not economic to buy those. Photodiodes are a dream - fast, cheap and very sensitive - but those devices generate very weak signal that'd have to be run thru an op-amp for our low-light applications. They also tend to pick up 50 Hz flickering of certain light sources and so on. It is possible to build this circuit using photodiodes, but you will have to spend more on amplifying and filtering the signal. If you want to have higher resolution devices, photodiodes are a sensible alternative, because tiny SMD photodiodes cost really not that much. Photocells (photoresistor) are old-school, but pretty good. They have very wide dynamic range, and while perform a bit worse than photodiodes, their output is strong enough not to need a complex amplifier. Photocells are also fairly slow, pretty much like human eye, not seeing 50 Hz flickering and needing some time to adjust when light levels change significantly. I have to say that, do not want to insult your intelligence, but we are talking about photoSENSITIVE cells, or photoresistors, not photoVOLTAIC cells, or solar cells. So, you need a bunch of photocells. Their characteristics (dark resistance, etc) are not particularly important, but it makes sense to pick ones with as high dark resistance as you can get. I got 12 photocells in hermetic package with flat lenses (TO-18) that seemed to be NSL-06xxx manufactured by Silonex. New ones are pretty expensive, but you can often get them repackaged, with symbols removed, for really cheap, around $0.20 each [$2.40]. Note that if you have hard time finding photocells in hermetic package, you can as well use regular photocells as well, it will be just slightly more difficult to assemble everything. Be sure to check that all photocells have similar characteristics - you can measure their resistance in some ambient light, and when covered with hand, but you can also pretty much figure it out by looking at each photocell and observing its layout, number of paths and other details. Some places tend to sell you a random assortment of photocells that looked similar at first sight, but are not the same and had visual differences when you looked at the photosensitive element. For example, I ordered few from AllElectronics, all listed as the same type, and they turned out to be three different photocell types in one bag. Don't despair if differences are slight (+/- 20%), it does not matter. It will be just difficult to use a photoresistor that has 1M resistance in very dim light next to one that has 100k. 1M versus, say, 850k, is bearable. Get a piece of plastic to be used to hold photosensors, cut it to have approx. 4" length and not more than 1" width, and bend it slightly after heating up carefully (of course, you don't want to start a fire ;-). You need a slight curvature, bend it by around 30 degrees. You can also use a straight piece of stick and install photosensors to its side, arranging them carefully, but that's more difficult, so consider it a last resort. Get an opaque wire cover. I found that "empty" Ethernet cable (with wires removed) works just perfect, as long as it is black or dark. You need it to be opaque, and to absorb any light instead of reflecting it, thus black is the best choice, with dark green being other option. Remember, we're building a directional sensor. If a considerable amount of light that gets to the sensor pipe won't be absorbed, but bounced instead, the sensor won't work too well. Note that not all types of plastic are opaque to near infrared! It's difficult to test, but you can use a phototransistor - insert the phototransistor on one end, seal it well so that no light gets inside from underneath the sensor, seal the tube on the other end, and put it close to any conventional desktop lamp (regular bulbs emit lots of infrared; some other light sources do not have to). You can also light the tube with TV remote or such. Observe readings from the phototransistor, it should remain not affected by any light source. You can also use a photocell and a precise multimeter, but many popular multimeters don't go beyond around 40-50 Mohm, while a completely sealed photocell in zero-light conditions may have higher resistance. Ok, hope you found some good material. You can also use plastic covers for alligator clips - this is what I decided to use at the end - or... well, in general, almost any small piece of plastic that resembles a hollow tube. You want one end of this pipe to be roughly the size of a single photodiode - that is why Ethernet cable and alligator clip covers are so good, it fits just perfectly onto TO-18. You need to get 10-16 pieces of equal length, around 1.5 to 2" (3.7 to 5 cm) and identical shape - one piece for each photosensor. Other end of each piece should have an opening of not more than 0.1" (2 mm) - if it is more, you will get better results by decreasing it with a round piece of plastic that has a smaller opening inside. If you used covers from alligator clips, you already have the right shape, and don't have to worry. The purpose of this device is to limit field of view for each sensor to just few degrees, and to get highly directional operation within the range of approx 10-20 feet (3-6 meters). At a certain distance, fields of view for each sensor will eventually start to merge together, decreasing sharpness. Only light rays that are coming from an object directly in the front of each sensor will make it to the photosensor, others being absorbed by the tube or not reaching tube entrance at all. You will get better results if you put all sensors in a light-tight box and use real optics - but it is more difficult to put together and calibrate. The advantage of this setup is that you avoid the effect of merging fields of view for each photosensor, but since your sensors are fairly low resolution, it won't suddenly make the device see tiny objects 20 meters down the road. Optics is a good decision if you decided to build a higher resolution sensor (32 elements and up, so resolutions of 128xN and more). You need to place photocells spacing them by not more than one times sensor dimensions - but don't place them too close to each other, as you need some space for covers made off the plastic pipes you prepared. Sensors have to be spaced in a regular manner, so that all photocells form a uniform row, and each is pointed under a slightly different angle, which is caused by the curvature of the mount board. The idea here is to keep field of view for each sensor separate from others. Of course, with this lens-less design, it is not really possible to achieve this in a long run, but you can certainly achieve it in the effective working range of this sensor, that is not going to exceed few meters for precise readings - and, at the same time, you are increasing overall angle of view for whole sensor array. With 30 degree curvature, you will get coverage of approx. five feet (over 1.5 meters) vertical at the distance of ten feet (3 meters). If you need more, you can have more, just bend the mount surface more, but stay within reasonable limits, if you go to far, you can miss pretty huge objects between (scan) lines and get poor image detail for smaller objects (e.g. pets). If you want to perform facial recognition and such, I'd think about placing the sensor higher and tilting it a bit, instead of getting super-wide angle of view with high distortion. But for a robot that isn't particularly tall, it is probably better to have its eyes closer to the ground, where its environment is, and where it can find most information. Now, you want to install covers on each photosensor. If you used TO-18 hermetically sealed photocells, it is just a snap-on job - otherwise, you'll need some patience and enough opaque sealant to make it happen. Make sure that upper ends of each sensor are precisely in line, and equally spaced, forming an arc, and correct any misalignment. Then, seal everything with glue. Well done. I hope you were careful enough not to cover any photosensor with glue or other residue. Note that cyanoacrylate glues are particularly nasty for this task, as they tend to leave white residue all around the place while drying. Confirm, in ambient light, that all sensors give roughly the same resistance reading when pointed in the same direction. Chances are, they do not, but if differences are less than around 50%, we can solve it later. If one sensor gives dramatically higher resistance, it is most likely covered by a glue particle, its cover is misaligned, or something like that. Try to resolve this problem before continuing, because compensating for this problem would mean simply reducing sensitivity of other sensors to match the level of the weakest link. Now, let's select and amplify the signal. Hook up one end of each photocell to safe +5V. While it may sound odd to keep all photocells powered all the time, it seems to decrease acquisition delays needed for the signal to stabilize. Connect output of the photocell to a bilateral switch - you will need three chips, $[0.90]. Connect control lines of each switch via a 74LS04 inverter [$0.40] to sensor select signals. Then, connect all bilateral switch outputs together, via a bunch of resistors Rx [$0.18, see later], and run them to a base of a NPN transistor [$0.10]. Connect the emitter of this transistor thru another bilateral switch [$0.30] to optocoupled AIN, and its collector to +5V. Drive this last bilateral switch from any bit of the control bus. Next thing is to get two 74LS04 hex inverters [$0.40] and run twelve sensor select lines thru them, connecting inverter outputs to control lines of each bilateral switch. select signal .----------. o--------------| inverter |------------. `----------' | Ctl .-------+-------. // .-/\/\/\-----| bilat. switch |----/\/\/\-----o +5V (safe) | Rx `---------------' | +------- other bilateral switches and photocells... | | .----o +5V (safe) | | /' +---|<` .----------- Ctl. bus bit | | `\| .-------+-------. | ~`----| bilat. switch |----o optocoupled AIN `-o C `---------------' This configuration is much cheaper than using many separate transistors for each photocell, but also has a single disadvantage - bilateral switches let some current thru even when off, and this may cause the transistor to go higher than it should. The most basic way of solving this problem is adding an extra resistor, around 100k to 1M for each line (Rx) until there's no substantial voltage at point C when all bilateral switches are in 'off' position. Since we don't want to take the risk, it does not hurt to use this last bilateral switch to limit any adverse effects of this circuit on other sensors - simply, raise the control line when sampling photosensors, and turn it off in all other operating modes. Since even very dim light will saturate the transistor easily when one bilateral switch is open, we need a way to add a pull-down to its base. This can be done at the point marked as 'C' - it will be possible to pull down the base, without causing excessive crosstalk. C can be also pulled up in conjunction with pulling down to adjust contrast (amplification). Now, of course, we have to decide what resistance is optimal for C - GND connection (and, eventually, C - +5V), and you will most likely find that there's no good answer. For base resistance, pick a value that does not result in full saturation (but is close to) for the least sensitive photocell in bright light conditions - brightest environment you want your robot to handle. Use software channel monitoring for this purpose. The location for this task can be best lit spot in your apartment, or just a sunny day outdoors. Note that it is not a good idea to adjust it with photocells directly pointed to a light bulb, those are NOT the typical operating conditions. Adjust it at the ground level just as the robot would see it, and live with the fact it can be blinded with extremely bright light directly in its face. Use 1 Mohm trimpot to select the value. Once again, this is important to observe the "weakest" channel - ignore all others, even if they are long saturated. Then, replace the trimpot with a single resistor [$0.015] - you have to measure trimpot resistance first, of course. Now you can probably notice why the idea of having a single amplifier and bilateral switches, instead of many amplifiers, is better. It is not because bilateral switches are cheaper than transistors, but because it is easier to have a single pull-down / pull-up point in the circuit without causing photocell cross-talk and other side effects. Next step: attach your trimpot in line with the resistor, go to poorest lit place your robot should be able to handle, and adjust the trimpot until you get some non-zero readings from the weakest sensor. Measure trimpot resistance - the value will greatly depend on operating conditions, shape and material used for sensor tubes, and sensors themselves. In general, it should be somewhere from 20 to 500 kohm, I imagine (I could be a weather guy, temperatures from 40 to 100 degrees, and yet I'm probably wrong). Disconnect the trimpot. Warning: all measurements have to be taken in AMBIENT light conditions, sensors pointed on a white wall or such. If different sensors see different objects of different brightness, this whole operation has no value. Now, how the computer can control resistance applied between a single fixed resistor you already have, and ground, in the range measured in last step? There are several answers. You can use either a motorized potentiometer (not very efficient, but fun), or so-called "digital potentiometer". Digital potentiometers are essentially D/A converters that control resistance between two lines in a certain range in response to digital input signal. There is a huge variety of those devices, and Maxim manufactures quite a few - go to http://www.maxim-ic.com to look around. Good news - they will send you a sample for free [$0], and it costs only around $1-$2 afterward. You most likely don't want a device with serial interface, but parallel interface is a waste of control lines. There are several models that are controlled by two control lines, "increase resistance" and "decrease resistance". This is just perfect for tasks where you have constant feedback and do not care about the exact value at a given time, as long as you're getting the right result. You don't need very high resolution, everywhere from 8 to 32 adjustment steps would do. Model to be used depends on the resistance you want to achieve, have a look for example at MAX5407, but pick the one that works best for you. MAX5407 is a very clever device that looks this way: _________ High -| \_/ |- -ZCen GND -| |- Vdd W -| |- CS Low -|_________|- U/-D W is the output signal. High and Low are two opposite points of the resistor array, you can use Low for input, and leave High not connected. GND and Vdd are, of course, power supplies for the chip. -ZCen enables a special feature to enable smooth (delayed) switching, and is not needed in this circuit, you can short it to Vdd. When CS goes high and U/-D is high, the chip enters incremental mode; when U/-D is low, it enters decremental mode (note, CS is not inverted like in most other chips we've used). For as long as CS is high, rising edge on U/-D causes a single decrement or increment of chip's resistance, depending on the mode. Falling edge on U/-D does not have any effect. After CS goes down, U/-D has no effect. If you can't find anything within the resistance range you want to achieve, you can use a simple single-transistor circuit: o GND | Rres MAX5407 .+---\/\/\/--. o o |__ | | | |\ | | | | `>|-------+-----' `---- +5V Rfix /` | C o---\/\/\/-------' The idea here is that by selecting the proper value of pull down resistor Rres, you should be able to control the resistance / current flowing thru an NPN transistor in response to MAX5407 resistance. This circuit is, however, not always required. If you have to build it, add few cents for any NPN transistor and an extra resistor. Rres value should be determined by trial and error ;-) This is not a very nice circuit, but should work, less or more. Duplicate a similar circuit for pulling up, if necessary (i.e. if you're getting too high contrast in normal operating conditions). It is a good time to test all this stuff. First, experiment with driving the digital potentiometer (it can be wired directly to your control bus). You will need to hook up two lines, U/-D and CS, and there will be more detail in the software section. Make sure you are able to regulate the output from the weakest photocell in the range expected, and play with Rres as needed. Next step is to verify channel separation. Point all sensors in the direction of any bright object (yes, this time it's ok to use a lamp) and adjust it for highest (!) C resistance. All lines should be fully saturated - if not, try something brighter. Note that if you are getting slightly less than 255 from all sensors when saturated - for example, 252 - it is not a big deal, there's most likely a slight voltage decrease during amplification; large differences, however, can be a sign of unplanned pull-down condition or some other problems, and will limit the quality of A/D conversion. Subsequently, cover each sensor for approx. 10 seconds - but be careful not to cover nearby sensors. If the sensor does not start to fade down to zero during this time, something is wrong. Note that "blinded" photocells with very high pull down resistance are fairly slow, so it may take some time for it to drift down, but you should see first results in few seconds. Also check that there's no light leak and that the sensor is covered completely. Next test: put all LEDs in fairly dark environment, and subsequently short each photocell. One line should go high, but there should be no ghosting in other channels. If you get more than 1% crosstalk, examine the circuit. Now, let's take care of possibly varying readings from photosensors in ambient light. Put the robot in some ambient light that results in readings around 128 (1/2 of the scale) from the weakest sensor. Now, adjust (decrease) the opening on the top of each pipe, except for the weakest sensor, until all sensors achieved comparable readings. Yes, this is a "lame" way to do it, but surprisingly, it works, unlike, say, installing extra resistors near each photocell. Adding resistors will not work because if one photocell changes in the range of 20 Mohm to 3 kohm, and another in the range of 25 Mohm to 4 kohm, adding 5 Mohm resistor to the first one will make it work in the range of 25 Mohm to... 5.003 Mohm. Thus, resistor based adjustment will be correct only for one particular light level. The correct way to solve the problem with different amounts of light getting to each photocell is to work on the amount of light getting to each photocell (magic, isn't it). Proven most effective method of adjusting openings is to have a piece of metal wire (such as any resistor lead) wrapped around one end of each tube, forming a collar with a small handle formed on one end, so it can be screwed tighter with any tool (or by hand). Once all photocells are configured in a decent way, set up the robot in ambient, medium light, and wave your hand few feet from the sensor. You should see a noticeable (and fairly sharp / short) change in the value read from each sensor. Do not wave too fast, as you may very well miss the difference on the oscilloscope - remember that each sensor captures only a very narrow area, so your hand may be in the field of view only for a very short time when moving, and that photocells are slow, so short blink will have less effect than longer exposure. Speed is inversely proportional to contrast, in some range. Night vision feature: if you want to amuse your friends, pets or yourself, you might want to add a circuit that drives a bunch of IR LEDs to lit up the scene in total darkness. There's no particular advantage of this solution over using visible light (read: turning lights on), so... ;-) Bright IR LEDs are pretty expensive, even $1.50 each, so this is not something I'd add here just for fun. Ok, so what now? This sensor (mounted to form a vertical column), as well as the distance sensor, should be able to sweep the scene to capture a 2D picture. There are two ways to do it. One is simple and yet very effective - just attach the sensor to the platform so that it has unobstructed view and is not blinded by LEDs and other equipment. Robot will be able to make a slight turn both ways after stopping to scan the scene. This means that on-demand snapshots can be taken, at probably no more than one frame each second, but during all other operations (i.e. traveling), only a distance map and one-line input - sufficient to detect movement, light, and other significant changes in the environment - will be available. For a general-purpose robot, this may be enough, and I decided to use this design. My robot does not require constant feedback, as there's no use and no need to perform full-time image analysis or recording - so this task is performed only if something that is of any interest for the robot happens - for example, it enters a new unexplored area or encounters new conditions. But you may want to build a robot that can take pictures full-time, at something closer to 5-10 frames per second. This is not impossible, and costs only perhaps $4 more. What is needed is a cheap motor, some turntable assembly, and another Hall / slotted optointerrupter sensor. The sensor is used to tell the computer when the turntable is positioned the right way, and what is the rotation speed. The motor can be a lame DC motor that delivers 1,200 RPMs - we can feed it with high frequency pulsed signal instead of constant voltage. This will work smoothly because the turntable will have some momentum. The only problem is to balance the turntable so that it does not fall apart and/or cause excess vibrations, but this can be done by trial and error, as always. Rotation speed (and frame rate) is only limited by the speed of photocells - by increasing rotation speed, you decrease contrast. Well, that's it! Total price for this section: around $7. And guess what - this is the end of base expenses. Closing with around $50, with a good chance for less if you save on motors, or get a better A/D converter. Now, some loose ideas for optional devices: 13) Compass - optional ====================== -- What is going to be built? We are going to implement a basic navigation aid that will help the robot get back on track after being moved, and to compensate for movement inaccuracies over time. Note that this system is not particularly useful indoors, where multiple points of reference are available, but most definitely helps outdoors if the robot is supposed to be able to follow its own steps at some point. -- What can you change or add? If you want to spend a bit more, you can upgrade to a super-precise analog compass. While digital compass simply gives eight readings that indicate N, NE, E, SE, S, SW, W and NW, analog compass gives constant high resolution data. While this is possible for the robot to interpolate digital compass output to get high resolution information (by detecting exact points where direction changes and calculating its own rotational speeds and drift rates), it is more convenient to use analog device. Finally, if you want to save, you can build your own digital sensor. -- Design details In general, for short-term navigation, the robot does not need any navigation system at all. This is because it is fairly trivial to measure and code rotation rates and drive-forward rates, as well as stopping and accelerating distances and times. Your measurements, however, will be most likely rough, and a subject to small changes caused by continuous discharging of batteries, rough terrain and many other factors. Vision and distance sensing can be combined to build a map of robot's environment by mapping certain characteristic reference points. In some cases, such as very non-specific surroundings (e.g. open space or an empty room), or annoyingly unpredictable drivetrain, navigation systems can be pretty helpful to avoid error accumulation. Having one indoors also simplifies certain operations. Compass sensors are generally the best cost-efficient navigation aid that do not require any supporting installations (such as perimeter wires, reference signal sources, external cameras or triangulation devices). There are two sorts of compass sensors. One kind has no moving parts, is more accurate, sensitive and generally better, and also, of course, more expensive and more difficult to build. This design relies on having very very very very sensitive Hall effect sensors (I'm not sure, but if I recall correctly, Panasonic sells them for cheap), and a fairly complex and precise signal amplification and power stabilization circuit. As you can imagine, those sensors generate really really really weak signal. While the sensor itself is very cheap, if you look at suggested hook-up scheme and characteristics, it's tricky. Ready-made boards with all the circuitry are being sold by around $30 by Acroname and other folks. But do you really need that much precision and solid-state sensing? Probably not. A cheaper alternative is pretty funny. Since a conventional compass uses a magnetic needle in a liquid to show the direction, why not use much cheaper and simpler to use Hall effect switches to detect the needle (more precisely, its south pole)?=) Dinsmore Sensors manufactures a sensor named 1490 that consists of a tiny compass and four carefully matched Hall effect switches in a tiny case to give eight possible readings: N, NE, E, SE, S, SW, W, NW. This sensor costs around $14 at Imagesco.com or $15 from the manufacturer, and can be interfaced directly just the way Hall effect switch for wheels is interfaced. Note, however, that there's no need to waste four signal select lines. Activate all sensors at once, using the same hook-up scheme as for wheel rotation sensor, and connect sensor outputs thru several distinct pull-up resistors, so that: N is connected to signal out thru a resistor that results in input level 128 when this pin is low and 0 when high S is connected to signal out thru a resistor that results in input level 64 when this pin is low and 0 when high E is connected to signal out thru a resistor that results in input level 32 when this pin is low and 0 when high W is connected to signal out thru a resistor that results in input level 16 when this pin is low and 0 when high Of course, you do not have to use powers of two. You an also do, say, 10, 20, 40, 80. or any other values that will result in non- ambigious results for all valid combinations. 1490 uses Hall switches with an internal comparator, so there's no risk of 128 becoming somewhat less than 128 when needle is further away. It is either 128 or 0 (more precisely, high resistance or 0). As a result, you should be able to encode all eight possible states in one line, assuming there's no excess noise in the circuit. All you need is some measuring, four resistors and four diodes. o +5V | | /' E sensor select (inv) o-----|<` (PNP) | `\ C | compass + -------------+------' sensor - ----o GND | RdirN +------/\/\/\-. | | | | N > ---------|-------------+--->|-+-----o AIN (all sensors) | RdirS | +------/\/\/\-. | | | | | | | S > ---------|-------------+--->|-+ | RdirW | +------/\/\/\-. | | | | | | | W > ---------|-------------+--->|-+ | RdirE | `------/\/\/\-. | | | | | E > -----------------------+--->|-' Diodes have to be used on each output line to avoid sensors from pulling down each other. My circuit worked fine with pull-up Rdirs of 47k (N), 100k (S), 220k (W) and 510k (E). Now, let's see what resistances will be specific for each possible input state state: Dir. | Pull-up from | Resistance to +5V ------+--------------+------------------- N | S, W, E | +/- 58 kohm NE | S, W | +/- 66 kohm SE | N, W | +/- 40 kohm S | N, W, E | +/- 37 kohm SW | N, E | +/- 45 kohm W | S, E, N | +/- 31 kohm NW | S, E | +/- 83 kohm So, as you see, differences aren't that big, but the converter should be able to pick them up in this range. If you have problems with this design, you can use a different setup where resistances are in parallel, but it would require four extra PNP transistors or bilateral switches that would enable bypassing of each resistor in the circuit: o +5V | W (+pull-up) | /' E | Ctl. sensor select (inv) o-----|<` (PNP) .------+--------. | `\ C .-| bilat. switch |-. | | `---------------' | `------+---/\/\/\/---------+--. RdirW | | E (+pull-up) | | Ctl. | .------+--------. | .-| bilat. switch |-. | | `---------------' | | .------+---/\/\/\/---------+--' : RdirE . RdirN . RdirS . AIN If you have some patience, you can also build your own sensor. After all, it is not that difficult to put four cheap Hall effect switches close to a home-brew magnetic needle in some fluid, with only one challenge, that is mounting the needle on some support that does not cause too much friction. You can even use an old compass for this needle support assembly and the needle itself. You will most likely need to place sensors closer to the needle than the original construction permitted, perhaps even submerging them partially. Of course, it will take some time to set up Hall effect sensors precisely to indicate eight directions without gaps (you don't want any section where the needle is not picked by any sensor), that's why I think it makes sense to spend $14 ;-) While 8 directions is not much, this is enough to position the robot precisely. Simple: the robot can rotate, and observe the moment when readings jump from one state to another. At this precise point, we're 22 degrees from the direction that is being read. Next change will occur after precisely 45 degree rotation. This way, the robot can accurately estimate its own rotational speed, and by combining this information with the record of last reading change, it should be able to determine its direction very well. There will be some drift over time caused by changing characteristics of motors, software inaccuracies or varying terrain, but this can be compensated for by re-running the test procedure after cumulative rotation angle since last test exceeds a defined value. But you may need more precision in some cases - for example, if your drivetrain or operating conditions contribute to excessive drift, and re-running tests is not feasible. In this case, you do not have to resort to solid state sensors. What you need instead are Hall effect sensors - real sensors, I mean, without the comparator and stuff, preferably linear. The answer is home brew sensors - in this case, it will be much easier to design the compass, I believe, because you don't need that precise alignment - or Dinsmore sensors again, they carry two analog compass chips for closer to $30. If you prefer your own design, analog Hall effect sensors can cost anywhere from $1 to $10, but cheapest linear sensor I've seen was fairly close to $1, so you still can save. 14) Other sensors and devices ============================= The purpose of this section is to list other sensors and input devices that you might find interesting. Your submissions are welcome. None of the following components is a part of the base system. Sensors: 1) Gyroscope Gyroscopic sensors may be a useful replacement for compasses, and can take readings in other axis. Gyroscopes are typically expensive, from around $30-$50 per unit, and cheaper ones tend to drift over time. Main advantage: gyroscopes work even when tilted, compasses do not. 2) Pyroelectric sensors Those devices are pretty interesting, being able to sense heat, including living creatures. This is a near but not so cheap add-on that costs around $30. 3) Sonar / radar Ultrasound or RF sensors can replace the IR sensor. The main benefit is much better dynamic range and more precise operation. Once again, this is more expensive. 4) Tilt sensor Tilt sensors are cheap devices that often use mercury (phear) to detect, well, tilt. This may be a useful tool to detect when, for example, the robot is going upwards or downwards, and when compass is useless. Output devices: 1) Robotic hand. http://www.imagesco.com sells some interesting robotic parts, including a fairly cheap gripper assembly - $12, without motors, but it is most likely possible to fit cheap motors in some way. This is an interesting alternative for people who don't have their own workshop. 2) Plasma gun Err, OK, not really. 15) Software: introduction ========================== One of main concepts for the robot was to make it easily controllable from any platform and any computer, old or new, using a language of your choice. This is achieved by using a parallel port interface and a simple transmission protocol where speeds are controlled exclusively by the software. This functionality can be easily moved to a very simple microcontroller or microprocessor, if needed. For the purpose of demonstrating basic software control, I will stick with the programming platform I know best, which is GNU C on Linux, but the code, with some minor changes, like removing or replacing iopl(), should work just fine on other systems, with the exception of the oscilloscope, and picture acquisition coe - this is because both use SVGAlib, a console graphics library that is pretty specific to Linux. This is not to say it would be difficult to port the code to any other graphics library. . The entire design is highly portable across languages, since almost every decent language supports direct port access, the only thing needed to talk to the robot. There are some considerations for setting up the operating system. While you don't need a real-time system, you most likely want to get as close as possible - for example, MS Windows deciding to swap out huge portion of memory, clean up some temporary folder, or start a screen saver while your robot is making a turn is not something you really want to happen, especially while your robot is making a precise turn or operating in some risky conditions (approaching stairs). Since Windows is a GUI environment with very little low-level control over its performance and scheduling policies - not to mention, it is much more resource-consuming than CLI alternatives. If you experience problems with controlling the robot under Windows, you may want to move to DOS instead. Linux is better than Windows, but only if you take some minimal care. You want to temporarily disable swap, shut down X Windows, crond, and other resource-consuming processes and subsystems. This is not because the software will need all CPU power, but because it will need uniform chunks of CPU time in predictable time intervals. Other large applications can consume resources for a longer while, putting your robot in danger, or, at minimum, causing it to misbehave. Linux also has another interesting feature, FIFO scheduling. To enable it, you will need to download the following program by Marcin Kaminski: http://lcamtuf.coredump.cx/soft/sched.c This trivial proggy will allow you to specify high-priority, first in first out process scheduling method for the robot control code (or any other program). Well, that's pretty much it... If you want to develop a port of this code to any other language or platform, or if you have your own robot software that is interesting and worth sharing, please let me know, I'd be pleased to mention or publish it here. 16) Software: underlying I/O library ==================================== First, we have to develop a basic library for talking to the robot. The following API will be written: void robot_init (void) Initializes the library, the robot, and calibrates timer loops. void robot_shutdown (void) Resets the robot and LPT port to its initial state. char set_register (char x, char val) Sets entire register 'x' to value 'val'. Old value is returned. Register update is not immediate. char set_reg_bit (char x, char bit, char val) Sets a single bit 'bit' of register 'x' to value 'val' (0 or 1). Returns old value. Register update is not immediate. void flush_register (char x) Forces register update for register 'x'. int start_timer (void) Creates and starts a new timer that is being returned by this function. char wait_to (int timer, int delay) Waits till the timer 'timer' (returned start_time) reaches 'delay' microseconds. The time is counted since start_time. This function is useful for timing I/O operations to wait a constant time regardless of how much time it took to execute code so far. wait_to() returns 0 if waiting was successful, or 1 if timer was already past the moment 'delay'. Note that default operating system based timing facilities usually have minimum threshold of 1000 microseconds, which is not acceptable. void get_samples (char sensor, int scnt, int idelay, int sdelay, int slen, char *data) Gets 'scnt' samples from sensor 'sensor'. Initial delay of 'idelay' is used after selecting the sensor (for eventual warm-up time), and 'sdelay' is used for delays between subsequent samples. 'slen' is sampling time for each sample. Results are stored in the array pointed by 'data', which has to be at least 'scnt' bytes long. 17) Software: basic commands ============================ Controlling output bus 18) Software: oscilloscope ========================== Simple SVGA oscilloscope 19) Software: sensor monitoring =============================== Multi-sensor scanner and bar signal strength viewer. Also, interpreting data from wheel sensor and compass, if equipped with; smoothing up and translating distance sensor output. 20) Software: sound recording and playing ========================================= First, playing back RAW files Then, recording sound 21) Software: picture acquisition ================================= Software image display, of course. Some support for MAX. Interpolation, multisampling. 22) Software: the main code =========================== Some fancy drive-around code.