3
\$\begingroup\$

I am trying to control a servo motor using PIC 12F675. I was successful in driving the servo as well as achieving the speed control for the servo. Thanks for the help from Stack Exchange

Now, my speed control is quite flaky. I tried tweaking my code here and there but I have had no success so far.

My main objective is that the servo should spin 0 to 90 and back based on the data from toggle switch. I achieved this goal. When I turn a potentiometer, the speed at which the servo rotates should change. I achieved this too. However, the servo is not rotating 90 degrees at all the time.

It rotates 90 ish -120 degrees at high speeds and rotates only 30-45 degrees on low speeds (or some weird behavior is happening). I want my servo to rotate 90 degrees but just my speed should vary.

Can any one point me to the error in my code?

GO_DONE=1; // start ADC
while(GO_DONE); // wait for ADC to complete
V_in=(ADRESH<<8)|ADRESL; //copy ADC values into a variable V_in
quotient=V_in/200; // I am dividing this because I will have integers between 1 to 5
// I am using this quotient value to magnify/diminish my time delays for speed

if(quotient<=1) 
{
    quotient=1; //fool proofing
}

if(GPIO&(1<<3)) //checking whether toggle switch is high. If yes, go forward else reverse
{
    while(counter>1000) //this counter is for the delay cycles.
    {
        counter=counter-(20*quotient);
        GPIO|=(1<<2);
        cnt_1=counter;
        while(cnt_1>0)
        {
            __delay_us(1);
            cnt_1--;
        }
        GPIO&=~(1<<2); //low signal
        __delay_ms(18);
    }
    cnt=1000;//reset of counter for reverse direction
}
elseif(!(GPIO&(1<<3))) // check if switch is low
{
    while(cnt<1500)
    {
        cnt=cnt+(20*quotient);
        GPIO|=(1<<2);
        cnt_2=cnt;
        while(cnt_2>0)
        {
            __delay_us(1);
            cnt_2--;
        }
        GPIO&=~(1<<2);
        __delay_ms(18);
    }
    counter=1500;//reset of counter for forward direction
}
\$\endgroup\$
3
  • \$\begingroup\$ You´re expecting us to read and understand your uncommented code. It would be much easier for us answer your question without having to reverse engineer the code first. \$\endgroup\$
    – posipiet
    Commented Feb 15, 2012 at 12:40
  • \$\begingroup\$ @posipiet I apologize for the same. I was submitting the question using a very poor bandwidth \$\endgroup\$
    – Sai
    Commented Feb 15, 2012 at 19:50
  • \$\begingroup\$ Again, community, someone describes their answer as well as they can and posts their code, and I was the first upvote in 43 views? \$\endgroup\$
    – Kortuk
    Commented Feb 16, 2012 at 7:10

1 Answer 1

2
\$\begingroup\$

You should set counter before the loop at the beginning of the conditional blocks.

Also, you can use the same counter for both outer loops.

The inner loops can be replaced by __delay_us (counter).

Apart from that, it looks like it should ramp the PWM nicely.

Your PIC supports PWM on two ports, which automates what you are doing in software. Try that, because your delay programmed function will be very awkward to program around once you try to do something else as well.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.