DMP小手 (RS0263*3)
RS0263為RoBoard的馬達
必須用RC servo控制馬達轉動
- RC servo的控制原理
- 利用 PWM pulse 的寬度指定 servo 轉動的位置
- controller circuit 控制 servo 轉到指定的位置
- feedback potentiometer 會將 servo 目前的位置迴授給控制器
所以並不會將servo的位置回傳
- 腳位相對位置
而RB110只有16個PWM
但其實還是十分好分辨的靠外側的腳位為地(GND) 通常接的為黑線
靠中間的腳位為電(Vxx) 通常接的為紅線
靠內側的腳位為訊號(GPxx) 沒有特定顏色
切記勿接錯 否則會發生慘案
然而腳位編號請看官網的介紹投影片(Hardware Introduction Slide)
- RC Servo lib
這邊記得將要用的所有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); }