Society of Robots - Robot Forum

General Misc => Misc => Topic started by: helmyshahryl on August 22, 2007, 10:10:27 PM

Title: Line Detection Robot using PIC16F877
Post by: helmyshahryl on August 22, 2007, 10:10:27 PM
Hi, I am doing my final year project on Line Detection using PIC16F877 and I am writing my codes in C.
Can anyone check my coding?

Thank You.


//LiDTrans PIC Programming

#include <pic.h>

//Hardware:
//Using PIC16F877
//Clock = 4Mhz


//Configuration Fuses
#if defined(_16F877)
#warning PIC16F877 selected
      __CONFIG(0x3FFD);      //PIC16F877 Configuration Fuses
                           // - XT crystal oscillator

#else
#error Unsupported PICmicro MCU selected
#endif


//Global Variables
volatile unsigned TRISPC @ (unsigned) &TRISC;      //declaration of TRISC as TRISPC
volatile unsigned PC @ (unsigned) &PORTC;         //declaration of PC as PORTC - RF input signal
volatile unsigned TRISLNSR @ (unsigned) &TRISD;      //declaration of TRISLNSR as TRISD
volatile unsigned LNSR @ (unsigned) &PORTD;         //declaration of LNSR as PORTD - Line Sensor

static bit TRISMRF    @ (unsigned) &TRISB*8+0;      //TRISB0
static bit TRISMLF    @ (unsigned) &TRISB*8+1;      //TRISB1
static bit TRISMRFH @ (unsigned) &TRISB*8+2;      //TRISB2
static bit TRISMLFH @ (unsigned) &TRISB*8+3;      //TRISB3
static bit TRISMRR    @ (unsigned) &TRISB*8+4;      //TRISB4
static bit TRISMLR    @ (unsigned) &TRISB*8+5;      //TRISB5
static bit TRISMRX    @ (unsigned) &TRISB*8+6;      //TRISB6
static bit TRISMLX    @ (unsigned) &TRISB*8+7;      //TRISB7
   
static bit       MRF    @ (unsigned) &PORTB*8+0;      //RB0 - Motor Right Forward
static bit       MLF    @ (unsigned) &PORTB*8+1;      //RB1 - Motor Left Forward
static bit       MRFH @ (unsigned) &PORTB*8+2;      //RB2 - Motor Right Forward High
static bit       MLFH @ (unsigned) &PORTB*8+3;      //RB3 - Motor Left Forward High
static bit       MRR    @ (unsigned) &PORTB*8+4;      //RB4 - Motor Right Reverse
static bit       MLR    @ (unsigned) &PORTB*8+5;      //RB5 - Motor Left Reverse
static bit       MRX    @ (unsigned) &PORTB*8+6;      //RB6 - Motor Right Stop
static bit       MLX    @ (unsigned) &PORTB*8+7;      //RB7 - Motor Left Stop

static bit TRISJSR @ (unsigned) &TRISA*8+0;         //TRISA0
static bit TRISJSL @ (unsigned) &TRISA*8+1;         //TRISA1

static bit JSR @ (unsigned) &PORTA*8+0;            //RA0 - Junction Sensor Right
static bit JSL @ (unsigned) &PORTA*8+1;            //RA1 - Junction Sensor Left

static bit TRISUSW @ (unsigned) &TRISA*8+2;         //TRISA2
static bit TRISOBS @ (unsigned) &TRISA*8+3;         //TRISA3

static bit USW @ (unsigned) &PORTA*8+2;            //RA2 - User Switch @Station
static bit OBS @ (unsigned) &PORTA*8+3;            //RA3 - Obstacles Limit Switch


