舵機是一種位置伺服的驅動器,主要是由外殼、電路板、無核心馬達、齒輪與位置檢測器所構成。其工作原理是由接收機或者單片機發出信號給舵機,其內部有一個基准電路,產生周期為20ms,寬度為1.5ms的基准信號,將獲得的直流偏置電壓與電位器的電壓比較,獲得電壓差輸出。經由電路板上的IC判斷轉動方向,再驅動無核心馬達開始轉動,透過減速齒輪將動力傳至擺臂,同時由位置檢測器送回信號,判斷是否已經到達定位。適用於那些需要角度不斷變化並可以保持的控制系統。當電機轉速一定時,通過級聯減速齒輪帶動電位器旋轉,使得電壓差為0,電機停止轉動。一般舵機旋轉的角度范圍是0°到180°度。
舵機有很多規格,但所有的舵機都有外接三根線,分別用棕、紅、橙三種顏色進行區分,由於舵機品牌不同,顏色也會有所差異,棕色為接地線,紅色為電源正極線,橙色為信號線。
舵機的轉動的角度是通過調節PWM(脈沖寬度調制)信號的占空比來實現的,標准PWM(脈沖寬度調制)信號的周期固定為20ms(50Hz),理論上脈寬分布應在1ms到2ms之間,但是,事實上脈寬可由0.5ms到2.5ms之間,脈寬和舵機的轉角0°~180°相對應。有一點值得注意的地方,由於舵機牌子不同,對於同一信號,不同牌子的舵機旋轉的角度也會有所不同。
大概了解了舵機以后,我們就試着來控制一個舵機吧,將GND和+5V連接好之后,我選擇信號輸入口為數字接口7,至於供電部分要注意,舵機轉動時電流會比較大,Arduino上的電源芯片可能會因過流保護到發熱而損壞,電源需要接到外部供電,切不可使用USB供電(本人嘗試過,深受其害)。
我本人更喜歡使用Arduino的傳感器擴展板,如下圖,連接舵機或傳感器是超方便的。
連接好電路就來編寫程序吧,我就讓舵機轉動到我輸入數字所對應的角度數,並將角度顯示到屏幕上。
程序如下:
int servopin=7;//定義舵機接口數字接口7
int myangle;//定義角度變量
int pulsewidth;//定義脈寬變量
int val;
void servopulse(int servopin,int myangle)//定義一個脈沖函數
{
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("servu=o_seral_simple ready" ) ;
}
void loop()//將0到9的數轉化為0到180角度,並讓LED閃爍相應數的次數
{
val=Serial.read();//讀取串行端口的值
if(val>'0'&&val<='9')
{
val=val-'0';//將特征量轉化為數值變量
val=val*(180/9);//將數字轉化為角度
Serial.print("moving servo to ");
Serial.print(val,DEC);
Serial.println();
for(int i=0;i<=50;i++)//給予舵機足夠的時間讓它轉到指定角度
{
servopulse(servopin,val);//引用脈沖函數
}
}
}
下載完程序就可以輸入1到9的數字,讓你的舵機轉相應的20°到180°了。
這里還有一個引用庫函數的控制舵機的程序(取自Burn's Interactive ),供大家參考。
arduino0012版本新增伺服電機控制lib,可以讓arduino更容易的控制伺服電機。
// 使用可變電阻控制伺服電機位置
#include <Servo.h> //引入lib
Servo myservo; // 創建一個伺服電機對象
int potpin = 0; // 設定連接可變電阻的模擬引腳
int val; // 創建變量,儲存從模擬端口讀取的值(0到1023)
void setup()
{
myservo.attach(9); // 9號引腳輸出電機控制信號
//僅能使用9、10號引腳
}
void loop()
{
val = analogRead(potpin);
// 讀取來自可變電阻的模擬值(0到1023之間)
val = map(val, 0, 1023, 0, 179); // 利用“map”函數縮放該值,得到伺服電機需要的角度(0到180之間)
myservo.write(val); // 設定伺服電機的位置
delay(15); // 等待電機旋轉到目標角度
}
特別需要注意的是控制信號只能通過9、10號引腳輸出,也就是說,該lib最多可以控制兩個伺服電機。