VCR Robot - Description

1. General.

Like every robot builder that wants to teach others how to build robots, I have built a sample robot, using parts from VCRs and bought only the minimum necessary to make the simplest robot I could think of. At the time I was using the Nemesis microcontroller, produced by Kronos Robotics, however this was not a good choice for Romania, because import taxes would have made their price almost double. Nemesis is a PIC 16F88 with a pre-programmed bootloader. This feature allows the user to program it from the serial port of the PC through a logic level adapter. Kronos Robotics also provides Athena, a free Basic compiler, lots of sample code and great support. Basic is easier to learn by young people, so I thought it is a good choice for beginners. And Nemesis costs only $12.95. A PIC 16F88 costs about $3, but needs a programmer (the cheapest I could find is $40) and the PBasic compiler costs $99. Too expensive. Now I would use an AVR ATtiny26 and Bascom-AVR for programming, cutting the price to about $15 for the whole project. 

Here is a movie with the robot driving (fast) avoiding to crash into obstacles:

Parts list.

The only parts you will need to buy for this project are the Nemesis microcontroller, the SN754410 motor driver IC, a prototyping board, the LM2940 voltage regulator, a battery box, 18 pin and 16 pin DIP sockets, a 5 pin female socket, a strip of breakable male pins. I also bought a serial lever shifter to program the microcontroller from Kronos Robotics website.

All the other parts you can get from a VCR, but you will need 2 VCRs to get 2 identical motors. You will also need a few cable ties, a couple construction nails, wire, a couple small wood screws and 4 AA batteries. 

NoItemCost $ eachQuantityWebsite and part number
1Nemesis12.951Kronos Robotics #16406
2Easy 232 serial adapter9.951Kronos Robotics #16167
340 pin straight header0.991Kronos Robotics #16290
4SN7544101.881Digikey 296-9911-5-ND
5LM29401.801Digikey LM2940CT-5.0-ND
6HOLDER BATT 4-AA CELLS WIRE LDS0.771Digikey BH14AAW-ND
7Conn header 0.1" single R/A 5PO F0.441Digikey S4105-ND
818 DIP socket0.941Digikey ED3318-ND
916 DIP socket0.831Digikey ED3316-ND
10Grid-Style PC Board with 356 Holes1.791Radio Shack 276-149
 Total cost$31.88  

On the Electronics  page we will go over the schematic to see how things work.

VCR Robot - Electronics

2. The electronics.

Let's take a look at the schematic: 

VCR robot schematic  

The main part (IC1)is the Nemesis microcontroller, the robot's brain. As you can see, it has 15 general I/O pins, 7 of which are connected to the internal Analog to Digital converter and 2 are connected to the built in UART (serial) interface and a Reset pin (Attn). It runs at 8MHz and it has 1024 bytes of memory for user programs. It also has a timer that can be used to generate PWM signal on pin 6.

IC2 part is the SN754410E Quad Half H-Bridge, which is the motor driver. This IC can drive 2 DC motors or one step by step motor. It provides currents of up to 1 amp per motor (or winding). The IC has 2 Direction pins and an Enable pin for each motor. If the Enable pin is set to high, the motors are powered, otherwise they can spin freely. If pin A is high (1) and pin B is low (0), the motor spins clockwise, if the pin A is low and B is high, the motor spins counterclockwise. If both pins are either high or low, the motor is braked (the output pins connected to the motors are short-circuited - if the power is cut when the motor is spinning, the motor becomes a generator, but the generated current will go back to the motor and make the motor spin in the opposite direction, slowing it down fast and after a complete stop, it makes the motor resist spinning). This H bridge IC has internal clamp diodes to protect the circuit from the back generated currents. The IC is powered from regulated 5V but motors are powered directly from the battery. This way they can get bigger voltages and current than the rest of the circuit.