//initializing port function
void InitPort()
{
   TRISPC = 0b00000111;                     //Determines RC0,RC1,RC2 as input
   TRISLNSR = 0b00000111;                     //Determines RD0,RD1,RD2 as input

   TRISMRF = 0;   //Declare RB0 as output
   TRISMLF = 0;   //Declare RB1 as output
   TRISMRFH = 0;   //Declare RB2 as output
   TRISMLFH = 0;   //Declare RB3 as output
   TRISMRR = 0;   //Declare RB4 as output
   TRISMLR = 0;   //Declare RB5 as output
   TRISMRX = 0;   //Declare RB6 as output
   TRISMLX = 0;   //Declare RB7 as output

   TRISJSR = 1;   //Declare RA0 as input
   TRISJSL = 1;   //Declare RA1 as input   

   TRISUSW = 1;   //Declare RA2 as input
   TRISOBS = 1;   //Declare RA3 as input

   ADCON1=ADCON1|0x0F;         //Switch PORTA from analog mode to digital mode

   PC = 0b00000000;   //initialize PORTC to all 0
   LNSR = 0b00000000;   //initialize PORTD to all 0

   MRF = 0;      //initialize RB0=0
   MLF = 0;      //initialize RB1=0
   MRFH = 0;      //initialize RB2=0
   MLFH = 0;      //initialize RB3=0
   MRR = 0;      //initialize RB4=0
   MLR = 0;      //initialize RB5=0
   MRX = 0;      //initialize RB6=0
   MLX = 0;      //initialize RB7=0

   JSR = 0;      //initialize RA0=0
   JSL = 0;      //initialize RA1=0

   USW = 0;      //initialize RA2=0
   OBS = 0;      //initialize RA3=0
}

//500 Usec Delay function
void Delay500Us()   
{
   unsigned char cnt500Us = 165;   // Delay Cycle to achieve 500Us delay
   while(--cnt500Us != 0)         // Delay Timing is approximately 3 usec per loop
      continue;                // Note this routine is for 4MHz crystal frequency
}

//100 msec Delay function
void Delay100ms()   
{
   unsigned char cnt100ms = 200;   // 200 * 500 Usec = 100 msec

   do
   {
      Delay500Us();
   }while(--cnt100ms != 0);
}

//1 sec Delay function
void Delay1s()   
{
   unsigned char cnt1ms = 10;   //10 * 100 msec = 1 sec

   do
   {
      Delay100ms();
   }while(--cnt1ms != 0);
}

//wait for user input function
void WaitUserInput()
{
   while (PC == 0b00000000)   // Loop and wait for LiDTrans received signal from RF transmitter
      continue;            
}

//wait for user press resume button
void UserSwitch()
{
   while (USW == 0)
      continue;
}

//Input from Line Detection Sensor
void LineSensor()
{
   while (LNSR!=0b00000111)
   {   
      switch(LNSR)
      {
         case 0b00000010:    MRF = 1;   MLF = 1;   break;
         case 0b00000011:    MRF = 1;   MLFH = 1;   break;
         case 0b00000001:    MRX = 1;   MLF = 1;   break;
         case 0b00000110:    MRFH = 1;   MLF = 1;   break;
         case 0b00000100:    MRF = 1;   MLX = 1;   break;   
      }
   }
}

//From Station A to Station B function
void A_to_B()
{
   LineSensor();

   while (JSR != 1 && JSL != 0)      //detects junction sensor (01 = Station A)
      LineSensor();

   MRF = 1; MLR = 1;               //from front, turn left

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Station A

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;
   MRX = 1; MLX = 1;               //LiDTrans stop

   UserSwitch();                  //wait for user give command to indicates loading job is done

   MRX = 0; MLX = 0;

   LineSensor();
   
   MRF = 1; MLR = 1;               //from Station A, turn left

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   while (JSR != 0 && JSL != 1)      //detects junction sensor (10 = Station B)
      LineSensor();

   MRR = 1; MLF = 1;               //from front, turn right

   Delay1s();

   MRR = 0; MLF = 0;

   LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Station B

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;
   MRX = 1; MLX = 1;               //LiDTrans stop            

   UserSwitch();                  //wait for user give command to indicates unloading job is done

   MRX = 0; MLX = 0;

   LineSensor();
   
   MRF = 1; MLR = 1;               //from Station B. turn left

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   while (JSR != 0 && JSL != 0)      //detects junction sensor (00 = Base)
      LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Base

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;

   //back to main()   
}

