help: servo motor

Discussion in 'General Electronics Chat' started by mastertiger, Aug 5, 2012.

  1. mastertiger

    Thread Starter New Member

    Jul 9, 2012
    24
    1
    can i change the direction of servo motor by change polarity ?
    if not
    how can i change the direction of servo motor by using pic 16f877a?
    i use servo motori sys s3006
    3 wire
    void main()
    {
    int x;
    trisb=0;
    trisd=0;
    portb=0;
    portd=0;

    for(x=0;x<4;x++)
    {
    PORTB.F0 = 1;
    Delay_us(1000);//1ms Delay
    PORTB.F0 = 0;

    Delay_us(1000);

    }
    }
    connect single wire to port b pin 0 in pic
    i read some threads about change delay time to change direction
    but it do not work
    help please
    thanks

    [​IMG]
     
  2. bertus

    Administrator

    Apr 5, 2008
    15,647
    2,346
  3. BMorse

    Senior Member

    Sep 26, 2009
    2,675
    234
    To control an RC servo you will need to use PWM with a duty‐cycle of 20ms, and the pulse width contained within those 20ms varies from 1ms to 2ms.

    This variation in the pulse width is what controls the servo. As a rule of thumb, if a 1ms
    pulse is constantly fed to the servo, it will position itself around ‐60° angle,
    1.5ms and it will go to the center (0°), and 2 ms will position the servo at +60°
    angle.

    Here is an example using a pic16f877a written in Mikropascal:
    Code ( (Unknown Language)):
    1. //designed for a PIC16F877A with a 4Mhz clock
    2. interrupt {
    3.      if (TMR0IF flag is raised) {
    4.           flagServo = true;
    5.           TMR0 := 100;
    6.           SetBit(INTCON,TMR0IE);
    7.           ClearBit(INTCON,TMR0IF);
    8.      }
    9. }
    10. main_body {
    11.      TRISC = 0;
    12.      delay = 1000; //-60
    13.      increment := 1;
    14.      steps := 10; //10 steps = approx. 1 degree
    15.      OPTION_REG := $86; //setup TMR0 to trigger
    16.      TMR0 := 100; //every 20ms
    17.      SetBit(INTCON,GIE);
    18.      SetBit(INTCON,TMR0IE);
    19.      while (1==1) {
    20.           if (flagServo) {
    21.           //generate pulse with width = “delay” microseconds
    22.               SetBit(PORTC,0);
    23.               delay_microseconds(delay);
    24.               ClearBit(PORTC,0);
    25.          //increase/decrease angle
    26.              delay = delay + increment * steps;
    27.              if (delay > 2000) {
    28.                     delay = 1999;
    29.                     increment = -1;
    30.             } else if (delay < 900) {
    31.                     delay = 901;
    32.                     increment = 1;
    33.                     }
    34.           flagServo = false;
    35.           }
    36.      }
    37. }
    38.  
     
  4. mastertiger

    Thread Starter New Member

    Jul 9, 2012
    24
    1
    thanks of replay
    ok if i want to do that with normal pin not pwm pin
    i need to change pulse wide time to reverse direction
    i try use (.7ms or 2ms ) to change direction but do not work
    void main()
    {
    int x;
    trisb=0;
    trisd=0;
    portb=0;
    portd=0;

    for(x=0;x<4;x++)
    {
    PORTB.F0 = 1;
    Delay_us(700);
    PORTB.F0 = 0;

    Delay_ms(1000);

    }
    }
    and this
    void main()
    {
    int x;
    trisb=0;
    trisd=0;
    portb=0;
    portd=0;

    for(x=0;x<4;x++)
    {
    PORTB.F0 = 1;
    Delay_us(2000);
    PORTB.F0 = 0;

    Delay_ms(1000);

    }
    }
    what i missed ?
    if i change the polarity like dc motor direction will change or motor will damage ?
     
    Last edited: Aug 5, 2012
  5. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    instead of 1000ms you want 20ms, and if you reverse the polarity it could damage the motor, it certainly wouldn't do what you want.
     
  6. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,802
    832
  7. BMorse

    Senior Member

    Sep 26, 2009
    2,675
    234
    I don't see why you are having issues, when the site you got the circuit from provides the code to run the servo..... you just need to modify it to suit your needs, (and write it in the appropriate compiler language since this is written in MicroC)....

    Code ( (Unknown Language)):
    1. void main()
    2. {
    3.   TRISB = 0; // PORTB as Ouput Port
    4.   do
    5.   {
    6.    //To Turn to 0 Degree
    7.    PORTB.F0 = 1;
    8.    Delay_us(1000);//1ms Delay
    9.    PORTB.F0 = 0;
    10.  
    11.    Delay_ms(1000);
    12.  
    13.    //To Turn to 90 Degree
    14.    PORTB.F0 = 1;
    15.    Delay_us(1500);
    16.    PORTB.F0 = 0;
    17.  
    18.    Delay_ms(1000);
    19.  
    20.    //To Turn to 180 Degree
    21.    PORTB.F0 = 1;
    22.    Delay_us(2000);
    23.    PORTB.F0 = 0;
    24.  
    25.    Delay_ms(1000);
    26.  }while(1);
    27. }
     
  8. BMorse

    Senior Member

    Sep 26, 2009
    2,675
    234
    OK, so I had to try it to see if the code works.... I am using Hi-tech C with a Pic16f887 running at 20Mhz.... this will run the servo from one end to the other looping it constantly... (Just change the word Servo to the I/O pin you are using.....)

    Code ( (Unknown Language)):
    1. void Move_Servo()
    2. {
    3.     int x;
    4.     while(1){
    5.         //to turn to 0 degrees
    6.         for (x=0;x<25;x++){
    7.             Servo = 1;
    8.             DelayMs(1);
    9.             Servo = 0;
    10.             DelayMs(10);
    11.         }//end for
    12.  
    13.     DelayMs(1000);  //short delay between moves
    14.    
    15.         //to turn it all the way to 180
    16.         for (x=0;x<25;x++){
    17.             Servo = 1;
    18.             DelayMs(2);
    19.             Servo = 0;
    20.             DelayMs(10);
    21.         }//end for
    22.     };//end while
    23. }
     
  9. mastertiger

    Thread Starter New Member

    Jul 9, 2012
    24
    1
    thanks for replay
    i make delay (delay_us(3000);)
    it work nice
    thanks again
     
    BMorse likes this.
Loading...