I too have noticed the "nervousness" of my car and other line following devices. I made a line follower out of LEGOrobotics last summer. It too was too nervous to make fast progress.

For my project to progress from its present state I need to:

1. Get my hands on an appropriate RC vehicle. The "stadium truck" style has been suggested. It has two wheel drive, excellent miniature steering and suspension, and a broad flat frame structure to which it would be easy to attach my PIC and things. Thing is they are expensive. If I get a "ready to run" it's about $200. It will have a two channel RC. I need three channels - anther $100 or so.

2. Corral the help of some friends with access to the correct facilities to help me design and build a robust kit that can be attached to most any RC 1/10 scale vehicle.

3. Prototype a "simple" state machine structure for my PBP code. Non-computer nurd middle schoolers will throw up their hands in dismay if they had to code PBP from scratch for this 'race'. I have neither the resources nor the contacts to create a LOGO or ROBOlab like language.

4. ioannis suggests potentiometer based motor control to calm down the bot's oscillations. My inclination is to try to get my HPWM signal down to the RC spec of fifty pulses per second. With my present code one gradation plus or minus on my PWM pulse width is the difference between stopped and going pretty fast. I saw this plan (below) for Interrupt driven PWM, but I have not yet studied it.

-------------here's what I found------------


1) Decide on the resolution (the number of steps between off and 100% on. Go with 16. That's plenty.

2) Decide on a PWM frequency. Go with 30Hz. It sounds odd, but the reason becomes apparent next.

3) Set a 1:8 prescaler on an 8-bit timer.

4) Create a label "Count" and set it to the resolution (16).

5) Create a label "Demand"

6) In the interrupt service routine for the timer interrupt:

6.1) Decrement Count

6.2) When Count becomes zero, set it back to the resolution value again (16).

6.3) If Demand > Count, set the PWM output bit. Otherwise, clear it.

There you have a single PWM output. Put a value from 0 to 16 into "Demand" and the PWM output will perform accordingly. If you want two outputs, you create two Demands and perform two comparisons. (You only need one Count.)

What happens is that (assuming a 4MHz clock), this will interrupt every 256*8=2048us. Each time, the counter decrements by one. This happens 16 times meaning that each of your unique mark to space ratios is 2048us apart and that your PWM time is 2048 * 16 = 32768us, or 30.51Hz.

If your demanded PWM value is less that the PWM counter, then your PWM should be marking, otherwise, you should be spacing.

Of course 30Hz might be a bit lumpy. Swap your 4MHz crystal for a 20MHz one and suddenly you're at 150Hz. Irritatingly audiable. Your options are to reduce your resolution (half the resolution = double the frequency) or reduce your total pulse time (half the pulse time = double the frequency).

The disadvantage of reducing the resolution is obvious. The disadvantage or reducing the pulse time is that it leaves you fewer free processor cycles for your "main" program. In the example above, your interrupt is only called every 2048 cycles. Assuming it costs 200 cycles (that's generous) to process the interrupt, that leaves your main program 1948 cycles between interrupts.

You could come down to a 2:1 prescaler with a PWM resolution of 8 and a clock of 20MHz. that gives you a PWM frequency of 20/4/(2*256*8)*1000000 = 1.22kHz. BUT there are only 512 operations between interrupts then and 200(ish) of hem are taken up servicing the interrupt itself.