//From Station A to Station C function
void A_to_C()
{
   LineSensor();

   while (JSR != 1 && JSL != 0)      //detects junction sensor (01 = Station A)
      LineSensor();

   MRF = 1; MLR = 1;               //from front, turn left

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Station A

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;
   MRX = 1; MLX = 1;               //LiDTrans Stop

   UserSwitch();

   MRX = 0; MLX = 0;

   LineSensor();
   
   MRF = 1; MLR = 1;               //from Station A, turn left

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   while (JSR != 1 && JSL != 1)      //detects junction sensor (01 = Station C)
      LineSensor();

   MRF = 1; MLR = 1;               //from front, turn left

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Station C

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;
   MRX = 1; MLX = 1;               //LiDTrans stop

   UserSwitch();

   MRX = 0; MLX = 0;

   LineSensor();
   
   MRR = 1; MLF = 1;               //from Station C, turn right

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   while (JSR != 0 && JSL != 0)      //detects junction sensor (00 = Base)
      LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Base

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;

   //back to main()
}

//From Station B to Station A function
void B_to_A()
{
   LineSensor();

   while (JSR != 0 && JSL != 1)      //detects junction sensor (10 = Station B)   
      LineSensor();

   MRR = 1; MLF = 1;               //from front, turn right

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Station B

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;
   MRX = 1; MLX = 1;               //LiDTrans stop

   UserSwitch();

   MRX = 0; MLX = 0;

   LineSensor();
   
   MRF = 1; MLR = 1;               //from Station B, turn left

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   while (JSR != 1 && JSL != 0)      //detects junction sensor (01 = Station A)
      LineSensor();

   MRR = 1; MLF = 1;               //from back, turn right

   Delay1s();

   MRR = 0; MLF = 0;

   LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Station A

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;
   MRX = 1; MLX = 1;               //LiDTrans stop

   UserSwitch();

   MRX = 0; MLX = 0;

   LineSensor();
   
   MRR = 1; MLF = 1;               //from Station A, turn right

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   while (JSR != 0 && JSL != 0)      //detects junction sensor (00 = Base)
      LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Base

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;

   //back to main()   
}

//From Station B to Station C function
void B_to_C()
{
   LineSensor();

   while (JSR != 0 && JSL != 1)      //detects junction sensor (10 = Station B)
      LineSensor();

   MRR = 1; MLF = 1;               //from front, turn right

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Station B

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;
   MRX = 1; MLX = 1;               //LiDTrans stop

   UserSwitch();

   MRX = 0; MLX = 0;

   LineSensor();
   
   MRR = 1; MLF = 1;               //from Station B, turn right

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   while (JSR != 1 && JSL != 1)      //detects junction sensor (11 = Station C)
      LineSensor();

   MRF = 1; MLR = 1;               //from front, turn left

   Delay1s();

   MRR = 0; MLF = 0;

   LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Station C

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;
   MRX = 1; MLX = 1;               //LiDTrans stop

   UserSwitch();

   MRX = 0; MLX = 0;

   LineSensor();
   
   MRR = 1; MLF = 1;               //from Station C, turn right

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   while (JSR != 0 && JSL != 0)      //detects junction sensor (00 = Base)
      LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Base

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;

   //back to main()         
}

//From Station C to Station A function
void C_to_A()
{
   LineSensor();

   while (JSR != 1 && JSL != 1)      //detects junction sensor (11 = Station C)
      LineSensor();

   MRF = 1; MLR = 1;               //from front, turn left

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Station C

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;
   MRX = 1; MLX = 1;               //LiDTrans stop

   UserSwitch();

   MRX = 0; MLX = 0;

   LineSensor();
   
   MRR = 1; MLF = 1;               //from Station C, turn right

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   while (JSR != 1 && JSL != 0)      //detects junction sensor (01 = Station A)   
      LineSensor();

   MRR = 1; MLF = 1;               //from back, turn right

   Delay1s();

   MRR = 0; MLF = 0;

   LineSensor();

   MRF = 1; MLR = 1;               //U-turn a station A

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;
   MRX = 1; MLX = 1;               //LiDTrans stop

   UserSwitch();

   MRX = 0; MLX = 0;

   LineSensor();
   
   MRR = 1; MLF = 1;               //from Station A, turn right

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   while (JSR != 0 && JSL != 0)      //detects junction sensor (00 = Base)
      LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Base

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;

   //back to main()         
}

