Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Servo Controller Using pic16f877a

Status
Not open for further replies.

doo20000

New Member
Hi, everyone i am doing my servo control using pic16f877a. I need some help because my code is not working. it only move alittle and just stop. could anyone help me so that i control my servo by press botton on port A bit0 it go right and press port A bit1 it go left. here is my code:

Please help me debug this sucker.

thank you

#include <htc.h>
#include <pic.h>

__CONFIG(RC & WDTDIS & PWRTEN & BOREN & LVPEN & WRTEN & DEBUGEN & UNPROTECT);

int x, y;

delay(int xvalue,int yvalue)
{

for(x = 0; x < xvalue; x++)
for(y = 0; y < yvalue; y++);

return;
}

main()
{
PORTA = 0x00;
PORTB = 0x00;
PCFG2 = 1;
PCFG1 = 1;
TRISA = 0xff;
TRISB = 0;

while(1) // Loop forever
{
if(RA0 == 1)
{
while(RA0 == 1) // If push button 0 is pressed
{

RB0 = 1; // Pulse high
delay(2,279); // 2 ms
RB0 = 0; // Low
delay(19,243); // 18 ms
}
}

else if (RA1 == 1)

{
while(RA1 == 1)
{

RB0 = 1; // Pulse high
delay(2,127); // 1 ms
RB0 = 0; // Low
delay(19,271); // 18 ms
}
}
}
}
 
I can't see where you set the port to be digital. Try adding ADCON1=0x06 to your initialisation code. It may be the two lines, PCFG2 = 1; PCFG1 = 1; as I have no idea what these lines do.


Mike.
 
Pommie said:
I can't see where you set the port to be digital. Try adding ADCON1=0x06 to your initialisation code. It may be the two lines, PCFG2 = 1; PCFG1 = 1; as I have no idea what these lines do.


Mike.

Hello, the part that say PCFG2 and PCFG1 that is where i turn my ADC on. thank you.
 
doo20000 said:
Hello, the part that say PCFG2 and PCFG1 that is where i turn my ADC on. thank you.
But, you need the ADC to be turned off and the ports to be setup as digital.

Mike.
 
i have no idea why my classmate got it to work with that two lines in his program. He got it to turn the servo turn left and right and center when the button were not pressed. Are all servo motor very much the same: it take 2ms to turn 180 and 1ms to turn 0 and 20ms to stop? because the code that i have very close to my classmate who got his servo to work. the different was just servo motor?

thank
 
Maybe they had the buttons on non analogue pins.

You also need to send a 1.5mS pulse when neither button is pressed or your servo will not return to the center position.

Mike.
 
Hello, Mike thank you for your comment. I am working on it but right now i just try to make it either go left or right first. do i really have to include that 1.5ms right now in my program those. right now the code is appearently not working because neither left nor right of the motor is being turn by the code. is there some example code that you have? just simple code to turn the motor. thank you
 
Adding the 1.5mS is just another else statement. As I don't know what PCFG does I would get rid of it and try something like,
Code:
main()
{
    PORTA = 0x00;
    PORTB = 0x00;
    //PCFG2 = 1;
    //PCFG1 = 1;
    ADCON1 = 0x06;
    TRISA = 0xff;
    TRISB = 0;

    while(1) // Loop forever
    {
        if(RA0 == 1)
        {
            while(RA0 == 1) // If push button 0 is pressed
            { 
    
                RB0 = 1; // Pulse high
                delay(2,279); // 2 ms 
                RB0 = 0; // Low
                delay(19,243); // 18 ms
            }
        }    
        else if (RA1 == 1)    
        {
            while(RA1 == 1)
            {        
                RB0 = 1; // Pulse high
                delay(2,127); // 1 ms 
                RB0 = 0; // Low
                delay(19,271); // 18 ms
            }
        } 
        else
        {
            RB0 = 1; // Pulse high
            delay(2,200); // 1.5 ms 
            RB0 = 0; // Low
            delay(19,271); // 18 ms
        } 
    }
}

The other possibility is that the chip isn't running at all. Can you put a scope on RB0 or put an LED on another pin and flash that?

I also see that your using an RC oscillator, have you got the right values for R and C?

Mike.
 