The U1 part is a PNA4613 Photo IC. This IC is an infra red photo transistor with an internal filter that allows only 40 kHz modulatedsignal to pass. It has an internal pull up resistor, so in the absence of a signal the output pin is always high. This IC is regularly found in TVs and VCRs as the remote IR signal receiver. We can use this IC to remote control the robot using a Sony TV remote, or as a proximity sensor, to detect objects in the robot’s path from a certain distance, together with the 2 IR LEDs (IRLED-LEFT and IRLED-RIGHT) flanking U1. The proximity sensor works like this: the microcontroller generates a 40 kHz PWM pulse one of the LEDs for a short time, then it turns is off and checks the sensor pin 5. If there is an object in front of the LED, some of the signal will be reflected back to the sensor and the pin 5 will get low. Then it will flash the other LED and check the sensor again. This way the robot can “see” an object to the left, right or both (center). But there is only one pin that can generate a PWM signal, how can we control 2 LEDs? We connect the anodes together to the pin 6 and each cathode to a separate pin of the microcontroller. We set those pins to output and we set them high. The LEDs will be lit only if we set those pins to low. So, when we want to flash the left LED, we turn his output pin to low and then generate the signal. After we check the sensor we turn the left LED’s output pin back high and turn the right LED’s output pin low and generate the signal. And so on. But what is the R3 adjustable resistor for? We use it to adjust the sensibility of the proximity sensor.

There are 3 pairs of IR LEDs – IR Photo Transistors, that form 3 IR reflective sensors, used to follow a black line on a white floor or to detect the edge of a sumo ring. They work like this: the IR LEDs are lit at power on and the microcontroller checks the IR Transistor pins. Because of the 10 kOhm resistor pull ups, the pins are high if there is no light reflected and they are low if there is a reflection. So we will get a 1 if there is black or a 0 if there is white underneath the sensor. We can adjust the sensibility of the sensor from the R6 adjustable resistor.

The circuit is powered from a 6V battery pack (4 AA alkaline batteries). After the power on switch, there is a 5V 1A Low Drop-Out voltage regulator, LM2940. I chose this regulator because the regular 7805 needs an input voltage of minimum 7.2V. C3 and C4 compensate for voltage drops when motors are powered up or switch directions and R1 and LED1 are used as a power on indicator.

The serial connector is used to program the microcontroller and debugging. R1 is used to pull up the reset pin and C1 and C2 are used to filter out any noise and power sags on the microcontroller. 

Here is the schematic of the serial adapter:

 Serial adaptor schematic  

And for those who want to cut the price in half, here is the schematic using AVR ATtiny26: 

Schematic using Tiny26

Now let's see how to build the Mechanics...

VCR Robot - Mechanics

 3. The mechanics. To keep costs low I have merged the chassis and electronics board together and mounted all on a perforated prototyping board. Besides the microcontroller, the H Bridge, the voltage regulator, a couple of nails and a few screws, all the other parts I pulled out from a couple of broken VCRs found on the side of the street. They were different brands, but inside they looked the same. I needed 2 VCRs because they rarely have 2 similar DC motors inside. But here’s what I got: 

DC motor with belt and wheels for the robot…

 VCR image - motor and belt  

 

On-off switch…

 VCR image - on-off switch   

 

IR photo diodes and LEDs, resistors and capacitors…

 VCR image - IR photo transistors and LED  

 

PNA4613 or something compatible, push buttons…

 VCR image - IR sensor     

 

And now, let’s see how we can attach wheels and motors to the chassis:

Robot image - nails soldered to the board  

Using a couple construction nails soldered to the perforated board as wheel axles! And drill 4 holes for each motor and tie it up with cable wraps! Don’t forget to twist the motor wires and solder 0.1uF ceramic capacitors between the motor leads and from the leads to the motor case. This will cut the noise to the circuit drastically:

Robot image - motors strapped to the board  

Then plant the parts, using sockets for the ICs. Solder everything. Then start to make connections between pads according to the schematic using thin wire. Insert shrinkwrap tubing around the LEDs to shield any side IR light that might influence the sensor.

Robot image - parts top

 

 

Robot image - parts bottom

 

Now we need a third wheel… Using a plastic bushing I had in a box and a piece of metal from a VCR I made a small caster for the robot. Using 2 small wood screws I attached the battery box to the board.

Robot image - castor wheel and battery box 

 

 

Insert the batteries and program the robot.

Robot image - batteries 

Let’s check if it is working… Yes! The on/off LED indicator is lit, wheels start to spin fiercefully!

Robot image - all done

Now let's see if the sensor is working properly. As you can see in the picture, the left LED is lit but the right one isn’t. And the debug window shows: Left 1  Right 0

Good!

Robot image - working

 

 

To see how I've programmed the robot, check out the Programming page...

VCR Robot - Programming

4. Programming.

 

Have a look at the program:

 

 Nemesis

'===============================================================

'VCR Robot with 2 DC Motors and 1 dual IR proximity sensor

'Random driving with IR headlights'Compiled program size: 176 bits (out of 1024 bits)

'===============================================================  

'--------------------------------------------------

'Variables declaration, labels, timer

'-------------------------------------------------- 

dim LeftIR           ' variables to store the values of the

dim RightIR          ' IR sensor for left and right directions 

const Motor1a      8   ' right motor

const Motor1b      9   '

const Motor2a     10   ' left motor

const Motor2b     14   '

const MotorEn     13   ' enable motors  

const IRsensor     5   ' IR sensor pin

const IRpulse      6   ' pin used to generate the IR pulse 

const LeftIRLed   11   ' left proximity IR LED

const RightIRLed   7   ' right proximity IR LED

const RightLineS   1   ' right line sensor

const CenterLineS  2   ' center line sensor

const LeftLineS    3   ' left line sensor 

hwpwm 0,50,15          ' pwm signal 40KHz 60% "on" time  

'=================================================================

'Main program

'================================================================= 

output Motor1a     ' we declare the direction of the I/O pins 

output Motor1b     ' for the motors and IR LEDs to  

output Motor2a     ' "output" and set the value to 

output Motor2b     ' "high" or "low". 

low Motor1a        ' all undeclared pins will be set to 

low Motor1b        ' "input". 

low Motor2a 

low Motor2b  

output LeftIRLed 

output RightIRLed 

high LeftIRLed 

high RightIRLed  

output MotorEn 

high MotorEn       ' turn on the power to the motors 

Mainloop:  

'------------------------------------------------- 

'Read the sensors 

'------------------------------------------------- 

  gosub ReadIRSensor  

'------------------------------------------------- 

'Print all sensor values in Debug window 

'-------------------------------------------------

  print "Left ",LeftIR,"  Right ",RightIR  

'------------------------------------------------- 

'Decide where to go 

'-------------------------------------------------

  if RightIR = 0 then    ' obstacle to the right

    gosub ReverseLeft    ' reverse left motor

  else                   ' no object

    gosub ForwardLeft    ' forward left motor

  endif

  if LeftIR = 0 then     ' obstacle to the left

    gosub ReverseRight   ' reverse right motor

  else                   ' no object

    gosub ForwardRight   ' forward right motor

  endif 

goto Mainloop            ' start again 

'=================================================================

'Subrutines

'================================================================= 

'-------------------------------------------------

'Motor control subrutines

'-------------------------------------------------

ForwardRight:

  low Motor1b

  high Motor1a

return 

ReverseRight:

  low Motor1a

  high Motor1b

return 

ForwardLeft:

  low Motor2b

  high Motor2a

return 

ReverseLeft:

  low Motor2a

  high Motor2b

return  

'-------------------------------------------------

'Read the IR proximity sensor subrutine

'-------------------------------------------------

ReadIRSensor:

  low RightIRLed            ' set active the right IR LED

  output IRpulse            ' start the pwm pulse

  pause 1                   ' wait a milisecond

  input IRpulse             ' stop the pulse

  RightIR = inp.IRsensor    ' read the value

  pause 1                   ' wait a milisecond

  high RightIRLed           ' deactivate the right IR LED

  low LeftIRLed             ' set active the left IR LED

  output IRpulse            ' start the pwm pulse

  pause 1                   ' wait a milisecond

  input IRpulse             ' stop the pulse

  LeftIR = inp.IRsensor     ' read the value

  pause 1                   ' wait a milisecond

  high LeftIRLed            ' deactivate the left IR LED

return

