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);
}













