[PIC] Limit Switch code for a Robot using PIC16F877A

Status
Not open for further replies.

ather_88

Newbie level 5
Joined
May 22, 2014
Messages
10
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
90
I have written a code for a robot which is receiving commands serially, If it Receives 'W' it moves forward,
'S' it moves backward,
'A' it moves left,
'D' it moves right,

I have used limit switches at the rear portion, when it touches any obstacle while moving behind, i.e. the limit switch makes contact in the BACKWARD direction and the robot should stop and wait for the obstacle to move so that It can move again the backward direction, mean while in the stop condition If it receives other three commands the robot should move in that direction.

The code which I've tested doesn't stops the robot when any of the two limit switches gets ZERO '0' at pins D0 and D1 in void chk_lmt_swt() function.

Code:
#include<16f877a.h>
#fuses HS,NOWDT,NOLVP
#use delay(clock=20000000)
//#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,stream=RS232,bits=8)
#use rs232(baud=57600,parity=N,xmit=PIN_C6,rcv=PIN_C7,stream=RS232,bits=8)
#define M1_1 PIN_B0          	  //left motor 1 Fwd      
#define M1_2 PIN_B1			 	 //left motor 1 Rev      
#define M2_1 PIN_B2			 	 //left motor 2 Fwd	  
#define M2_2 PIN_B3			 	//left motor 2 Rev        
#define M3_1 PIN_B4				//Right motor 1 Fwd		
#define M3_2 PIN_B5				//Right motor 1 Rev       
#define M4_1 PIN_B6				//Right motor 2 Fwd      
#define M4_2 PIN_B7				//Right motor 2 Rev       
#define trig PIN_D6
//trig = PIN_RD6      //pin 29   OUTPUT
//Echo = PIN_RD7	    //pin 30   INPUT
void stop();
void forward();
void reverse();
void right();
void left();
void ultrasonic();
void chk_lmt_swt();


int going_forward;
int going_reverse;
int going_right;
int going_left;

void chk_lmt_swt()
{
 if(!input(PIN_D0) || !input(PIN_D1))
 {
  stop();
   }
}
void   ultrasonic()
{
       int16 width;
       int16 range=0.00;
          width=0;
          range=0;
          output_high(trig);   //send pulse with a 10us width
          delay_us(20);
          output_low(trig);
	  
          while (!input(PIN_D7))  //wait until an echo is received
          {

	        }
          while (input(PIN_D7)) //calculate the width of the echo received
          {
             delay_us(10);
             width++;
          }

          range=(width*10)/58; //calculate range
          range=range/2;
		 

          if(range<5)
             {
                stop();
                output_high(PIN_B6);
               
             }
         }
 
void forward()
{
 output_high(M1_1);             
 output_high(M2_1);
 output_high(M3_1);
 output_high(M4_1);
 going_forward =1;
 } 
 
void reverse()
{
  output_high(M1_2);
  output_high(M2_2);
  output_high(M3_2);
  output_high(M4_2);
  going_reverse=1;
  chk_lmt_swt();

} 

void right()
{
 output_high(M1_1);
 output_high(M2_1);
 output_low(M3_1);
 output_low(M4_1);
 going_right = 1;
}

void left()
{
 output_high(M3_1);
 output_high(M4_1);
 output_low(M1_1);
 output_low(M2_1);
 going_left=1;
}
void stop()
{
 output_low(M1_1);
 output_low(M2_1);
 output_low(M3_1);
 output_low(M4_1);
 output_low(M1_2);
 output_low(M2_2);
 output_low(M3_2);
 output_low(M4_2);
 going_forward=0;
 going_reverse=0;
 going_right=0;
 going_left=0;
 delay_ms(500);
}
void main()
{
 char data;
 set_tris_d(0x80);
 output_high(PIN_B7);
 stop();
 while(1)
 {
  data=getc();
  switch(data)
  {
   case 0x57:					// for forward   W
   			if(going_reverse==1||going_right==1||going_left==1)
   			stop();
  			forward();
   		   // if(going_forward==1)
          //  ultrasonic();
  			break;
   case 0x53:                 // for Reverse S
   		
			if(going_forward==1||going_left==1||going_right==1) 
			{
			stop();
			reverse();
			}
  	else 
	if(going_reverse==1)
		chk_lmt_swt();
		break;
   case 0x41:				//for Left A
 			if(going_forward==1||going_reverse==1||going_right==1)
  			stop();
			//if (going_left==1)
			left();
			break;
   case 0x44:              //FOR RIGHT D
			if(going_forward==1||going_left==1||going_reverse==1)
			stop();  
			right();
			break;
   case 0x58:            //for STOP X
			stop();
 }
}

}
 