The program is easy. First there are the variable, ports and other stuff declared, so the microcontroller knows where the sensors and motors are connected. Then the main program starts a loop that reads the sensor, prints the values on the Debug window on the PC, decides how to drive then loops. Let’s take them one by one: 

 

1. Declarations. We need to set 2 variables to hold the sensor values for later operations. Then we need to specify the pins where the sensors, motors and LEDs are connected. All the pins that will be used as outputs have to be specifically set so, otherwise they will be set as inputs by default. And the microcontroller needs to know what state they need to be (high or low). Most important, we need to set the hardware PWM generator for a signal of 40 kHz and 50% duty cycle. 

 

2. IR sensor reading. Here I have used only one sensor and 2 LEDs to build a dual IR sensor. I turn on one LED at a time for a short while, read the sensor and store the value in a variable, then turn the other LED on and read the sensor and store the value in an other variable.  

 

3. Print the values. This is a simple print to serial port to be able to adjust the sensitivity of the sensor. When you do the adjusting, take off the jumper so the motors don’t get power. You don’t want the robot to fly off the table with the serial adapter connected to it. Also take the jumper off every time you program the robot. To adjust the sensor sensitivity, take a sheet of paper and put it vertically in front of the robot, about at the distance you want the robot to start to see the obstacles in it’s path. Then adjust the resistor until you see the values on the screen change from 1 to 0. Keep in mind that different colors reflect IR differently, so the robot will not always turn away at the same distance. 

 

4. Driving decision. Now imagine you are onboard of a tank. You have 2 joysticks to control the motors. Pull the sticks and you drive forward. Push the sticks and you go on reverse. To turn you have to push one stick and pull the other. But instead of windows you have 2 lights. If left light turns on, you have an obstacle on you left. If the right light is on, you have an obstacle to your right. And if both lights are on, the obstacle is in front of you. So, you drive forward (pull both sticks), if the left light suddenly turns on, what do you do? You just push the right stick until the light turns off, then pull it back. For the right light, you push the left stick. And for both lights, you push both sticks to drive in reverse for a while and then turn either left or right. 

 

5. Loop. For a human the action described above seems continuous. But for a robot is a continuous loop that checks the sensor and decides how to drive for a little period of time. This time period depends on the time the robot takes to read the sensor and the time it drives after the driving decision (if needed). Depending on how little or how large this period of time is, the robot will react faster or slower to the changes in it’s path.  This program is very simple and can be used for driving with bumper sensors, IR photo reflective sensors (for line following), or, with a few modifications, can be used for sumo combat. 

To complete the robot, I have built a daughter board that mounts underneath the robot and holds the IR photo reflective sensors for line following. See the result on the Add-on page…

VCR Robot - Upgrade

5. Upgrade 

For line following I have built a daughter board that gets mounted under the robot so the sensors are closer to the ground. On the main board I have soldered 2 pieces of 3 pin female connectors. On one of them I have connected the power and ground and on the other the 3 signal lines for the sensors. On the daughter board I have soldered 3 IR photo transistors that I have pulled out from a VCR spaced about 3/8 of an inch from each other. In between them I have soldered 2 IR LEDs mounted in some LED holders so that the IR light will not get sideways to the photo transistors. I have installed an adjustable pot so I can adjust the sensitivity of the sensors. Then I made the connections to 5 pins installed 3 on one side (signal lines) and 2 on the other side (power and ground lines). 

Daughter brd - bottom view

Daughter brd - front view   

Daughter brd - side view   

Here is the program: 

Nemesis

'===============================================================

'VCR Robot with 2 DC Motors and 3 IR line sensors

'Line following

'Compiled program size: 280 bits (out of 1024 bits)

'===============================================================  

'--------------------------------------------------

'Variables declaration, labels, timer...

'-------------------------------------------------- 

dim Lvalue,Cvalue,Rvalue,Cvalue2,Rvalue2

dim state,dir 

const Motor1a      8   ' right motor

const Motor1b      9   '

const Motor2a     10   ' left motor

const Motor2b     14   '

const MotorEn     13   ' enable motors  

const IRsensor     5   ' IR sensor pin

const IRpulse      6   ' pin used to generate the IR pulse 

