I've decided to build a mobile robot in the first week after my summer examination period in the 4th year at the university. I'd finished all exams quite early and I got bored soon doing nothing. My field was technical cybernetics so I thought I might learn something new and have some fun. Among others, I really wanted to practise soldering and this was a great opportunity.
So I did some research on the Net (meaning Google ;)) and found HandyBoard. It can do exactly what I need and it's very simple to program. HandyBoard runs special system called Interactive C which allows you to connect to the microcontroller through the serial interface and execute C-language commands in real-time right on the board. It's incredible! Simply connect your robot to a computer and using one simple command it's possible to control all motors, read inputs, send data to outputs, control display and more. It works almost like a normal unix shell. I was impressed.
Many people asked me about cost of this toy. Well, it was almost $0. I'm not kidding you :) I had to buy the printed circuit board, but it's extremely cheap and the quality is excellent, it's really worth buy. Don't waste your time and money trying to make the PCB on your own. So that was PCB, now all the electronic parts. I got them for free as samples from different manufacturers. Just register on sites like Texas Instruments and others. They will send you almost anything you want for free using UPS, I couldn't believe it :)
Now let's have a look at some specs and I'll describe the construction itself below...
In the beginning of July 2004 I decided to use Handyboard to control the robot. However, the biggest challenge was getting all the electronic parts. I couldn't find some parts with exactly the same parameters as stated in the HandyBoard documentation, but it's life... Fortunately it was easy to find list of equivalent parts so I managed to buy everything.
Originally I wanted to make the printed circuit board (PCB) by myself, but I realized that its drawing was only available as a set of GIF images and redraw them to the computer would have taken me at least a week or two I quickly decided to order over the Internet from a manufacturer in California. It turned out that it was much cheaper than if I let it manufacture here in Czech Republic. And I must say that its quality was really perfect. Non-soldering mack, metalic holes, printing on top, simply wonderful.
After about three days (I couldn't find a resistance net with 10 pins) I had finished the main PCB as well as the interface board. Everything went smooth.
If you are interested in HandyBoard schematics, they are available on-line:
Printed circuit board drawings are available as well:
My biggest problem was where to find a suitable wheelframe. It's not that easy to make at home so I went out looking for something I could use. Finally I found a flea fair where people were selling anything you can imagine. At one stall they had broken RC offroad car without the controller. I got it for less then $10 which was quite good concerning it has two-speed gear, independently supported wheels, suspension and a ballance gear unit.
Only steering design was so stupid... There was a small geared DC motor but almost no information about the actual position of the wheels. It worked with only five states:
Isn't it great? :) It was sufficient for basic steering and having fun with the car, but not for computer controlled steering. So I dove into the steering system first. The ideal solution would be to use a servo motor which can turn exactly to requested position. But I didn't know what type to use that time and it was quite expensive considering that this project was extremely low-cost. Moreover, I was facing this during weekend and had no chance to buy any servo.
But I realized that there was a (Piher) potentiometer on my desk which could do the trick. I was quite lucky because it perfectly worked with analog inputs on the HandyBoard. The solution is simple, I just fixed the potentiometer on the steering motor's axle and connected it with one analog input. There was then value in range of 0-255, but because of the different range of the trimmer I got only 25 usable values. But it's still much better than only 5 states as before.
As I said before, the microcontroller runs Interactive C [IC] which gives you the flexibility of C language, but there are some limitations. One (quite important) is that IC is missing some mathematical functions. You won't find any goniometric function (like sin(), cos() etc.). The example below is extremely simple and tries to show how to overcome this issue. Let's say you want to control your robot using classical analog joystick, but setting motor speed to the value you read from joystick is not good idea because its characteristic is not suitable for direct control. It is extremely sensitive. We need to slow down a bit around the zero point. We can achieve this by modeling a function which will map joystick value to motor speed.
The code below is extremely simple but its purpose is not to explain C language, but instead to show how
easy is to control the HandyBoard peripherals. By calling motor(motor_num, speed) we make the
robot moving, steering or turning its camera. Reading button state is a matter of one simple call as well.
So don't be afraid and dive into writing your code. It's really fun.
For those who don't feel very confident in C language, Interactive C offers one great feature. Simply connect your board to a serial port, run IC and you can control the board in real time by executing commands through the IC console. This mode is simply great for testing and finding the best settings for your application.
/*
* Simple joystick controller for a wheeled robot
*/
void main() {
int motor_0; // Main motor
int motor_2; // Steering motor
/* Table mapping analog input values to PWM.
Generated by sampling custom function in Matlab.
*/
int speed[195] = {<Insert 195 values ranging from 100 to -100 according to your
requirements and sensitivity of your joystick.>};
while(!stop_button()){
/* Main motor */
motor_0=speed[analog(5)];
if((motor_0 < 3) && (motor_0 > -3)) motor_0 = 0;
motor(0, motor_0);
/* Steering motor */
if(analog(6)<140) motor(2,-20);
if(analog(6)>160) motor(2,20);
if((analog(6)>=140) && (analog(6)<=160)) off(2);
msleep(20L);
}
}