5. Upgrade

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
|