const LeftIRLed   11   ' Left proximity IR LED

const RightIRLed   7   ' Right proximity IR LED 

const RightLineS   1   ' right line sensor

const CenterLineS  2   ' center line sensor

const LeftLineS    3   ' left line sensor  

'=================================================================

'Programul principal

'=================================================================

Main: 

'=================================================================

'Main program

'================================================================= 

output Motor1a     ' we declare the direction of the I/O pins 

output Motor1b     ' for the motors and IR LEDs to  

output Motor2a     ' "output" and set the value to 

output Motor2b     ' "high" or "low". 

low Motor1a        ' all undeclared pins will be set to 

low Motor1b        ' "input". 

low Motor2a 

low Motor2b  

output LeftIRLed 

output RightIRLed 

high LeftIRLed 

high RightIRLed  

output MotorEn 

high MotorEn  

'---------------------------------------------------------------

'Line following program

'---------------------------------------------------------------

Linefollowloop:

  ' read the sensors

  Lvalue = inp.LeftLineS      '0 means white, 1 means black

  Cvalue = inp.CenterLineS

  Rvalue = inp.RightLineS

  ' calculate the state value

  Cvalue2 = 2*Cvalue

  Rvalue2 = 4*Rvalue

  state = Lvalue + Cvalue2 + Rvalue2

  ' show the values on the Debug window

  print "Left ",Lvalue,"  Center ",Cvalue,"  Right ",Rvalue,"  State ",state 

  ' decide how to turn by the state value

  branch state,do0,do1,do2,do3,do4,do5,do6,do7

goto Linefollowloop 

do0:                 ' 0 0 0 -> no sensor over the line

  if dir == 0 then   ' decide by the direction of the last turn

    gosub Tleft

  else

    gosub Tright

  endif

goto Linefollowloop 

do1:                 ' 0 0 1 -> left sensor over the line

  dir = 0            ' remember this turn direction

  gosub Left

goto Linefollowloop 

do2:                 ' 0 1 0 -> center sensor over the line

  gosub Fwd

goto Linefollowloop 

do3:                 ' 0 1 1 -> left and center over the line

  gosub Tleft

goto Linefollowloop 

do4:                 ' 1 0 0 -> right sensor over the line

  dir = 1            ' remember this turn direction 

  gosub Right

goto Linefollowloop 

do5:                 ' 1 0 1 -> not used - left and right over line

goto Linefollowloop 

do6:                 ' 1 1 0 -> right and center over the line 

  gosub Tright

goto Linefollowloop 

do7:                 ' 1 1 1 -> all sensors over the line  

  gosub Stop

goto Linefollowloop   

'=================================================================

'Subrutines

'================================================================= 

'-------------------------------------------------

'Motor control subrutines

'------------------------------------------------- 

Fwd:

  low Motor1b

  low Motor1b

  high Motor1a

  high Motor2a

return 

Left:

  low Motor2a

  low Motor1b

  high Motor2b

  high Motor1a

return 

Right:

  low Motor2b

  low Motor1a

  high Motor2a

  high Motor1b

return 

Tright:

  low Motor1b

  low Motor1a

  low Motor2b

  high Motor2a

return 

Tleft:

  low Motor2b

  low Motor2a

  low Motor1b

  high Motor1a

return 

Stop:

  low Motor2b

  low Motor2a

  low Motor1b

  low Motor1a

return

I plugged the daughter board on the robot, downloaded the program (make sure the jumper is off so the motors won’t be powered during testing) and I placed the robot on a piece of white paper with a piece of black electrical tape on it. I moved the robot sideways looking at the Debug window on the PC but sensors did not pick any reflected IR light. I have adjusted the pot to get the maximum light on the LEDs but still nothing! Hmm, what may be the problem? I hooked a IR LED (using wires and a 100 ohm resistor) to the power lines and place it directly in front of one of the photo transistors. The value did changed in the Debug window from 1 to 0, just as it was supposed to do. Then I placed the LED sideways very close to the photo transistor and placed a corner of the white paper over them and the value changed again. The conclusion is: the photo transistors from the VCRs have a very narrow angle of detection, so the LED has to be in close proximity and even a little tilted, as that the IR light spot on the paper will be directly in front of the photo transistor. After modifying the daughter board so that each photo transistor had one LED in front of it a little tilted backward, I have placed the robot back on the paper and checked to see if the values were changing in the Debug window. And yes, they did.

