Servo的使用,以SG90舵機為例
舵機控制說明 (Servo.h裡時間單位都是微秒us,角度是°)
舵機透過脈衝寬度的時間
來控制(PWM
),頻率是50Hz的(即一個週期是20ms)。(!!!脈寬是本質)
SG90舵機的控制引數範圍是:0°: 0.5ms , 180°: 2.5ms
。
然後對於每一度,將脈寬範圍除以180°即得。
servo.attach(GIO, pulse_width_min, pulse_width_max);
這裡就可以設定上面的脈寬min和max(出於安全考慮,Servo的預設值是1000,2000,導致實際執行時並不是滿的180°)
使用,實際就是設定脈寬:
servo.write(degree_OR_pulse_width_in_us);
當值<200時,引數為度數
,根據上面除法得到每度的脈寬然後內部設定對應脈寬(範圍內);
超過200後,值代表脈寬
(範圍內),直接寫入脈寬,和servo.writeMicroseconds()
一樣。
注意超出範圍的值將被設為最低或最大值
舵機執行的實際脈寬:可用servo.read()
檢視度數,servo.readMicroseconds()
檢視實際脈寬。
總之,使用Servo的時候,要先確定自己舵機的pwm控制引數,然後在attach的時候設定好,才能得到對應的角度。
測試程式碼
#include <Servo.h>
Servo my_ser;
void setup()
{
Serial.begin(115200);
Serial.println();Serial.println();
my_ser.attach(2, 500, 2500); //將舵機訊號連線到GPIO2, D4,設定高電平脈衝時間上下限(保證實際轉動角度的引數)
my_ser.write(0);
delay(100);
}
//展示了脈寬變化和對應的實際脈寬
void loop()
{
//degree change
for (int i = 0; i < 200; i+=1) {
my_ser.write(i);
Serial.printf("i: %d\tdegree: %d\tpulse_width_us: %d\n", i, my_ser.read(), my_ser.readMicroseconds());
delay(200);
}
//pulse width change
for (int i = 200; i < 2600; i+=1) {
my_ser.write(i); //等價於my_ser.writeMicroseconds(i);
Serial.printf("i: %d\tdegree: %d\tpulse_width_us: %d\n", i, my_ser.read(), my_ser.readMicroseconds());
delay(200);
}
}
用analog直接控制脈衝
analogWriteFreq(freq);
:設定頻率,一般50Hz
analogWriteRange(range);
:設定步長,即將一個週期分成多少份,使用時的單位就是份數了
analogWrite(PIN, value);
:將PIN的脈寬設為value份數。取值範圍為(0, range),實際就是設定脈寬多少
#include <Servo.h>
const uint8_t servo = 2; //舵機在GPIO2
Servo my_ser;
void setup() {
Serial.begin(115200);
Serial.println();
analogWriteFreq(50); //設定頻率為50Hz,即週期20ms
analogWriteRange(200); //將20ms分成200份,每份0.1ms
my_ser.attach(servo);
analogWrite(servo, 5); //初始化
delay(500);
analogWrite(LED_BUILTIN, 200);
delay(200);
}
void loop() {
for (int i = 5; i < 26; i++) {
analogWrite(servo, i);
Serial.printf("i: %d\tdegree: %d\tpulse_width_us: %d\n", i, my_ser.read(), my_ser.readMicroseconds());
delay(1000);
}
}
值得注意的是,輸出始終為i: i可變 degree: 90 pulse_width_us: 1500
,而其它值不變,沒試my_ser.write
,但是用analog就沒什麼必要了,且它的read
都不可用了的樣子,值一直不變。
參考資料
程式碼裡的Servo.h
另外,arduino常有不程式碼提示的問題,我看網上說好像要把專案放在設定裡那個位置才行,不過有時候又可以,我又懶得放那,就沒試了。
analog:[【萬物皆可PWM!使用ESP8266驅動SG90舵機!】