# PIC12F683 with 3 push button switch’s driving servo motor in three positons.

#### Rooney

Joined Jan 11, 2015
4
Hello,
I am trying to drive servo motor MG996R maximum angular rotation is 120º in three positions 0º , 60º , 120º degree with 3 push button switches SW1, SW2 and SW3. I tried the code but i do not get the exact position of servo motor.
The problem is that I do not know the exact value of PR2 with TIMER2 . I do not have OSC or logic analyzer to measure. Period ms with timer2 interrupt routine. I have the code compiled with XC8 and schematic diagram of circuit.

I appreciate any help! Thank you very much.

#### Attachments

• 2.2 KB Views: 14
• 34 KB Views: 9

#### KeithWalker

Joined Jul 10, 2017
453
Hello,
I am trying to drive servo motor MG996R maximum angular rotation is 120º in three positions 0º , 60º , 120º degree with 3 push button switches SW1, SW2 and SW3. I tried the code but i do not get the exact position of servo motor.
The problem is that I do not know the exact value of PR2 with TIMER2 . I do not have OSC or logic analyzer to measure. Period ms with timer2 interrupt routine. I have the code compiled with XC8 and schematic diagram of circuit.

I appreciate any help! Thank you very much.
Servos are not very accurate when comparing the input pulse length to position. They can vary a lot, even from the same batch. I suggest that you change the values in the three position subroutines to get the right positions for your use. For example, in the statement:

void SFront(void) //
{
servo = 180;//
__delay_ms(100);
LED = 1;

Change the "servo = value" to get the right servo deflection.
Keith.

#### sagor

Joined Mar 10, 2019
116
Not sure if this helps with the timer part, but the MikroElektronica timer calculator comes up with this for a 1.5ms timer for a PIC at 8Mhz. (modify as required):

Code:
//Timer2
//Prescaler 1:1; Postscaler 1:12; TMR2 Preload = 249; Actual Interrupt Time : 1.5 ms
//Place/Copy this part in declaration section
void InitTimer2(){
T2CON     = 0x5C;
PR2         = 249;
TMR2IE_bit     = 1;
INTCON     = 0xC0;
}
void Interrupt(){
if (TMR2IF_bit){
TMR2IF_bit = 0;
}
}
Keith's answer can also solve your issue with some trial and error in figuring out the "position" regardless of any errors in the timer.

#### MMcLaren

Joined Feb 14, 2010
842
There's an example Servo driver in the PIC12F683 PWM Problem thread that shows how to break up a long 20-msec servo period into more managable 250-usec PWM intervals to provide a relatively high resolution servo pulse.

Good luck on your project. Cheerful regards...

#### Sensacell

Joined Jun 19, 2012
2,451
KeithWalker nailed it.

There is little requirement for RC servo accuracy between units or manufacturers.
You need to calibrate the values for your specific RC servos.

#### jpanhalt

Joined Jan 18, 2008
8,080
KeithWalker nailed it.

There is little requirement for RC servo accuracy between units or manufacturers.
You need to calibrate the values for your specific RC servos.
While I may agree on intermanufacturer variations, within a single servo type/manufacturer they are reproducible enough allow a "reversed servo"* to be fed with the same signal on contralateral control surfaces of a model airplane and not require individual trimming.

*Edit: Or non-reversed with an adjustment in geometry.

Last edited: