//加一顆 LED 測試 Uno 是否能正常工作
setup(){
pinMode(6, OUTPUT);
}
loop(){
digitalWrite(6, HIGH);
delay(1000);
digitalWrite(6, LOW);
delay(1000);
}
舵機藉由回饋訊號控制,以 SG90S 為例,其內部有一個可變電阻,電阻值會根據直流馬達轉動而改變
改變的電阻值會產生相對應直流電壓,與外部脈波信號產生的相對應直流電壓的壓差再回饋到直流馬達上
當二者電壓差值為 0 時,舵機停止
基本驅動的方式為輸入一個 50Hz,脈波範圍從 1.0ms 到 2.0ms 的 PWM 值
依據規格書上說明,50Hz 1.5ms 的脈波會讓舵機位置置中,1ms 的脈波會讓舵機 all the way left,反之 2ms 的脈波會讓舵機 all the way right
使用上會以函式庫為主
要特別注意的是當發生舵機堵轉(因為某種因素無法轉到要求的位置)時,會導致電流異常持續升高或減速齒輪空轉磨齒損壞電機
SG90S 規格
重量:9g
尺寸:23*12.2*29mm
工作電壓:4.8V(~5V)
轉矩:1.8kg-cm,當工作電壓為4.8V時
運轉速度:0.1秒 ∕ 60度 ,當工作電壓為4.8V時
脈衝寬度範圍:500~2400µs
死頻帶寬度(dead band width):10µs
#include <Servo.h>
Servo myservo;
int pos = 0;
void setup(){
myservo.attach(9);
}
void loop(){
for(pos = 20; pos <= 110; pos += 1){
myservo.write(pos);
delay(10);
}
for(pos = 110; pos >= 20; pos += -1){
myservo.write(pos);
delay(10);
}
}
透過改變磁極來驅動中心轉子
相較於舵機藉由回饋訊號控制,
步進馬達則屬於無回饋信號的 Open Loop Control System
換句話說就是射後不理
幾個有趣的步進電機驅動
使用 uln2003 IC 來做驅動 28BYJ-48, 5V DC,規格如下:
• 工作電壓: 5~12V DC
• 轉一圈步數:5.625度/64 (搭配 1/64減速齒輪達到 4096 脈波數轉一圈)
• 每分鐘圈數:80 RPM(Revolution per minute)
• 重量:37 公克
int motorPin1 = 8;
int motorPin2 = 9;
int motorPin3 = 10;
int motorPin4 = 11;
int motorSpeed = 5;
// 1相激磁
void clockwise3() {
// 1
digitalWrite(motorPin4, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, LOW);
delay(motorSpeed);
// 2
digitalWrite(motorPin4, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, LOW);
delay(motorSpeed);
// 3
digitalWrite(motorPin4, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin1, LOW);
delay(motorSpeed);
// 4
digitalWrite(motorPin4, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, HIGH);
delay(motorSpeed);
}
// 1-2相激磁
void counterclockwise (){
// 1
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay(motorSpeed);
// 2
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay (motorSpeed);
// 3
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay(motorSpeed);
// 4
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
delay(motorSpeed);
// 5
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
delay(motorSpeed);
// 6
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, HIGH);
delay (motorSpeed);
// 7
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
delay(motorSpeed);
// 8
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
delay(motorSpeed);
}
//2相激磁
void clockwise2() {
// 1
digitalWrite(motorPin4, HIGH);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, LOW);
delay(motorSpeed);
// 2
digitalWrite(motorPin4, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin1, LOW);
delay(motorSpeed);
// 3
digitalWrite(motorPin4, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin1, HIGH);
delay(motorSpeed);
// 4
digitalWrite(motorPin4, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, HIGH);
delay(motorSpeed);
}
#include <Stepper.h>
Stepper stepper(64, 8,9,10,11);
//轉一圈為64步 (360/5.625 deg),定義8,9,10,11為輸出腳位
void setup(){
//將馬達的速度設定成80RPM
stepper.setSpeed(80);
}
void loop(){
stepper.step(256);//正半圈
delay(1000);
stepper.step(-256);//反半圈
delay(1000);
stepper.step(512);//正1圈
delay(1000);
stepper.step(-512);//反1圈
delay(1000);
}
發現步進馬達不會反向轉,問題出在官方的函式庫驅動的順序
修改 libraries\Stepper\src\Stepper.cpp 約 186 行
將
if (this->pin_count == 4) {
switch (thisStep) {
case 0: // 1010
digitalWrite(motor_pin_1, HIGH);
digitalWrite(motor_pin_2, LOW);
digitalWrite(motor_pin_3, HIGH);
digitalWrite(motor_pin_4, LOW);
break;
case 1: // 0110
digitalWrite(motor_pin_1, LOW);
digitalWrite(motor_pin_2, HIGH);
digitalWrite(motor_pin_3, HIGH);
digitalWrite(motor_pin_4, LOW);
break;
case 2: //0101
digitalWrite(motor_pin_1, LOW);
digitalWrite(motor_pin_2, HIGH);
digitalWrite(motor_pin_3, LOW);
digitalWrite(motor_pin_4, HIGH);
break;
case 3: //1001
digitalWrite(motor_pin_1, HIGH);
digitalWrite(motor_pin_2, LOW);
digitalWrite(motor_pin_3, LOW);
digitalWrite(motor_pin_4, HIGH);
break;
}
改成
if (this->pin_count == 4) {
switch (thisStep) {
case 0: // 0011
digitalWrite(motor_pin_1, LOW);
digitalWrite(motor_pin_2, LOW);
digitalWrite(motor_pin_3, HIGH);
digitalWrite(motor_pin_4, HIGH);
break;
case 1: // 0110
digitalWrite(motor_pin_1, LOW);
digitalWrite(motor_pin_2, HIGH);
digitalWrite(motor_pin_3, HIGH);
digitalWrite(motor_pin_4, LOW);
break;
case 2: //1100
digitalWrite(motor_pin_1, HIGH);
digitalWrite(motor_pin_2, HIGH);
digitalWrite(motor_pin_3, LOW);
digitalWrite(motor_pin_4, LOW);
break;
case 3: //1001
digitalWrite(motor_pin_1, HIGH);
digitalWrite(motor_pin_2, LOW);
digitalWrite(motor_pin_3, LOW);
digitalWrite(motor_pin_4, HIGH);
break;
}