Arduino的搖桿控制板
認識並使用JoySticky(搖桿控制板)來操控MeArm
先來認識一下Arduino專用的雙搖桿搖桿擴充板,以下二款是網路上常買得到的板子,價位大約二百元上下,特別都是具有二個PS2相容的搖桿及設計好的舵機插槽和藍芽模組插槽(建議是使用HC-05或HC-06)
MeArm專用搖桿控制板
這一款是專為MeArm設計的Arduino搖桿擴充板,注意看舵機插槽的標示,右側有明確地標出GND,VCC,PWM分別代表接地(-)、電源和訊號,下方還標出BASE,L,R,Claw是舵機順序
Arduino專用搖桿控制板
另外這款雖沒標示MeArm專用,但也是一樣的,舵機pin有六個,我們只用由左向右的四個,注意GND是在下方
看一下擴充板後方留的針腳再看一下Arduino上的pin位,應該很容易就猜到它們如何接在一起
藍芽模組
藍芽模組插入預留的插槽
如果買來的藍芽模組是六根pin的,就插入中間的四根
如果你已經上傳了相關的程式碼到Arduino UNO裡,那麼你應該可以用搖桿來控制機械手臂了…,這也算是MeArm的初步操作,可以試試如何移動它!
※一般來說,從坊間購買的套件,有的會預先將可以操控的程式碼燒錄到板子裡,一接好線就能立即使用,但我們還是要自己稍微研究一下這其中的程式寫法,才有學習的價值
研究一下Arduino搖桿板的程式寫法
在研究程式之前,我們先了解下控制板硬體部份的參數,像是四顆舵機是佔用了哪些pin(D11,D10,D9,D5),而搖桿則佔用了類比值輸入pin(A0~A3),T當移動搖桿時,它會送給Arduino(0~1023)的數值,而我們在程式中藉由這個值的判斷來決定手臂的動作…
#include <Servo.h>
const int SERVOS = 4; //定義使用4個舵機
const int ACC = 10; // 閒置開始計數之前電位計值的精度
//定義使用到的陣列變數
int PIN[SERVOS], value[SERVOS], idle[SERVOS], currentAngle[SERVOS], MIN[SERVOS], MAX[SERVOS], INITANGLE[SERVOS], previousAngle[SERVOS], ANA[SERVOS];
Servo myservo[SERVOS]; //建立舵機物件
void setup() {
//各舵機的初始設定
//底部舵機
PIN[0] = 11; // 這個舵機接的pin
MIN[0] = 10; // 舵機角度最小值
MAX[0] = 179; // 舵機角度最大值
INITANGLE[0] = 90; // 啟動時舵機的預設位置
ANA[0] = 0; //搖桿接的pin
//左側舵機
PIN[1] = 10;
MIN[1] = 10;
MAX[1] = 115;
INITANGLE[1] = 90;
ANA[1] = 1;
//右側舵機
PIN[2] = 9;
MIN[2] = 40;
MAX[2] = 170;
INITANGLE[2] = 90;
ANA[2] = 2;
//夾子舵機
PIN[3] = 5;
MIN[3] = 10;
MAX[3] = 102;
INITANGLE[3] = 60;
ANA[3] = 3;
//下面的程式才是實際執行動作,將上頭的設定帶進舵機
for (int i = 0; i < SERVOS; i++) {
myservo[i].attach(PIN[i]);
myservo[i].write(INITANGLE[i]);
value[i] = 0;
idle[i] = 0;
previousAngle[i] = INITANGLE[i];
}
}
void loop() {
for (int i = 0; i < SERVOS; i++) {
value[i] = analogRead(ANA[i]); //讀取搖桿數值
currentAngle[i] = myservo[i].read(); //讀取舵機角度值
if (value[i] > 800) {
idle[i] = 0;
if (currentAngle[i] > MIN[i]) currentAngle[i] -= 2;
if (!myservo[i].attached()) {
myservo[i].attach(PIN[i]);
}
myservo[i].write(currentAngle[i]);
} else if (value[i] < 300) {
idle[i] = 0;
if (currentAngle[i] < MAX[i]) currentAngle[i] += 2;
if (!myservo[i].attached()) {
myservo[i].attach(PIN[i]);
}
myservo[i].write(currentAngle[i]);
} else {
++idle[i];
}
}
if (idle[3] > 100) {
myservo[3].detach();
idle[3] = 0;
}
delay(20); // 給舵機一點緩衝的時間
}