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%工作週期的波型。

clip_image001

圖一. 固定週期不同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度,所以對應到中間位置)。

clip_image002

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

不同的RC SERVO製造商就會有不同的預設PWM與旋轉角度範圍 (一般是180度或270度),所以在控制之前,最好先仔細閱讀使用手冊。

一般以PWM訊號控制的RC SERVO對外連接線如下圖三所示,白線為PWM訊號線,紅線為電源線,黑線為地線,使用者通常會透過微處理器連接SERVO 控制器來提供PWM訊號及電源,但RoBoard已經將兩者整合,在使用上較為方便。

clip_image004

圖三. 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。)

clip_image006

圖四. RoBoard的RC SERVO接口

clip_image008

圖五. 將3個SERVO安裝在RoBoard的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

    和第5 channel,呼叫方式如下:

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)

2. rcservo_Close()

 說明:結束RCSERVO相關功能,釋放占用的記憶體,通常在程式結束之前呼叫。

輸入參數:無。

輸出:無。

3. rcservo_EnterCaptureMode()

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

輸出:無。

4. 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)

5. rcservo_EnterPlayMode()

說明:進入執行模式,可以開始使用rcservo_MoveTo()函數。

輸入參數:無。

輸出:無。

6. 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就會從第一個動作播放至最後動作,完成後就結束程式。

clip_image010clip_image012clip_image014

       
  clip_image015   clip_image016

以人手調整動作並按任一鍵紀錄  按ESC開始播放動作     動作播放完畢

小結

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