arduino學習筆記5 舵機控制
阿新 • • 發佈:2019-01-01
舵機控制
舵機是一種位置伺服的驅動器,主要是由外殼、電路板、無核心馬達、齒輪與位置檢測器所構成。其工作原理是由接收機或者單片機發出訊號給舵機,其內部有一個基準電路,產生週期為20ms,寬度為1.5ms的基準訊號,將獲得的直流偏置電壓與電位器的電壓比較,獲得電壓差輸出。經由電路板上的IC判斷轉動方向,再驅動無核心馬達開始轉動,透過減速齒輪將動力傳至擺臂,同時由位置檢測器送回訊號,判斷是否已經到達定位。適用於那些需要角度不斷變化並可以保持的控制系統。當電機轉速一定時,通過級聯減速齒輪帶動電位器旋轉,使得電壓差為0,電機停止轉動。一般舵機旋轉的角度範圍是0度到180 度。具體的旋轉範圍根據舵機型號有所不同。
大多數規格的舵機都會引出三根線,常見的是紅棕橙三個顏色,也有紅白黑三色的。紅色為5v電源線,黑色或棕色線為接地線,橙色或白色線為訊號線。
用Arduino控制舵機的方法有兩種,一種是通過Arduino 的普通數字感測器介面產生佔空比不同的方波,模擬產生PWM訊號進行舵機定位,第二種是直接利用Arduino 自帶的Servo函式進行舵機的控制,這種控制方法的優點在於程式編寫,缺點是隻能控制2 路舵機,因為Arduino 自帶函式只能利用數字9、10介面。Arduino 的驅動能力有限,所以當需要控制1個以上的舵機時需要外接電源。
以下實驗僅需要一紮跳線和一個舵機。
//UART send 1~9==>20~180 degree int servopin=9;//設定舵機驅動腳到數字口9 int myangle;//定義角度變數 int pulsewidth;//定義脈寬變數 int val; void servopulse(int servopin,int myangle)/*定義一個脈衝函式,用來模擬方式產生PWM值*/ { pulsewidth=(myangle*11)+500;//將角度轉化為500-2480 的脈寬值 digitalWrite(servopin,HIGH);//將舵機介面電平置高 delayMicroseconds(pulsewidth);//延時脈寬值的微秒數 digitalWrite(servopin,LOW);//將舵機介面電平置低 delay(20-pulsewidth/1000);//延時週期內剩餘時間 } void setup() { pinMode(servopin,OUTPUT);//設定舵機介面為輸出介面 Serial.begin(9600);//設定波特率為9600 Serial.println("servo=o_seral_simple ready" ) ; } void loop() { val=Serial.read();//讀取串列埠收到的資料 if(val>'0'&&val<='9')//判斷收到資料值是否符合範圍 { val=val-'0';//將ASCII碼轉換成數值,例'9'-'0'=0x39-0x30=9 val=val*(180/9);//將數字轉化為角度,例9*(180/9)=180 Serial.print("moving servo to "); Serial.print(val,DEC); Serial.println(); for(int i=0;i<=50;i++) //產生PWM個數,等效延時以保證能轉到響應角度 { servopulse(servopin,val);//模擬產生PWM } } }
以上程式碼的效果為:輸入數字1,舵機角度為20度,輸入2,舵機為40度,以此類推,直到輸入9,舵機輸出180為止。
現將其進行修改
int servopin=9;//設定舵機驅動腳到數字口9
int myangle;//定義角度變數
int pulsewidth;//定義脈寬變數
int val;
void servopulse(int servopin,int myangle)/*定義一個脈衝函式,用來模擬方式產生PWM值*/
{
pulsewidth=(myangle*11)+500;//將角度轉化為500-2480 的脈寬值
digitalWrite(servopin,HIGH);//將舵機介面電平置高
delayMicroseconds(pulsewidth);//延時脈寬值的微秒數
digitalWrite(servopin,LOW);//將舵機介面電平置低
delay(20-pulsewidth/1000);//延時週期內剩餘時間
}
void setup()
{
pinMode(servopin,OUTPUT);//設定舵機介面為輸出介面
Serial.begin(9600);//設定波特率為9600
}
void loop()
{
val=Serial.read();//讀取串列埠收到的資料
if(val>='0'&&val<='1') //判斷收到資料值是否符合範圍
{
val=val-'0'; //將ASCII碼轉換成數值,例'9'-'0'=0x39-0x30
val=val+1;
val=val*10*val*val;//將數字轉化為角度
Serial.print("moving servo to ");
Serial.print(val,DEC);
Serial.println();
for(int i=0;i<=50;i++) //給予舵機足夠的時間讓它轉到指定角度
{
servopulse(servopin,val);//引用脈衝函式
}
}
}
此時如果將舵機裝於機械爪上,則效果為,輸入1爪子張開,輸入0爪子閉合。