RC SERVO之PWM控制範例

發佈日期
2010.08.05
類  別
技術
資料出處
機器人夢工廠 安東尼


RC SERVO為多數小型機器人最主要的致動器,它的體積小、重量輕並且可提供精確的旋轉角度與足夠的扭力,目前市面上知名的廠牌國產的有祥儀、廣營、栗研 等,日、韓系則有Kondo、Hitec所生產的RC SERVO大部份是透過PWM(脈波寬度調變)來控制。本文將逐步介紹PWM原理、RC SERVO feedback功能、如何使用單板電腦RoBoard產生PWM來控制RC SERVO,最後以KONDO的KRS 788HV RC SERVO為例,編寫一個以示教方式教導機器人完成揮手動作的程式。讓閱讀過本文的讀者了解到RC SERVO的控制原理,以及對如何編輯機器人動作有初步的概念。

什麼是PWM訊號?
它是Pulse Width Modulation的縮寫,是將訊號編碼於脈波寬度上的一種技術,此技術以數位方式來模擬類比訊號,廣泛應用在資料傳輸上。而因數位訊號只存在High,LOW電位的變化,相較於類比訊號,比較不會受到雜訊干擾。
PWM 訊號中,脈波寬度在整個週期所占的比例稱為工作週期(duty cycle),是指位於邏輯高準位(logic high level)的波型在整個週期中占所的比例。下圖一說明兩個不同工作週期的波型差異,其中30%工作週期的波型位於邏輯高準位的時間少於50%工作週期的 波型。
 

圖一 固定週期不同duty cycle的PWM波型

PWM如何控制RC SERVO?
市面上的RC SERVO控制介面可分為以下幾種:PWM、RS232、RS485、I2C,其中PWM控制是一種受歡迎的控制方式,一般是利用duty cycle high的寬度來控制RC SERVO的旋轉角度,舉例來說,KONDO KRS-788HV這個SERVO所接受的duty cycle high寬度介於700us~2300us之間,因此使用者必須提供此範圍的PWM訊號才能令它動作。
下圖二為改變duty cycle high寬度來控制RC SERVO角度示意圖,以KRS-788HV為例,給予1500us的PWM訊號,它會轉到90度處(因為1500us寬度為中間值,KRS-788HV的可動角度為0~180度,所以對應到中間位置)。
 

圖二 改變PWM duty cycle控制RC SERVO角度示意圖

不同的RC SERVO製造商就會有不同的預設PWM與旋轉角度範圍(一般是180度或270度),所以在控制之前,最好先仔細閱讀使用手冊。
一般以PWM訊號控制的RC SERVO對外連接線如下圖三所示,白線為PWM訊號線,紅線為電源線,黑線為地線,使用者通常會透過微處理器連接SERVO 控制器來提供PWM訊號及電源,但RoBoard已經將兩者整合,在使用上較為方便。
 

圖三 PWM SERVO對外連接接頭

RC SERVO的feedback功能
在許多以PWM 控制的RC SERVO中,功能上還可分為:具有feedback與沒有feedback兩種,前者具有回傳絕對角度的功能,後者則沒有,所以前者可讓使用者得知RC SERVO目前所在的絕對角度(必須傳送一特殊PWM訊號)。我們可以利用feedback來完成:以示教方式編輯機器人動作、閉迴路的角度控制等功能。

RoBoard上RC SERVO接口位置
RoBoard有高達24組的RC SERVO連接埠,如下圖四,靠外側的腳位為地線,中間為電源輸出,內側為PWM訊號輸出,編號排序依序為右下方的00至左上方的23,圖五是將伺服馬達 安裝至RoBoard上的情形。(注意:RoBoard支援的電壓為6~24V,且RC SERVO連接埠輸出電壓(圖中的Vxx)與RoBoard的輸入電壓相同,若使用的馬達運作電壓為12V,請提供12V電壓給RoBoard。)
 

圖四 的RC SERVO接口

 
圖五 將3個SERVO安裝在的SERVO連接埠0、1、2

RoBoIO Library中RCSERVO 相關函數簡要說明
1. rcservo_SetServo(channel, servono)
說明:設定channel上所使用的馬達型態,通常在rcservo_Initialize()之前呼叫。
輸入參數一:channel,一個0~23的數字。
輸入參數二:servono,馬達型態。
(1) RCSERVO_KONDO_KRS78X,代表使用的馬達是KONDO KRS786ICS、KRS788HV。
(2) RCSERVO_HITEC_HSR8498,代表使用的馬達是HITEC HSR8498。
(3) RCSERVO_SERVO_DEFAULT,代表使用的馬達是大部分具有feedback功能的馬達。
(4) RCSERVO_SERVO_DEFAULT_NOFB,代表使用的馬達是大部分無feedback功能的馬達。
輸出:True / False。
例如:使用KONDO KRS786ICS與HITEC HSR8498兩種SERVO各接在PWM第1和第5channel,呼叫方式如下:
rcservo_SetServo(1, RCSERVO_KONDO_KRS78X)
rcservo_SetServo(5, RCSERVO_HITEC_HSR8498)
注意:型態必須設定正確,否則SERVO將不會動作。

