Ana içeriğe geç

Gamepad Kontrolü - Arduino'dan Probot'a

Arduino projelerinde joystick kontrolü için genelde analog pinlere potansiyometre bağlarsınız. Probot'ta ise WiFi üzerinden gerçek gamepad kullanabilirsiniz! Xbox, PlayStation kontrolcüleri desteklenir.

Arduino vs Probot Kontrol

Arduino Analog Joystick

void loop() {
    // Fiziksel analog joystick okuma
    int xValue = analogRead(A0);  // X ekseni
    int yValue = analogRead(A1);  // Y ekseni
    bool buttonPressed = !digitalRead(2); // Buton (pull-up)

    // -255 ile +255 arası motor kontrolü
    int motorSpeed = map(yValue, 0, 1023, -255, 255);

    if (buttonPressed) {
        motorSpeed = 0; // Buton basılıysa dur
    }

    // Motor kontrolü
    analogWrite(MOTOR_PWM, abs(motorSpeed));
    digitalWrite(MOTOR_DIR, motorSpeed > 0);

    delay(20); // Stabillik için
}

Probot WiFi Gamepad

#include <probot.h>

TunaGamepad gamepad(robot);
BasicMotorController motor(9, 8, 7);

void teleopLoop() {
    // WiFi gamepad okuma (çok daha kolay!)
    float forwardPower = -gamepad.getAxis(Axis::LeftJoystickY);  // -1.0 ile +1.0
    float rotationPower = gamepad.getAxis(Axis::RightJoystickX);

    // Buton kontrolü
    if (gamepad.getButton(Button::A)) {
        forwardPower = 0; // A basılıysa dur
    }

    // Tank drive kontrolü
    float leftPower = forwardPower + rotationPower;
    float rightPower = forwardPower - rotationPower;

    leftMotor.setPower(leftPower);
    rightMotor.setPower(rightPower);

    // delay() gerekmez! Sistem otomatik 20ms döngüsü
}

Görüldüğü gibi: Arduino'da 10+ satır kod, Probot'ta 5 satır!

Temel Gamepad Kullanımı

Eksenler (Axis)

void teleopLoop() {
    // Sol joystick
    float leftX = gamepad.getAxis(Axis::LeftJoystickX);   // -1.0 ile +1.0
    float leftY = gamepad.getAxis(Axis::LeftJoystickY);   // -1.0 ile +1.0

    // Sağ joystick  
    float rightX = gamepad.getAxis(Axis::RightJoystickX); // -1.0 ile +1.0
    float rightY = gamepad.getAxis(Axis::RightJoystickY); // -1.0 ile +1.0

    // Tetikleyiciler
    float leftTrigger = gamepad.getAxis(Axis::LeftTrigger);   // 0.0 ile 1.0
    float rightTrigger = gamepad.getAxis(Axis::RightTrigger); // 0.0 ile 1.0

    Serial.print("Sol Y: ");
    Serial.print(leftY);
    Serial.print(" | Sağ X: ");
    Serial.println(rightX);
}

Butonlar

void teleopLoop() {
    // Ana butonlar
    if (gamepad.getButton(Button::A)) {
        Serial.println("A butonu basıldı!");
    }

    if (gamepad.getButtonPressed(Button::B)) {
        Serial.println("B butonu basıldı (bir kez)!");
    }

    if (gamepad.getButtonReleased(Button::X)) {
        Serial.println("X butonu bırakıldı!");
    }

    // D-Pad
    if (gamepad.getButton(Button::DPadUp)) {
        Serial.println("Yukarı ok basıldı!");
    }

    // Shoulder butonları
    if (gamepad.getButton(Button::LeftShoulder)) {
        Serial.println("Sol shoulder basıldı!");
    }
}

Joystick Butonları

void teleopLoop() {
    // Joystick'e basma (L3/R3)
    if (gamepad.getButtonPressed(Button::LeftJoystick)) {
        Serial.println("Sol stick basıldı - reset");
    }

    if (gamepad.getButtonPressed(Button::RightJoystick)) {
        Serial.println("Sağ stick basıldı - ayar değiştir");
    }
}

Arduino'dan Probot'a Dönüşüm Örnekleri

Örnek 1: Tank Drive Robotu

Arduino Versiyonu

// 2 potansiyometre ile tank drive
void loop() {
    int leftPot = analogRead(A0);   // Sol joystick
    int rightPot = analogRead(A1);  // Sağ joystick

    // -255 ile +255 arası motor değerleri
    int leftMotor = map(leftPot, 0, 1023, -255, 255);
    int rightMotor = map(rightPot, 0, 1023, -255, 255);

    // Sol motor kontrolü
    analogWrite(LEFT_MOTOR_PWM, abs(leftMotor));
    digitalWrite(LEFT_MOTOR_DIR, leftMotor > 0);

    // Sağ motor kontrolü  
    analogWrite(RIGHT_MOTOR_PWM, abs(rightMotor));
    digitalWrite(RIGHT_MOTOR_DIR, rightMotor > 0);

    delay(20);
}

Probot Versiyonu

