A friend and I have been working on a robot for a while now. It started as a senior design project in college. As our knowledge of the PIC grew, we made certain improvements to the project such as changing from the PIC16F628A to the PIC16F877A. Currently, my partners robot is fully functional. I am providing my entire code for you to look over and maybe use yourself at some point. The only problem that I am currently faced with is the fact that my ADC doesn't seem to be functioning. I'm going to be purchasing another 877a to be certain of this. Enjoy!
If anyone thinks that they may be able to help me with my ADC problem, please let me know. Thanks to all.Code:'********************************************************* 'Identify all defines for crystal, LCD display, and ADC '********************************************************* DEFINE OSC 20 ' Define 20MHz Oscillator DEFINE LCD_DREG PORTB ' Set LCD Data port DEFINE LCD_DBIT 4 ' Set starting Data bit (0 or 4) if 4-bit bus DEFINE LCD_RSREG PORTB ' Set LCD Register Select port DEFINE LCD_RSBIT 3 ' Set LCD Register Select bit DEFINE LCD_EREG PORTB ' Set LCD Enable port DEFINE LCD_EBIT 2 ' Set LCD Enable bit DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits) DEFINE LCD_LINES 2 ' Set number of lines on LCD DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us DEFINE LCD_DATAUS 50 ' Set data delay time in us 'DEFINE ADC_BITS 10 ' Defines number of adc bits (o - 255 output) 'DEFINE ADC_CLOCK 3 ' ADC clock speed 'DEFINE ADC_SAMPLEUS 1 ' How often the adc samples inputs '********************************************************* 'Declaring all variables and alias's '********************************************************* OBJECTSTATUS VAR BYTE ' Variable for object detection 'BATVOLTAGE VAR WORD ' Variable for battery voltage 'BAT_DIGIT VAR BYTE ' Variable for voltage digits before decimal 'BAT_DEC VAR BYTE ' Variable for voltage digits after decimal A VAR BYTE ' Loop variable for right object detection B VAR BYTE ' Loop variable for left object detection 'FPC VAR WORD ' Variable for Front Photocell on ADCIN 1 'RPC VAR WORD ' Variable for Rear Photocell on ADCIN 2 'LPC VAR WORD ' Variable for Left Photocell on ADCIN 3 'RIPC VAR WORD ' Variable for Right Photocell on ADCIN 4 RIGHT_IRLED VAR PORTD.0 ' Alias Right_Irled to PortD.0 LEFT_IRLED VAR PORTD.1 ' Alias Left_Irled to PortD.1 IR_RECEIVER VAR PORTD.2 ' Alias Ir_Receiver to PortD.2 PAUSE 1000 ' Pause 1 second to allow power to stabilize '********************************************************* 'Configurations for all ports on PIC16F877A. '********************************************************* ADCON1 = %10000010 ' ADC configuration TRISA = %11111111 ' Configure PortA TRISB = %00000000 ' Configure PortB TRISC = %10000000 ' Configure PortC TRISD = %00000100 ' Configure PortD TRISE = %00000000 ' Configure PortE '********************************************************* 'This is the main loop of the program. It calls all the subroutines for 'their operations and then continues from where it called them. It uses 'variables determined by the subroutines to search for objects, find 'distance to objects, and eventually, check for light sources and charge 'the batteries. '********************************************************* MAIN: 'Read the battery voltage (NO LONGER WORKING) ' GOSUB CHECK_BATTERIES ' Check the battery voltage ' PAUSE 100 ' Allow time for samples 'Check light sources (IS NOT WORKING PROPERLY) ' GOSUB CHECK_LIGHT ' PAUSE 100 'Look for objects and move the robot accordingly GOSUB CHECK_RIGHT ' Check for object on right PAUSE 100 ' Allow time for signal GOSUB CHECK_LEFT ' Check for object on left PAUSE 100 ' Allow time for signal IF (OBJECTSTATUS.0 = 0 && OBJECTSTATUS.1 = 0) THEN GOSUB FORWARD IF (OBJECTSTATUS.0 = 1 && OBJECTSTATUS.1 = 0) THEN GOSUB LEFT IF (OBJECTSTATUS.0 = 0 && OBJECTSTATUS.1 = 1) THEN GOSUB RIGHT IF (OBJECTSTATUS.0 = 1 && OBJECTSTATUS.1 = 1) THEN GOSUB BACK GOTO MAIN '********************************************************* 'This subroutine is used to measure the voltage remaining on the batteries. 'If this voltage reaches a certain point, it will tell the robot to find 'the brightest light and charge itself. This is still experimental as I 'have not determined how to implement solar technology. However, I can 'use this subroutine to just calculate the voltage and display it on LCD. 'Also, at this point in time, this has stopped working due to problems with 'the ADC on my PIC. '********************************************************* 'CHECK_BATTERIES: ' Check for the current battery voltage ' ADCIN 0, BATVOLTAGE ' Store the 10-bit conversion in variable ' BATVOLTAGE = BATVOLTAGE * 3 ' BAT_DIGIT = (BATVOLTAGE * 5) / 1000 ' BAT_DEC = (BATVOLTAGE * 5) - (BAT_DIGIT * 1000) ' LCDOUT $FE, 1 ' Clear display ' LCDOUT $FE, 2 ' Return home (beginning of first line) ' LCDOUT $FE, $0C ' Cursor Off ' LCDOUT "VOLTS: ", DEC BAT_DIGIT, ".", DEC BAT_DEC, "V" ' PAUSE 500 ' IF (BAT_DIGIT <= 6) THEN GOSUB CHECK_LIGHT 'RETURN '********************************************************* 'As my ADC doesn't seem to be working properly, this does not work. '********************************************************* 'CHECK_LIGHT: ' Check for brightest light ' ADCIN 1, FPC ' Get input from front photocell ' ADCIN 2, RPC ' Get input from rear photocell ' ADCIN 3, LPC ' Get input from left photocell ' ADCIN 4, RIPC ' Get input from right photocell ' IF (FPC > RPC) && (FPC > LPC) && (FPC > RIPC) THEN GOSUB FORWARD ' IF (RPC > FPC) && (RPC > LPC) && (RPC > RIPC) THEN GOSUB BACK ' IF (LPC > FPC) && (LPC > RPC) && (LPC > RIPC) THEN GOSUB LEFT ' IF (RIPC > LPC) && (RIPC > RPC) && (RIPC > LPC) THEN GOSUB RIGHT ' IF (FPC == RPC == LPC == RIPC) THEN GOSUB CALC 'RETURN '********************************************************* 'Object Detection subroutines '********************************************************* CHECK_RIGHT: ' Check for objects on right FOR A = 1 TO 50 ' Execute for C 50 times HIGH RIGHT_IRLED ' Sending this high and low for 13us generates PAUSEUS 13 ' roughly a 38khz signal. Leaves PWM open for LOW RIGHT_IRLED ' use with another application. This will PAUSEUS 13 ' generate at roughly 38khz for 50 cycles. IF (IR_RECEIVER == 0) THEN OBJECTSTATUS.0 = 1 IF (IR_RECEIVER == 1) THEN OBJECTSTATUS.0 = 0 NEXT A ' RETURN CHECK_LEFT: ' Check for objects on left FOR B = 1 TO 50 ' Execute for D 50 times HIGH LEFT_IRLED ' Same operation as with the right irled. PAUSEUS 13 ' LOW LEFT_IRLED ' PAUSEUS 13 ' IF (IR_RECEIVER == 0) THEN OBJECTSTATUS.1 = 1 IF (IR_RECEIVER == 1) THEN OBJECTSTATUS.1 = 0 NEXT B ' RETURN '********************************************************* 'Motor control subroutines. As is, it is configured for 4 wheel drive. 'Two H-Bridges are implemented with two sets of Tamirya Gearbox Motors. '********************************************************* FORWARD: ' Move forward HIGH PORTD.4 LOW PORTD.5 HIGH PORTD.6 LOW PORTD.7 RETURN LEFT: ' Turn left LOW PORTD.4 HIGH PORTD.5 HIGH PORTD.6 LOW PORTD.7 RETURN RIGHT: ' Turn right HIGH PORTD.4 LOW PORTD.5 LOW PORTD.6 HIGH PORTD.7 RETURN BACK: ' Back up LOW PORTD.4 HIGH PORTD.5 LOW PORTD.6 HIGH PORTD.7 RETURN 'NOGO: ' Stop ' LOW PORTD.4 ' LOW PORTD.5 ' LOW PORTD.6 ' LOW PORTD.7 'RETURN '********************************************************* 'This subroutine calculates the percentage of light that the CDS_Photocells 'are receiving in. If it is above 80% it will stop the robot to allow the 'batteries to charge. '********************************************************* 'CALC: ' Determine whether to keep searching or stop 'IF (FPC < %11110011) THEN GOSUB FORWARD 'light less than 80% 'IF (FPC >= %11110011) THEN GOSUB NOGO 'light more or equal to 80% 'RETURN END





Bookmarks