2. rcservo_Initialize(usedchannels)
說明:初始化rcservo,並設定輸出PWM訊號的channels。
輸 入參數一:usedchannels,設定輸出PWM訊號的channel,共有RCSERVO_USENOCHANNEL、 RCSERVO_USECHANNEL0~RCSERVO_USECHANNEL23等25個參數,設定複數channel時,彼此必須以“ ”相連。沒有設定到的channel則被當作是一般的GPIO。
輸出:True / False。
例如:對SERVO初始化並將第1 channel和第5 channel設定為輸出PWM訊號,其餘channel為GPIO,呼叫方式如下:
rcservo_Initialize(RCSERVO_USECHANNEL1 RCSERVO_USECHANNEL5)

3. rcservo_Close()
說明:結束RCSERVO相關功能,釋放占用的記憶體,通常在程式結束之前呼叫。
輸入參數:無。
輸出:無。

4. rcservo_EnterCaptureMode()
說明:進入擷取模式,可以開始使用rcservo_ReadPositions()函數。
輸入參數:無。
輸出:無。

5. rcservo_ReadPositions(channels, cmd, * width)
說明:讀取指定channel上的feedback值。
輸入參數一:channels,為讀取feedback訊號的channel,共有RCSERVO_USECHANNEL0~RCSERVO_USECHANNEL23等24個參數。設定複數channel時,彼此必須以“ ”相連。
輸入參數二:預設是0。
輸入參數三:* width,通常為儲存feedback值的陣列。
輸出:無。
例如:將第1、4、5、8 channel所擷取到的feedback值存在position[32]中,呼叫方式如下:
rcservo_ReadPositions(RCSERVO_USECHANNEL1
           RCSERVO_USECHANNEL4
           RCSERVO_USECHANNEL5
           RCSERVO_USECHANNEL8, 0, position)

6. rcservo_EnterPlayMode()
明:進入執行模式,可以開始使用rcservo_MoveTo()函數。
輸入參數:無。
輸出:無。

7. rcservo_MoveTo(* width, playtime)
說明:播放馬達移動到下一個位置的單一動作。
輸入參數一:* width,通常是為馬達“下一個”要到達的角度值陣列。
輸入參數二:playtime,執行每個陣列的間隔時間,以1ms為單位。
輸出:無。
 
範例:以教導方式編輯KONDO機器人揮手動作
此範例是在Windows XP與VC2008上做開發,程式撰寫流程如下:設定RC SERVO型態→初始化→進入擷取模式→開始擷取馬達角度→進入播放模式→設定播放參數並開始播放→結束程式。
1.  #include <stdio.h>
2.  #include <conio.h>
3.  #include <roboard.h> //RoBoard可用函數的標頭檔
4.  #define SPACE 100 //擷取的動作個數,預設100
5.  struct frame {
6.  unsigned long position[32];
7.  }motion[SPACE];
8.  int main(void) {
9.  int i,n;
10.  char c;
11.  unsigned long channels=RCSERVO_USECHANNEL0 RCSERVO_USECHANNEL1
12.                        RCSERVO_USECHANNEL2;
13.  for(i=0;i<3;i ) //設定3個channel上的RC SERVO型態
14.  {
15.    rcservo_SetServo(i,RCSERVO_KONDO_KRS78X); //使用KRS788 RC SERVO
16.  }
17.  if(rcservo_Initialize(channels)==false)
18.  {
19.     printf("%s\n",roboio_GetErrMsg());//若初始化失敗,印出錯誤訊息
20.     return 1;
21.  }
22.  rcservo_EnterCaptureMode(); //進如擷取模式
23.  printf("Press any key to read servo position or press \”Esc\” to play motion\n");
24.  i=0;
25.  for(c=getch();c!=27;c=getch()) //按Esc鍵離開擷取模式
26.  {                              //或按其它鍵擷取機器人動作
27.    if(i>(SPACE-1))
28.    {
29.      printf("擷取的動作個數已超過上限!\n");
30.      break;
31.    }
32.    rcservo_ReadPositions(channels,0,motion[i].position);
33.    printf("Record NO.%d motion\n",i );
34.  }
35.  if(i>0)
36.  {
37.    rcservo_EnterPlayMode(); //進入播放模式
38.    for(n=0;n<i;n )
39.    {
40.      rcservo_MoveTo(motion[n].position, 1000L); //每個動作間隔1秒
41.    }
42.  }
43.  rcservo_Close(); //結束程式
44.  return 0;
45.}

實作結果
程式編譯完成後,在RoBoard上執行的結果如下所示,左圖中先以人手調整KONDO機器人的手臂,並按任意鍵讓程式記錄調整好的動作(依照上面程式自定的紀錄空間,共可記錄100組動作),最後按ESC就會從第一個動作播放至最後動作,完成後就結束程式。


圖說:(由左至右)以人手調整動作並按任一鍵紀錄、按ESC開始播放動作、動作播放完畢

小結
在機器人致動器的選擇上,PWM SERVO是一款很受歡迎的解決方案,本文以逐步介紹的方式帶讀者初步了解機器人動作的原理與生成,應該可了解到玩機器人並非想像中的複雜,讀者不妨可將 動作看做是製作動畫般,先錄製每個單一動作,再以固定速度播放,就完成機器人連續動作。依照此流程,或許讀者可試試將本文範例的PWM輸出channel 數量增加為機器人SERVO的總數,進而編輯出高難度的動作。對於使用不同作業系統的玩家,www.roboard.com上有提供跨平台的RoBoIO Lib讓大家可以免費下載,希望能讓更多玩家加入玩機器人的行列。

全文摘至機器人世界情報網

arrow
arrow
    全站熱搜

    機器人 發表在 痞客邦 留言(0) 人氣()