void teleopLoop() {
    // WiFi gamepad ile tank drive
    float leftPower = -gamepad.getAxis(Axis::LeftJoystickY);
    float rightPower = -gamepad.getAxis(Axis::RightJoystickY);

    leftMotor.setPower(leftPower);   // Direkt güç ayarı
    rightMotor.setPower(rightPower);
}

Örnek 2: Arcade Drive (Tek Joystick)

Arduino Versiyonu

void loop() {
    int forwardPot = analogRead(A0);  // İleri-geri
    int turnPot = analogRead(A1);     // Sağa-sola

    int forward = map(forwardPot, 0, 1023, -255, 255);
    int turn = map(turnPot, 0, 1023, -255, 255);

    // Arcade drive hesaplaması
    int leftMotor = forward + turn;
    int rightMotor = forward - turn;

    // Motor değerlerini sınırla
    leftMotor = constrain(leftMotor, -255, 255);
    rightMotor = constrain(rightMotor, -255, 255);

    // Motor kontrolü...
    delay(20);
}

Probot Versiyonu

void teleopLoop() {
    float forward = -gamepad.getAxis(Axis::LeftJoystickY);
    float turn = gamepad.getAxis(Axis::LeftJoystickX);

    // Arcade drive (Probot otomatik sınırlar)
    tankdrive.arcadeDrive(forward, turn);
}

Örnek 3: Servo Kontrol

Arduino Versiyonu

#include <Servo.h>

Servo gripper;

void setup() {
    gripper.attach(9);
}

void loop() {
    int potValue = analogRead(A0);
    int servoAngle = map(potValue, 0, 1023, 0, 180);

    gripper.write(servoAngle);

    delay(15); // Servo için stabillik
}

Probot Versiyonu

#include <Servo.h>

Servo gripper;

void robotInit() {
    gripper.attach(9);
}

void teleopLoop() {
    // Tetikleyici ile servo kontrolü
    float trigger = gamepad.getAxis(Axis::RightTrigger); // 0.0-1.0
    int servoAngle = trigger * 180; // 0-180 derece

    gripper.write(servoAngle);

    // delay() gerekmez
}

Yaygın Hatalar

1. Eksen Yönlerini Karıştırmak

// ❌ Y ekseni ters olabilir
float forward = gamepad.getAxis(Axis::LeftJoystickY);  // Robot geri gidebilir

// ✅ Eksiyi test edin
float forward = -gamepad.getAxis(Axis::LeftJoystickY); // Genelde minus gerekir

2. getButton vs getButtonPressed

// ❌ Sürekli tetiklenir
if (gamepad.getButton(Button::A)) {
    Serial.println("A basıldı!"); // Her 20ms yazdırır!
}

// ✅ Sadece bir kez tetiklenir
if (gamepad.getButtonPressed(Button::A)) {
    Serial.println("A basıldı!"); // Sadece basma anında
}

3. Gamepad Bağlantısını Kontrol Etmemek

// ❌ Gamepad bağlı değilse çöker
float power = gamepad.getAxis(Axis::LeftJoystickY);

// ✅ Önce bağlantıyı kontrol et
if (gamepad.isConnected()) {
    float power = gamepad.getAxis(Axis::LeftJoystickY);
    motor.setPower(power);
} else {
    motor.setPower(0); // Güvenli mod
}

Gamepad Debugging

Bağlantı Kontrolü

void teleopLoop() {
    if (gamepad.isConnected()) {
        Serial.println("Gamepad bağlı ✓");
    } else {
        Serial.println("Gamepad bağlı değil ✗");
    }
}

Tüm Değerleri Görme

void teleopLoop() {
    Serial.print("LY: "); Serial.print(gamepad.getAxis(Axis::LeftJoystickY));
    Serial.print(" | LX: "); Serial.print(gamepad.getAxis(Axis::LeftJoystickX));
    Serial.print(" | A: "); Serial.print(gamepad.getButton(Button::A));
    Serial.print(" | B: "); Serial.println(gamepad.getButton(Button::B));
}

Gamepad Tipi Öğrenme

void robotInit() {
    Serial.print("Gamepad tipi: ");
    Serial.println(gamepad.getControllerName());
}

Avantajlar - Arduino'ya Göre

Arduino Zorlukları:

  • Fiziksel joystick gerekir (pahalı, yer kaplar)
  • Kablo karmaşası (potansiyometre, butonlar)
  • Analog okuma noise'u (filtreleme gerekir)
  • Sınırlı buton sayısı
  • Manuel mapping gerekir

Probot Kolaylıkları:

  • Kablosuz kontrol (WiFi üzerinden)
  • Profesyonel gamepad (Xbox, PlayStation)
  • Otomatik filtreleme (smooth değerler)
  • Çok buton/eksen (16+ buton, 6+ eksen)
  • Otomatik mapping (değerler hazır)

Sonraki Adımlar

  1. Web Interface - Gamepad'i web'den görüntüleme
  2. Lifecycle Differences - Teleop vs Auto modları
  3. Pratik Örnekler - Gerçek robot projeleri

İpucu: Gamepad kontrolü Arduino'da çok zor olan bir şey. Probot bunu çok kolaylaştırıyor. Potansiyometre ve butonlarla uğraşmak yerine profesyonel gamepad kullanın!