最近文章

Arduino筆記(十五):控制伺服馬達 Servo

[2017/03/14]
先前寫的一篇文章:「Arduino筆記(八):控制步進馬達」,說明如何使用Arduino 的 Stepper 函式庫,控制步進馬達的正反轉。這篇文章要來實做一下伺服馬達的功能?同樣都是馬達,步進馬達和伺服馬達有和不同?同樣都可控制正轉反轉以及轉速,簡單的說最大的差別在於伺服馬達有回饋反授的機制,會將訊號傳回給驅動器;而步進馬達不會回傳訊號,這就是最大的不同。也因為這個回饋反授機制,讓伺服馬達轉動時的精確度較高,不會有失步的狀況。以下就來看看如何透過 Arduino 控制伺服馬達。

Adruino 開發板提供的電壓是 5V,如果供給 MG996R伺服馬達使用,在空轉情況下應該沒有問題,但如果接有其他電子零件,可能就會不夠,建議再加額外的電源給伺服馬達,本篇也會說明外接電力的方式。


[Servo Library]

•  attach(pin, min, max) :連接伺服馬達的控制線給 Arduino 的一個 Pin 腳
  pin : 在早期的 Arduino 只能指定 Pin 9 跟 Pin 10
  min (選項) : 對應於伺服上的最小 ( 0度) 角度的脈衝寬度 (以微秒為單位),預設為 544
  max (選項) : 對應於伺服上的最大 (180度) 角度的脈衝寬度 (微秒),預設為 2400

•  write(angle) :將值寫到伺服機相對應的控制軸
  angle: 寫到伺服機的值,從 0 到 180

•  read():讀取目前的伺服機值

[材料]

• Arduino Uno x 1
• 伺服馬達 (型號 MG996R) x1
• 連接線 x 3條

MG996R  伺服馬達規格
•  角度:180度 (對應的角度是-90度~+90度)
•  扭力:11KG 大扭力舵機/金屬齒輪伺服器
•  產品淨重: 55g
•  產品拉力: 9.4kg/cm(4.8V ), 11kg/cm(6V)
•  反應速度: 0.17sec/60degree(4.8v) 0.14sec/60degree(6v)
•  工作電壓: 4.8-7.2V
•  齒輪形式: 金屬齒輪

[接線圖一:讓伺服馬達正反轉] 

• MG996R連接線路
MG996R
Arduino
棕色線 GND
GND
紅色線 V+
5V
橘色線 PWM
Pin 9

• MG996R 直接連接接 Arduino 電源

• MG996R 外接電源,再連接 Arduino


[程式一]

#include <Servo.h>

Servo myservo;  // 建立一個 servo 物件,最多可建立 12個 servo

int pos = 0;    // 設定 Servo 位置的變數

void setup() {
  myservo.attach(9);  // 將 servo 物件連接到 pin 9
}

void loop() {
  // 正轉 180度
  for (pos = 0; pos <= 180; pos += 1) // 從 0 度旋轉到 180 度,每次 1 度 
  {     
    myservo.write(pos);               // 告訴 servo 走到 'pos' 的位置
    delay(15);                        // 等待 15ms 讓 servo 走到指定位置
  }

  // 反轉 180度
  for (pos = 180; pos >= 0; pos -= 1) // 從 180 度旋轉到 0 度,每次 1 度 
  { 
    myservo.write(pos);               // 告訴 servo 走到 'pos' 的位置

    delay(15);                        // 等待 15ms 讓 servo 走到指定位置
  }
}


[接線圖二:利用電阻控制伺服機] 


• MG996R及電阻連接線路
MG996R
Arduino
電阻
棕色線 GND
GND
Pin 1
紅色線 V+
5V
Pin 3
橘色線 PWM
Pin 9
-
-
Pin A2
Pin 2

[程式二]

#include <Servo.h>
Servo myservo;      // 建立一個 servo 物件,最多可建立 12個 servo

int r1_pin = 2;     // 可變電阻連接的 pin 腳
int r1_val;         // 從可變電阻來的數值 

void setup() 
{ 
  myservo.attach(9);  // 將 servo 物件連接到 pin 9
} 

void loop() 
{ 
  r1_val = analogRead(r1_pin);         // 從可變電阻讀取類比數值 (介於 0 跟 1023) 
  r1_val = map(r1_val, 0, 1023, 0, 179);  // 將類比值轉換為 servo 可讀取的範圍值(介於0 跟 180) 
  myservo.write(r1_val);                  // 設定 servo 位置 
  delay(15);                           // 等待 15ms 讓 servo 走到指定位置
} 


[實驗結果]

video

[參考資料]

•  MG996R Metal Gear Dual Ball Bearing Servo Datasheet
Arduino.cc:Servo library
• Arduino IDE Sample program

8 則留言:

  1. 作者已經移除這則留言。

    回覆刪除
  2. 作者已經移除這則留言。

    回覆刪除
  3. #include servo.h---->#include "S"ervo.h

    回覆刪除
    回覆
    1. 在編輯Html時,修改 Servo.h前後的括號改成 &lt 時,誤將S改成小寫,已經修正,謝謝您。

      刪除
  4. 哈囉 想請教一下~
    read函式可以直接讀取馬達目前的角度嗎? 還是讀取到的是前一次自己設定要擺動的角度呢?
    因為我想讓伺服馬達像風扇一樣左右擺動,並且接一個按鈕,當我按按鈕就回傳當下的角度
    不知道是否可以實現
    非常感謝!

    回覆刪除
    回覆
    1. 您好, read函式無法讀取目前伺服馬達的角度, 但是我看過有些網友對伺服馬達稍加改造後, 找到Encoder回授信號即可讀取目前位置, 詳細作法可參考其他網友的文章:http://sinocgtchen.blogspot.tw/2014/10/servo-smart-servo-servo-hacked.html

      刪除
  5. 我想請問一下 我使用你的PROGRAM 但改了用其他pin,卻無反應,我用了pin6和pin11都沒有反應,但用pin10卻有,是怎麼回事

    回覆刪除
    回覆
    1. 根據你的描述,我也不知道為何會這樣?有沒有重新Reset試看看?有沒有可能線沒接好?

      刪除