PIC Lesson: Servo Motor

Servo motor adalah alat electromechanical. Ia adalah sebuah motor yang mempunyai feedback loop. Oleh itu ia sebuah motor yang boleh dikawal posisi dan kelajuannya tanpa feedback kepada microcontroller. Servo motor hanya berputar dalam lingkungan sudutnya sahaja, contohnya hanya boleh berputar pada 1800.

Servo motor mempunyai tiga wayar. Kebiasaannya wayar merah adalah supply positif, wayar hitam adalah ground manakala wayar ketiga adalah signal daripada microcontroller. Wayar signal mempunyai beberapa standard warna iaitu warna putih, kuning atau oren.

Servo motor bergerak mengikut pulse signal. Signal ke servo adalah berbentuk PWM dengan frequency lebih kurang 50Hz iaitu masa bagi satu cycle adalah 20mS. Posisi armature servo motor bergantung pada duty cycle PWM tersebut. Dengan mengubah-ubah duty cycle, servo motor akan bergerak atau berputar. Dengan ini juga, kelajuannya boleh di kawal. Contoh signal untuk menggerakkan servo motor berputar mengikut arah jam atau mengikut arah lawan jam seperti diagram di bawah.

Walaubagaimanapun, untuk memprogram servo, tidak boleh menggunakan PWM Module dalam PIC kerana PWM yang diperlukan adalah frekuensi rendah. Oleh itu, PWM boleh dihasilkan menggunakan counter di dalam timer interrupt. Kemudian, hanya perlu menetapkan nilai posisi servo tersebut.

Berikut adalah skematik untuk menggerakkan servo mnggunakan input analog.

Bagi interface menggunakan Arduino boleh rujukĀ Arduino Lesson: Servo Motor, menggunakan ESP32 boleh rujuk ESP32 Lesson: Servo Motor dan menggunakan Raspberry Pi boleh rujuk Raspberry Pi Lesson: Servo Motor.

Berikut adalah video demo mengawal Servo Motor melalui Variable Resistor.

PIC Source Code

57 Replies to “PIC Lesson: Servo Motor”

  1. maaf tapi saya tak faham,tidak ada library header file dalam file,HI-tech.boleh tunjuk saya,step by step

  2. di mana saya boleh dapat “LibraryHardware.h”
    “LibraryPeripheral.h”?saya carik dalam file hi-tech tetapi tidak ada.

  3. Is this code able to control more then one servo ?
    I modify it into this.
    static void interrupt isr(void){
    if(TMR0IF = 1){
    TMR0IF = 0;
    counter++;
    if (counter == position1) servo1=0;
    if (counter == position2) servo2=0;
    if (counter == 391){
    counter=0;
    servo1=1;
    servo2=1;
    }
    }
    }

    But somehow servo1 will rotate clockwise nonstop till it hit the border.

    1. Lin, I don’t know why. Make sure your power supply to the servo can supply enough current. Sometimes servo drain power supply current and program not proper working.

      1. Im using a power supply that can supply 15A it should be more than enought ?

        I modify it into this and it worked.
        if (counter1 == position1) servo1=0;
        if (counter2 == position2) servo2=0;
        if (counter3 == position3) servo3=0;
        if (counter4 == position4) servo4=0;
        if (counter5 == position5) servo5=0;
        if (counter6 == position6) servo6=0;

        if (counter1 == 391){
        counter1=0;
        servo1=1;
        }
        if (counter2 == 391){
        counter2=0;
        servo2=1;
        }
        if (counter3 == 391){
        counter3=0;
        servo3=1;
        }
        if (counter4 == 391){
        counter4=0;
        servo4=1;
        }
        if (counter5 == 391){
        counter5=0;
        servo5=1;
        }
        if (counter6 == 391){
        counter6=0;
        servo6=1;
        }

        And i still dun understand what is the difference .

  4. ini comment saudara yg sy angkat dr page dc motor lesson saudara:

    frequency = Crystal_freq/(4x256xPreescalexCounter) = 20000000/(4x256x2x4883)=2Hz (T=0.5s)

    compare with this page:

    (20MHz/(4*256*390)=50Hz)

    there is another 256 here…klau sy tgk kat website http://www.microcontrollerboard.com/pic-timer0-tutorial.html ni rumus utk internal clock adalah seperti diatas dimana jika kita set tmr0=0…how? sy confuse sbb nampak mcm rumus untuk external clock cam tulis dlm website tu…

    1. mtaufiq23, contoh tersebut guna preescale 256. Tgk setting kat OPTION_REG.
      Contoh kat Servo Motor, preescale=1. 20MHz/(4x1x(256-0)x390) = 50Hz
      Contoh kat DC Motor, preescale=2. 20MHz/(4x2x(256-0)x4883) = 2Hz

  5. salam..bukan ke rumus utk kire frequency, f=fosc/(4x256x(256-TMR0)xcount)…
    knp hilang bhgn 256-TMR0 dr rumus saudara utk tentukan f=50hz….?

  6. 2. yang bhagian ni…
    position=(int)(0.9775*(max-min)*read_a2d(0)/1000+min);

    adc 10-bit bkan max 1023 ke? Kalo read_a2d(0)= 1022, min = 10, max =50,
    position = 0.9775* 40.47525 = 39.56=39…
    Knape pkai 1000 bukan 1023, dan 0.9775 tu utk ape?

    Sori double post.

  7. Salam. Beberape soklan..

    1. Yang (20MHz/(4*256*390)=50Hz) tu, 256 mane datang? Nk kira internal clock cycle kene Fosc/4, jadi ko set PS0PS2 tu 111 eh? Tapi dlm code knape ko set OPTION_REG 00001000, PS tu sume 0, ke ko set dlm library adc?

    1. ws, Sodrohu.
      1. 256 sebab Timer0 8bit. Fosc/4 sebab set Tocs=0 (OPTION_REG).
      2. Sebenarnya 0.9775*(max-min)*read_a2d(0)/1000 sama juga dengan 1*(max-min)*read_a2d(0)/1023. Nanti saya akan edit code untuk elak kekeliruan.

  8. salam, sy ingin bertanya kenapa apabila saya menggunakan complier hi-tech v9.82 , ada error & fail. tolong bantu sy…

    1. Smart Home mcm mana, byk konsep smart home. Tapi, kena study lah apa yg nak buat, smart home byk kena buat interfacing dan protocol.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.