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); // 給舵機一點緩衝的時間

}