nothing obviously wrong - could you add some printf() statements to trace the logic? e.g.
Code:
void chk_lmt_swt()
{
printf("D0 %d D1 %d\n", input(PIN_D0) ,input(PIN_D1)));
 if(!input(PIN_D0) || !input(PIN_D1))
 {
  stop();printf("Stopped\n");
   }
}
 
hello


Problem of parenthesis misplaced

Code:
void chk_lmt_swt()
{
 if  [B]([/B](!input(PIN_D0) ||[B] ([/B]!input(PIN_D1))
 {
  stop();
   }
}
 

hello


Problem of parenthesis misplaced

Code:
void chk_lmt_swt()
{
 if  [B]([/B](!input(PIN_D0) ||[B] ([/B]!input(PIN_D1))
 {
  stop();
   }
}
! has a higher precedence than || therefore if input(PIN_D0) OR input(PIN_D1) is false, i.e. 0, stop() should be called
Code:
void chk_lmt_swt()
{
 if(!input(PIN_D0) || !input(PIN_D1))
 {
  stop();
   }
}
assuming that was what was intended??
 

In programming, i allways learn that the number of opened parenthesis must be equal to the closed parenthesis
to avoid erratic behavior.
Did the rules changed ?

are they some warning in compilation logging ?
 

In programming, i allways learn that the number of opened parenthesis must be equal to the closed parenthesis
to avoid erratic behavior.
Did the rules changed ?

are they some warning in compilation logging ?

in
Code:
 if(!input(PIN_D0) || !input(PIN_D1))
the number of ( balances the number of ) or am I reading it wrong
the compiler will generally generate errors if not
of couse the parenthesis can be in the wrong place so it may compile OK but the code fails at run time
 

Yes, you're right..
i was just disturbed by this kind of writting..
.

I often put in extra () if I am not sure of the associativity and precedence of particular operators (and cannot be bothered to look it up) or even just to make the code clearer for documentation purposes
 

I have checked the code but it's not working the way I want,

I have also made some modifications but it didn't work too, can someone help me out Please,
 

can you put some printf() statements in the code so you can check the values of PIN_D0 etc and the flow of control?
 

hello

init of PORTD in the main :

Code:
 set_tris_d(0x80);

only D7 is an input ...
what about D0 and D1

Code:
set_tris_d(0x83);
 

I have set now D0 and D1 as inputs by,
Code:
set_tris_d(0x83);
but still I am not getting the desired results, I want to stop the moving robot if D0 or D1 gets zero, it should wait until D0 or D1 gets high, Since the robot is moving backward it must carry on the same direction if D0 or D1 is high now, Mean while now the robot can also move in the other three directions too.

I have also use this printf() commands, but the virtual Rs-232 screen in ISIS doesn't return any thing.
 

hello

What to do with else condition ?
check limit during reverse mouvment ?

Code:
case 0x53:                 // for Reverse S
        if(going_forward==1||going_left==1||going_right==1) 
    {
    stop();
    reverse();
    }
      else 
        [B]  {[/B]
    if(going_reverse==1)
        chk_lmt_swt();
           }
        break;
 

i also used limit switch and some the time problem was bcoz of noise only.
so i think you should use 0.1uf capacitor across both end of limit switch.
 


yes if u use capacitor then its hardware debouncer and if u use in programming then its software.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…