Now let’s put the robot to work! I have placed the jumper back and put the robot down on a line following course and switched the power on. The robot drove fiercefully and crashed into the wall! Oops! What now?  It looks that the robot moves too fast and cannot react to the change in sensor values in time. But how can I slow it down? Well, I have remembered that there is a voltage drop on a diode placed in series on the power line so I have pulled  3 diodes from the VCR and connect them in series and placed them instead of the jumper to the motors power line. Now the robot drove a lot slower but followed the line perfectly. Maybe a little too slow. I think 2 diodes will do the trick. 

Ok, but we now have 2 different programs and every time we want the robot to do something we have to reprogram it. Not so easy to do. What if we integrate both programs in a single one? How can we make the robot know which program to execute? Well, we can add a push button to select the program at start. If we press the button once, it will execute the avoiding program and if we press it twice it will execute the line following program. But wouldn’t it be better if we could somehow have a visual confirmation of the program that will be run? Sure! Nemesis has 2 more pins that we did not use: P4 and P12 (Tx and Rx). We can connect one red LED and one green LED (with a resistor in series) between pins 5, 4 and 3 on the programming connector. The red LED will be connected with the cathode on the pin 4 and the anode to a resistor connected to the pin 5. The green LED will have the cathode to the pin 3 and anode to the same resistor connected to the pin 5. 

Let’s see the program: 

Nemesis

'===============================================================

'VCR Robot with 2 DC Motors and 3 IR line sensors

'Select Driving and Line following programs

'Compiled program size: 489 bits (out of 1024 bits)

'===============================================================  

'--------------------------------------------------

'Variables declaration, labels, timer...

'-------------------------------------------------- 

dim LeftIR             ' variables to store the values of the

dim RightIR            ' IR sensor for left and right directions 

dim Lvalue,Cvalue,Rvalue,Cvalue2,Rvalue2

dim state,dir 

const Motor1a      8   ' right motor

const Motor1b      9   '

const Motor2a     10   ' left motor

const Motor2b     14   '

const MotorEn     13   ' enable motors  

const IRsensor     5   ' IR sensor pin

const IRpulse      6   ' pin used to generate the IR pulse 

const LeftIRLed   11   ' Left proximity IR LED

const RightIRLed   7   ' Right proximity IR LED 

const RightLineS   1   ' right line sensor

const CenterLineS  2   ' center line sensor

const LeftLineS    3   ' left line sensor 

const Button       0   ' program selection button 

const LED1         4   ' line program

const LED2        12   ' driving program 

hwpwm 0,50,15          ' pwm signal 40KHz 60% "on" time 

'=================================================================

'Main program

'=================================================================  

Main: 

RCSTA = 0          ' stop serial transmission    

output Motor1a     ' we declare the direction of the I/O pins 

output Motor1b     ' for the motors and IR LEDs to  

output Motor2a     ' "output" and set the value to 

output Motor2b     ' "high" or "low". 

low Motor1a        ' all undeclared pins will be set to 

low Motor1b        ' "input". 

low Motor2a 

low Motor2b  

output LeftIRLed 

output RightIRLed 

high LeftIRLed 

high RightIRLed  

output LED1 

output LED2 

low LED1 

low LED2  

output MotorEn 

high MotorEn 

'-----------------------------------------------------------------

'program selection

'-----------------------------------------------------------------

loop1:

  waitport Button,0,255,loop1

  high LED1

  low LED2

  c = 0

  select = 0

  pause 100 

loop2:

  c = c+1

  if c = 3 then

    goto blink

  endif

  waitport Button,0,255,loop2

  low LED1

  high LED2

  select = 1

  pause 100

blink:

  toggle LED1

  pause 100

  toggle LED1 

start:

  waitport Button,0,255,start

  if select = 1 then

    goto Drivingloop

  else

    goto Linefollowloop

  endif

 '---------------------------------------------------------------