//From Station C to Station B function
void C_to_B()
{
   LineSensor();

   while (JSR != 1 && JSL != 1)      //detects junction sensor (11 = Station C)
      LineSensor();

   MRF = 1; MLR = 1;               //from front, turn left

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Station C

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;
   MRX = 1; MLX = 1;               //LiDTrans stop

   UserSwitch();

   MRX = 0; MLX = 0;

   LineSensor();
   
   MRR = 1; MLF = 1;               //from Station C, turn right

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   while (JSR != 0 && JSL != 1)      //detects junction sensor (10 = Station B)
      LineSensor();

   MRF = 1; MLR = 1;               //from back, turn left

   Delay1s();

   MRR = 0; MLF = 0;

   LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Station B

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;
   MRX = 1; MLX = 1;               //LiDTrans stop

   UserSwitch();

   MRX = 0; MLX = 0;

   LineSensor();
   
   MRF = 1; MLR = 1;               //from Station B, turn left

   Delay1s();

   MRF = 0; MLR = 0;

   LineSensor();

   while (JSR != 0 && JSL != 0)      //detects junction sensor (00 = Base)
      LineSensor();

   MRF = 1; MLR = 1;               //U-turn at Base

   Delay1s();
   Delay1s();

   MRF = 0; MLR = 0;

   //back to main()      
}


//main function
void main()
{
   while (1 == 1)
   {
   InitPort();                  //call initializing port function
   WaitUserInput();            //call waiting for user input function
   if (PC == 0b00000001)
      A_to_B();               //call function station A to station B
   else if (PC == 0b00000010)
      A_to_C();               //call function station A to C
   else if (PC == 0b00000011)
      B_to_A();               //call function station B to A
   else if (PC == 0b00000100)
      B_to_C();               //call function station B to C
   else if (PC == 0b00000101)
      C_to_A();               //call function station C to A
   else if (PC == 0b00000110)
      C_to_B();               //call function station C to B
   }
}
Title: Re: Line Detection Robot using PIC16F877
Post by: Admin on August 27, 2007, 01:04:15 PM
Does it compile fine?

Anything you are worried about not working?

Have you tried it on a robot yet?

(I think everyone is too lazy to go through all your code)
Title: Re: Line Detection Robot using PIC16F877
Post by: helmyshahryl on August 27, 2007, 07:22:40 PM
I'd compile the code and it's OK. I compile it using MPLAB IDE with PICC Lite toolsuite. But then, I haven't try it on the robot due to the robot still under construction. I just want to make sure that there is no mistakes on the logic or may be on the syntax that i must define for this 16f877 pic, such as ADCON pin, OSC or anything. Especially on how to use XT oscillator (crystal). What i must do in order to make sure my program is running OK because, right now, i am just using default value for I/O. Did I missed something that i must enable or disable in the codes?
Thank You so much.
Title: Re: Line Detection Robot using PIC16F877
Post by: paulstreats on August 27, 2007, 09:36:29 PM
admin is right, i am too lazy to check your code unfortunatley, i may have a look when i get bored though.

Although i can tell you not to worry too much about setting the osc to xt because you get this option when you enable the pic programmer in mplab and it will set the bits there for you, as well as other bits like wd timer, code protect etc..

Have you tried just using the mplad to simulate how your code would run (you can set up a watch window to see what state the port bits are in, and you can also stimulate the pins high/low to make the code think it is receiving sensor input).

And the correct way to address the a/d ports, you will find in the 16f877.h file which is located in the include directory wherever picclite is installed, this is quite easy to read and understand and will probably let you see for yourself wether you are using the right code.

 this is how i go about setting up general ports on pics:

Code: [Select]
#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit))

static bit pin0 @ PORTBIT(PORTA, 0); //portA Pin 0
static bit T_pin0  @ PORTBIT(TRISA, 0); // Tris for above

static bit pin1 @ PORTBIT(PORTA, 1); //portA Pin 1
static bit T_pin1  @ PORTBIT(TRISA, 1); // Tris for above

etc...