Electronic – Weird Servo Speed Control problem

picservo

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
}

Best Answer

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.

Related Topic