'Driving program

'---------------------------------------------------------------

Drivingloop:

   gosub ReadIRSensor

   if RightIR = 0 then    ' obstacle to the right

    gosub ReverseLeft    ' reverse left motor

  else                   ' no object

    gosub ForwardLeft    ' forward left motor

  endif

  if LeftIR = 0 then     ' obstacle to the left

    gosub ReverseRight   ' reverse right motor

  else                   ' no object

    gosub ForwardRight   ' forward right motor

  endif 

goto Drivingloop            ' start again    

'---------------------------------------------------------------

'Line following program

'---------------------------------------------------------------

Linefollowloop:

   Lvalue = inp.LeftLineS      '0 means white, 1 means black

   Cvalue = inp.CenterLineS

   Rvalue = inp.RightLineS

   Cvalue2 = 2*Cvalue

   Rvalue2 = 4*Rvalue

   state = Lvalue + Cvalue2 + Rvalue2

   branch state,do0,do1,do2,do3,do4,do5,do6,do7 

goto Linefollowloop 

do0:                 ' 0 0 0 -> no sensor over the line

  if dir == 0 then   ' decide by the direction of the last turn

    gosub Tleft

  else

    gosub Tright

  endif

goto Linefollowloop 

do1:                 ' 0 0 1 -> left sensor over the line

  dir = 0            ' remember this turn direction 

  gosub Left

goto Linefollowloop 

do2:                 ' 0 1 0 -> center sensor over the line

  gosub Fwd

goto Linefollowloop 

do3:                 ' 0 1 1 -> left and center over the line

    gosub Tleft

goto Linefollowloop 

do4:                 ' 1 0 0 -> right sensor over the line

  dir = 1            ' remember this turn direction

   gosub Right

goto Linefollowloop 

do5:                 ' 1 0 1 -> not used - left and right over line

goto Linefollowloop 

do6:                 ' 1 1 0 -> right and center over the line

    gosub Tright

goto Linefollowloop 

do7:                 ' 1 1 1 -> all sensors over the line

    gosub Stop

goto Linefollowloop   

'=================================================================

'Subrutines

'================================================================= 

'-------------------------------------------------

'Motor control subrutines

'------------------------------------------------- 

ForwardRight:

  low Motor1b

  high Motor1a

return 

ReverseRight:

  low Motor1a

  high Motor1b

return 

ForwardLeft:

  low Motor2b

  high Motor2a

return 

ReverseLeft:

  low Motor2a

  high Motor2b

return  

Fwd:

  low Motor1b

  low Motor1b

  high Motor1a

  high Motor2a

return 

Left:

  low Motor2a

  low Motor1b

  high Motor2b

  high Motor1a

return 

Right:

  low Motor2b

  low Motor1a

  high Motor2a

  high Motor1b

return 

Tright:

  low Motor1b

  low Motor1a

  low Motor2b

  high Motor2a

return 

Tleft:

  low Motor2b

  low Motor2a

  low Motor1b

  high Motor1a

return 

Stop:

  low Motor2b

  low Motor2a

  low Motor1b

  low Motor1a

return 

'-------------------------------------------------

'Read the IR proximity sensor subrutine

'-------------------------------------------------

ReadIRSensor:

  low RightIRLed            ' set active the right IR LED

  output IRpulse            ' start the pwm pulse

  pause 1                   ' wait a milisecond

  input IRpulse             ' stop the pulse

  RightIR = inp.IRsensor    ' read the value

  pause 1                   ' wait a milisecond

  high RightIRLed           ' deactivate the right IR LED

  low LeftIRLed             ' set active the left IR LED

  output IRpulse            ' start the pwm pulse

  pause 1                   ' wait a milisecond

  input IRpulse             ' stop the pulse

  LeftIR = inp.IRsensor     ' read the value

  pause 1                   ' wait a milisecond

  high LeftIRLed            ' deactivate the left IR LED

return 

Well, I hope you enjoyed this robot and maybe you have learned something from it. Please leave your comments on the forum. Thank you very much! 

Gabriel (Ro-Bot-X).