Hello, mike thank you for your comments. Did try and make some modification as your request and it was right like what you said. however, changes has been made but however i think the timing probably off. on my servo it's say 20ms for 6 degree does it mean something? because even i change port and tested it it still not move like it should. stutter any ideas mike? thank you so much for your help.
 
Thank you all for shedding some light on the topic, i've been looking for information for quite some time now. I've written a program for PIC16F877A with saving the timing variable to an eeprom chip, but instead of controlled movement of the servo i get wild 360 degree turning (apparently the servo isn't limited in it's rotation by it's hardware composition).
This is a part from my first program
Code:
  output_high(PIN_C1);
  delay_us(1000+5*i);
  output_low(PIN_C1);
  delay_ms(18);
i has a value between 0 and 19, but with any value the servo goes berserk.

This is my second program and it works fine:
Code:
main()
{
 output_low(PIN_C1);
 delay_ms(20);
 while(1)
 {
  output_high(PIN_C1);
  delay_us(1500); /*middle = 1.5ms*/
  output_low(PIN_C1);
  delay_ms(18);

  output_high(PIN_C1);
  delay_us(1500); /*middle = 1.5ms*/
  output_low(PIN_C1);
  delay_ms(18);

  delay_ms(1000);


  output_high(PIN_C1);
  delay_us(1000); /*start_pos = 1ms*/
  output_low(PIN_C1);
  delay_ms(18);

  output_high(PIN_C1);
  delay_us(1000); /*start_pos = 1ms*/
  output_low(PIN_C1);
  delay_ms(18);

  delay_ms(1000);


  output_high(PIN_C1);
  delay_us(1500); /*middle = 1.5ms*/
  output_low(PIN_C1);
  delay_ms(18);

  output_high(PIN_C1);
  delay_us(1500); /*middle = 1.5ms*/
  output_low(PIN_C1);
  delay_ms(18);

  delay_ms(1000);


  output_high(PIN_C1);
  delay_us(2000); /*end_pos = 2ms*/
  output_low(PIN_C1);
  delay_ms(18);

  output_high(PIN_C1);
  delay_us(2000); /*end_pos = 2ms*/
  output_low(PIN_C1);
  delay_ms(18);

  delay_ms(1000);

 }
}
I would also like to ask if its a requirement to have a 18ms delay for the low voltage state of the signal ( i.e. output_low(PIN_C1); delay_ms(18);).
 
Last edited:
Thank you all for shedding some light on the topic, i've been looking for information for quite some time now. I've written a program for PIC16F877A with saving the timing variable to an eeprom chip, but instead of controlled movement of the servo i get wild 360 degree turning (apparently the servo isn't limited in it's rotation by it's hardware composition).

If an unmodified servo has rotated 360 degrees, then it's most probably destroyed the feedback pot.
 
the servo is fine

If an unmodified servo has rotated 360 degrees, then it's most probably destroyed the feedback pot.

Yes, I've taught so myself, but I've plugged it to my RC receiver and it works just fine. I guess the feedback pot is unlimited in it's rotation range also (it's a TowerPro SG-50 servo - 5grams).

EDIT: I would also like to ask if there is some software like CCS C Windows IDE (PCW) for linux (ubuntu)
 
Last edited:
If an unmodified servo has rotated 360 degrees, then it's most probably destroyed the feedback pot.
As far as I know, the pots don't have stops and can rotate continuously. It's the one output gear that has a stop on it. You can open the servo up and carve the stop off that gear to make a continuous rotation servo.
 
As far as I know, the pots don't have stops and can rotate continuously. It's the one output gear that has a stop on it. You can open the servo up and carve the stop off that gear to make a continuous rotation servo.

In all the continuous rotation mods I've seen you just remove the drive to the pot, then manually set the pot for the pulse width you want centre to be.
 
The ones I know

Hola Futz,

The very very few servos I know, have physical limits at both ends of the pot.

Even more, one article explaining how to get continuous rotation of a servo was based on eliminating the pot (with its limits) and replacing it with resistors to take the physical constraint out of the way.
 
Controlling servo motor with PIC16f877a

Hi everyone
Im kind of new in PIC , I want to control the servo motors with 2 buttons
for example if button 1 pressed the servo rotate 90 degree CW and then if button 2 pressed the servo rotate CCW 90 degree (back to the previous position)
I think it will be easy but im confusing at the parts of delay or pulse
can anyone send me the code plz...
thanks
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top