RoBoard魔人的機器人日誌

2011/10/20

[教學] 如何控制RS0263-DMP小手

DMP小手 (RS0263*3)


RS0263為RoBoard的馬達
必須用RC servo控制馬達轉動

  • RC servo的控制原理
  1. 利用 PWM pulse 的寬度指定 servo 轉動的位置
  2. controller circuit 控制 servo 轉到指定的位置
  3. feedback potentiometer 會將 servo 目前的位置迴授給控制器
由於RS0263沒有feedback的功能
所以並不會將servo的位置回傳


  • 腳位相對位置
RB100有24個PWM
而RB110只有16個PWM
但其實還是十分好分辨的
靠外側的腳位為地(GND) 通常接的為黑線
靠中間的腳位為電(Vxx) 通常接的為紅線
靠內側的腳位為訊號(GPxx) 沒有特定顏色

切記勿接錯 否則會發生慘案

然而腳位編號請看官網的介紹投影片(Hardware Introduction Slide)


  • RC Servo lib
 rcservo_Init(...);
這邊記得將要用的所有Pin腳都加入
例如要加入1號與5號的腳位即:
rcservo_Init(RCSERVO_USEPINS1 + RCSERVO_USEPINS5);



 rcservo_SetServo(pin, servo_model);
SetServo要為妳要用的腳位設定傳輸的型態
這lib很佛心的是 幾乎所有會用到的RCservo 都已經先幫我們寫好型態了
所以只要依照馬達給相對應的模式 就可以使用了


rcservo_EnterPWMMode()
這是一個告訴PWM要開始的函式

然而傳輸方式有以下兩種
1. rcservo_SendPWM(pin, PWM period, PWM duty, count)

2. reservo_SendCPWM(pin, PWM period, PWM duty)

相信有人會問兩者的差別
第1種方法要搭配另一個函式rcservo_IsPWMCompleted(pin)
如函式名稱所寫   它是用來判斷此腳位的通訊是否完成
然而第一種方法的count就是要連續發出count筆通訊資料給馬達
當然在發資料的同時 程式會繼續往下跑    為了讓程式能稍稍暫停
就會用到判斷通訊完成的函式了

第二種方法雖然比較好用
不過使用時必須要小心
因為它是一直傳送通訊資料
直到使用函式reservo_StopPWM(pin)為止

兩者各有優缺

















code: 用G146地磁控制DMP小手做剪刀石頭布
#include "stdio.h"
#include "conio.h"
#include "roboard.h"
#include "roboard_dll.h"
void rock(unsigned long);
void paper(unsigned long);
void scissors(unsigned long);
const unsigned char acceler_addr = 0x30>>1;
int main(void)
{
 roboio_SetRBVer(RB_110);
 rcservo_Init(RCSERVO_USEPINS1 + RCSERVO_USEPINS2 + RCSERVO_USEPINS3);
 rcservo_SetServo(RCSERVO_PINS1, RCSERVO_DMP_RS0263);
 rcservo_SetServo(RCSERVO_PINS2, RCSERVO_DMP_RS0263);
 rcservo_SetServo(RCSERVO_PINS3, RCSERVO_DMP_RS0263);
 rcservo_EnterPWMMode();

    i2c_Initialize(I2CIRQ_DISABLE);
 i2c0_SetSpeed(I2CMODE_AUTO, 400000L);
 i2c0master_StartN(acceler_addr, I2C_WRITE,2);
 i2c0master_WriteN(0x20);
 i2c0master_WriteN(0x37);

 unsigned int acceler_X, acceler_Y,mode,lastmode;
 unsigned long PWM_period = 10000L;
 while(!kbhit()){
  i2c0master_StartN(acceler_addr, I2C_WRITE,1);
  i2c0master_WriteN(0x29);
  i2c0master_StartN(acceler_addr, I2C_READ,1);
  acceler_X = i2c0master_ReadN();

  i2c0master_StartN(acceler_addr, I2C_WRITE,1);
  i2c0master_WriteN(0x2b);
  i2c0master_StartN(acceler_addr, I2C_READ,1);
  acceler_Y = i2c0master_ReadN();
  
  mode = 0;
  mode = acceler_X >= 0x80 ? mode + 1 : mode;
  mode = acceler_Y >= 0x80 ? mode + 2 : mode;
  switch(mode){
     case 0:
      if(lastmode != mode)
       printf("paper!\n");
      paper(PWM_period);
      break;
     case 1:
      if(lastmode != mode)
       printf("scissors!\n");
      scissors(PWM_period);
      break;
     case 3:
      if(lastmode != mode)
       printf("rock!\n");
      rock(PWM_period);
      break;
  }
  lastmode = mode;
 }
 i2c_Close();
 rcservo_Close();
 return 0;
}
void rock(unsigned long PWM_period){
 unsigned long PINS1_duty = 1900L;
 unsigned long PINS2_duty = 700L;
 unsigned long PINS3_duty = 1900L;
 rcservo_SendCPWM(RCSERVO_PINS1, PWM_period, PINS1_duty);
 rcservo_SendCPWM(RCSERVO_PINS2, PWM_period, PINS2_duty);
 rcservo_SendCPWM(RCSERVO_PINS3, PWM_period, PINS3_duty);
}
void paper(unsigned long PWM_period){
 unsigned long PINS1_duty = 700L;
 unsigned long PINS2_duty = 1900L;
 unsigned long PINS3_duty = 700L;
 rcservo_SendCPWM(RCSERVO_PINS1, PWM_period, PINS1_duty);
 rcservo_SendCPWM(RCSERVO_PINS2, PWM_period, PINS2_duty);
 rcservo_SendCPWM(RCSERVO_PINS3, PWM_period, PINS3_duty);
}
void scissors(unsigned long PWM_period){
 unsigned long PINS1_duty = 1900L;
 unsigned long PINS2_duty = 1900L;
 unsigned long PINS3_duty = 1900L;
 rcservo_SendCPWM(RCSERVO_PINS1, PWM_period, PINS1_duty);
 rcservo_SendCPWM(RCSERVO_PINS2, PWM_period, PINS2_duty);
 rcservo_SendCPWM(RCSERVO_PINS3, PWM_period, PINS3_duty);
}
Share:

0 留言:

張貼留言

技術提供:Blogger.

追蹤者