Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Controlling Servo Motor using PIC16F877A in 15 degrees interval

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
Activity points
90
I have written a code for controlling servo motor using CCS compiler, for the rotation of the motor from its neutral position to its clock wise direction in 15 degrees interval, the code is tested on Proteus its working fine but as I burnt the controller, the motor does not moves in the same way.
the code is as follows:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<16f877a.h>
#fuses HS,NOLVP
#use delay(clock=20000000)
void main()
{
 int16 i;
 while(1)
{
      
for(i=1500;i<=2000;)
  {    
    output_high(PIN_B7);
    output_high(PIN_D6);
        delay_us(i); //sending 5 volts to servo for pulse_width microseconds
        output_low(PIN_D6);
        delay_ms(20);
        delay_ms(300);
        i = i+82;
}
       }
}



Kindly someone help me in changing the code where I have make a mistake.
 
Last edited by a moderator:

The servo expects a pulse period of about 20 ms (50 Hz pulse frequency). You have > 320 ms, far to slow. Depending on the servo type, it will either work with low servo gain (analog controller) or might stop completely (digital controller). Delete the 300 ms delay and reduce the loop increment respectively.
 

Yes u are right, Actually I wanted the servo to stop at every 15degree interval that's why I added the delay_ms(300) but now I 've changed the code so that it stops at every 15 degree for some while, and its working fine now.
The code is:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<16f877a.h>
#fuses HS,NOLVP
#use delay(clock=20000000)
void main()
{
 int16 i,a;
 int16 pulse_width = 1000;
 while(1)
{
for(i=1500;i<=2000;)
  {    
        for(a=1;a<=50;a++)
        {
        output_high(PIN_B7);
        output_high(PIN_D6);
        delay_us(i); //sending 5 volts to servo for pulse_width microseconds
        output_low(PIN_D6);
        delay_ms(20);
        }
       i = i+82;
}
 
       }
}



- - - Updated - - -

Now I want my servo to be controlled via Serial Communication using simple commands, when I send 1 it should go to 15degrees , when 2 it jumps to 30 degrees and when 3 and so on, I would like to know is it possible using serial communication. Kindly let me know,
 

yes why not make lookup table that is using if else conditon change the pulse width.
 

Can you please guide me how? If there is any tutorial related to it,
 

I have written a code using lookup table, let me share.
Code:
#include<16f877a.h>
#fuses HS,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,stream=RS232,bits=8)
const int16 rht_lft[7] = {1500, 1583, 1666, 1749, 1832, 1915, 2000};
void main()
{
 
 
 int16 i;
 int16 a;
 char ser_com;
 while(1)
{
  ser_com = getc();
  switch(ser_com)
  {
   	case 0x31:
		for(a=1;a<=50;a++)
		{
 		output_high(PIN_D6);
       	delay_us(rht_lft[0]); //sending 5 volts to servo for pulse_width microseconds
      	output_low(PIN_D6);
       	delay_ms(20);
		}
        break;
  	case 0x32:
      	for(a=1;a<=50;a++)
		{
 		output_high(PIN_D6);
       	delay_us(rht_lft[1]); //sending 5 volts to servo for pulse_width microseconds
      	output_low(PIN_D6);
       	delay_ms(20);
		}
        break;
  	case 0x33:
		for(a=1;a<=50;a++)
		{
 		output_high(PIN_D6);
       	delay_us(rht_lft[2]); //sending 5 volts to servo for pulse_width microseconds
      	output_low(PIN_D6);
       	delay_ms(20);
		}
       	break;
 	case 0x34:
    	for(a=1;a<=50;a++)
		{
 		output_high(PIN_D6);
       	delay_us(rht_lft[3]); //sending 5 volts to servo for pulse_width microseconds
      	output_low(PIN_D6);
       	delay_ms(20);
		}
		break;
	case 0x35:
		for(a=1;a<=50;a++)
		{
 		output_high(PIN_D6);
       	delay_us(rht_lft[4]); //sending 5 volts to servo for pulse_width microseconds
      	output_low(PIN_D6);
       	delay_ms(20);
		}
		break;
	case 0x36:
		for(a=1;a<=50;a++)
		{
 		output_high(PIN_D6);
       	delay_us(rht_lft[5]); //sending 5 volts to servo for pulse_width microseconds
      	output_low(PIN_D6);
       	delay_ms(20);
		}
		break;
	case 0x37:
 		for(a=1;a<=50;a++)
		{
 		output_high(PIN_D6);
       	delay_us(rht_lft[6]); //sending 5 volts to servo for pulse_width microseconds
      	output_low(PIN_D6);
       	delay_ms(20);
		}      
		break;
	}
 }
}

I have checked this code on the ISIS 7 its working fine, can this code be reduced to fewer lines, as i've used cases and all cases repeat the same code just it changes the index of the array.
 

can this code be reduced to fewer lines, as i've used cases and all cases repeat the same code just it changes the index of the array.
Sounds like you're answering the question yourself...
 

I have tested the above code in simulation it works, but when I tested on the hardware, it doesn't work, the servo didn't move, I've checked all the parameters of Serial.

can some one guide me on it,
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top