Motor Kontrolü¶
Bu Sayfada Ne Anlatıyoruz?¶
Joystick eksenini güvenli biçimde motora çevirmenin temelini kuruyoruz. Hızlı L298N testi ve kütüphaneye uyumlu raw kontrolcüyle aynı fikri temiz ve genişletilebilir hale getiriyoruz.
Önemli uyarı — L298N yarışmada desteklenmez
Bu sayfadaki ilk örnek, sahaya çıkmadan önce hızlı test içindir. L298N yaygın ve kolay bulunur ama yarışmada resmi olarak desteklenmez. Bu modülü yalnızca bağlantıyı doğrulamak ve yön/invert kontrolünü test etmek için kullanın; yarışma robotunda destekli bir kontrolcüye geçeceğiz.
Neden L298N ile başlıyoruz?¶
İlk hedef nettir: Joystick’ten gelen bir ekseni, motorda güvenli bir harekete çevirmek. L298N’in basitliği sayesinde temel akışı, kablo yönü ve invert gibi ayarları hızlıca doğrularız. Kütüphanenin destekli kontrolcülerine geçiş sonra bir dakikalık iştir; bu ilk adım sadece zemini sağlam kılar. Unutmayın: Probot kütüphanesinde her şey “destekli kontrolcü” olmak zorunda değil; isterseniz doğrudan pin düzeyinde de motor sürebilirsiniz.
Bağlantı özeti (L298N + seviye dönüştürücü)¶
ESP32‑S3 kartımız 3.3 V lojik seviyesiyle çalışır; çoğu L298N kartı 5 V lojik bekler. Bu yüzden sinyal hatlarında bir seviye dönüştürücü kullanmanızı öneririz: 4‑kanal logic level converter. ESP’nin GND’sini L298N ve dönüştürücü ile ortaklayın. ENA pinini PWM destekli bir pine bağlayın; IN1/IN2 pinleri yönü belirler (IN1=1/IN2=0 ileri, IN1=0/IN2=1 geri gibi). Motoru teker havadayken deneyin; düşük güçten başlayın. Ayrıntılı şema ve güvenlik notları için elektronik bölümüne bakın.
Yarışma notu
L298N bu dokümanda yalnızca test amaçlıdır. Yarışma robotunda destekli, uygun bir motor kontrolcüsüne geçmeniz gerekir.
Motor Testi (L298N, schedulersiz)¶
Aşağıdaki örnek, tek bir motoru joystick’in sol Y eksenine bağlar. Eksen değerini (−1..1) PWM gücüne (−1000..1000) ölçekler; yön bilgisini IN1/IN2’ye yazar. Kodu karta yükleyip arayüzden Init ve Start’a bastıktan sonra seri ekranda eksen/güç değerini görürsünüz.
#define PROBOT_WIFI_AP_PASSWORD "TakiminizIcinGuv3nliBirSifre"
#include <probot.h>
#include <probot/io/joystick_api.hpp>
#include <math.h>
// L298N kontrolcu pinleri:
// - ENA: hız için PWM (0..255)
// - IN1/IN2: yön seçimi (IN1=1/IN2=0 ileri, tersi geri)
#define PIN_ENA /* DOLDUR */
#define PIN_IN1 /* DOLDUR */
#define PIN_IN2 /* DOLDUR */
// PWM 0..255; küçük titreşimleri yok saymak için deadzone kullanacağız
static const int kPwmMax = 255;
static const float kDeadzone = 0.05f; // eksen mutlak değeri 0.05'ten küçükse 0 kabul
void robotInit(){
// Pinleri çıkış olarak ayarla
pinMode(PIN_ENA, OUTPUT);
pinMode(PIN_IN1, OUTPUT);
pinMode(PIN_IN2, OUTPUT);
// Güvenli başlangıç: hız 0, yön LOW
digitalWrite(PIN_IN1, LOW);
digitalWrite(PIN_IN2, LOW);
analogWrite(PIN_ENA, 0);
}
void robotEnd(){
// Kapanışta motoru bırak
analogWrite(PIN_ENA, 0);
}
void teleopInit(){
// Gerekirse joystick eşlemesini burada ayarlayabilirsiniz
// probot::io::joystick_mapping::setActiveByName("standard");
}
void teleopLoop(){
// Joystick'i oku (varsayılan: deadzone uygulayan ve Y eksenini oyun stiline göre çeviren)
auto js = probot::io::joystick_api::makeDefault();
float axis = js.getLeftY(); // −1..1
// Küçük titreşimleri yok say
if (fabsf(axis) < kDeadzone) axis = 0.0f;
// Yön ve büyüklüğü ayır
bool forward = axis >= 0.0f;
int pwm = (int)(fabsf(axis) * kPwmMax);
if (pwm > kPwmMax) pwm = kPwmMax;
// Yön sinyalleri (pwm=0 ise iki pin de LOW)
if (pwm == 0){
digitalWrite(PIN_IN1, LOW);
digitalWrite(PIN_IN2, LOW);
} else if (forward){
digitalWrite(PIN_IN1, HIGH);
digitalWrite(PIN_IN2, LOW);
} else {
digitalWrite(PIN_IN1, LOW);
digitalWrite(PIN_IN2, HIGH);
}
// Hız (PWM) uygula
analogWrite(PIN_ENA, pwm);
// Hızlı doğrulama (seri)
Serial.print("[L298N] axis=");
Serial.print(axis, 2);
Serial.print(" pwm=");
Serial.println(pwm);
// 20 ms döngü (joystick ve motor akıcı olsun)
delay(20);
}
void autonomousInit(){}
void autonomousLoop(){ delay(1000); }
Kütüphanede destekli kontrolcüler (hızlı bakış)¶
Testi geçtikten sonra yarışma robotunda destekli bir motor kontrolcüsüne geçeceğiz. “Open‑loop” kontrolcü, joystick’ten gelen değeri doğrudan güce çevirir; basit ve hızlıdır. “Kapalı çevrim” kontrol ise encoder gibi sensörlerden aldığı geri bildirimle gücü anlık ayarlar; hız/konum hedefini daha kararlı tutar.
Bu sayfada yalnızca open‑loop yaklaşımı gösterdik; encoder bağlandığında kontrolcüler setVelocity / setPosition ile kapalı çevrime geçebilir. Şimdilik bilmeniz gereken şu: Open‑loop kontrol, doğrudan güç; kapalı çevrim kontrol, sensör geri bildirimiyle hedefi tutturmaya çalışan akıllı katmandır. İkisi de kütüphane ile uyumlu şekilde çalışır.
Zamanlayıcı (scheduler) notu
Basit örneklerimizde merkezi scheduler zorunlu değildir; doğrudan teleopLoop() içinde güncelleme yapıyoruz. Kapalı çevrime geçtiğinizde scheduler kullanmak işleri kolaylaştırır; o noktada kısaca değineceğiz.
Bu yaklaşımın güzelliği şu: İster doğrudan pin düzeyinde sürün, ister kütüphane içindeki arayüz ve kontrolcülerle çalışın; temel mantık aynı kalır. Yarışmaya giderken sahada destekli kontrolcülere geçeriz, ama geliştirme ve doğrulama sırasında bu esneklik hız kazandırır.
Kütüphanede destekli open‑loop kontrolcü (tam örnek)¶
L298N’yi doğruladıktan sonra gerçek motor kontrolcüsüne geçelim. Aşağıdaki örnek, kütüphanedeki BoardozaVNH5019MotorController ile tek motoru joystick eksenine bağlar. EN pinleri kart üzerinde 3V3’e sabitlenmişse -1 bırakabilirsiniz.
#define PROBOT_WIFI_AP_PASSWORD "TakiminizIcinGuv3nliBirSifre"
#include <algorithm>
#include <probot.h>
#include <probot/io/joystick_api.hpp>
#include <probot/devices/motors/boardoza_vnh5019_motor_controller.hpp>
// INA/INB/PWM (+ isteğe bağlı EN pinleri)
static constexpr int PIN_INA = /* DOLDUR */;
static constexpr int PIN_INB = /* DOLDUR */;
static constexpr int PIN_PWM = /* DOLDUR */;
static constexpr int PIN_ENA = -1;
static constexpr int PIN_ENB = -1;
static probot::motor::BoardozaVNH5019MotorController leftMotor(
PIN_INA, PIN_INB, PIN_PWM, PIN_ENA, PIN_ENB);
void robotInit(){
leftMotor.setPower(0.0f);
leftMotor.setBrakeMode(true); // Boşta fren, isteğe bağlı
}
void robotEnd(){
leftMotor.setPower(0.0f);
}
void teleopInit(){
// Gerekirse joystick eşlemesini burada ayarlayabilirsiniz
// probot::io::joystick_mapping::setActiveByName("standard");
}
void teleopLoop(){
auto js = probot::io::joystick_api::makeDefault();
float axis = js.getLeftY(); // −1..1
float cmd = std::clamp(axis, -1.0f, 1.0f);
leftMotor.setPower(cmd);
Serial.printf("[VNH] axis=%.2f power=%.2f\n", axis, cmd);
delay(20);
}
void autonomousInit(){}
void autonomousLoop(){ delay(1000); }
Sonraki Adımlar¶
Tek motorla doğrulanan akış, şasi ve mekanizmalara taşındığında saha testleri çok hızlanır. Devamında iki motorla sürüş, ardından kapalı çevrim ve güvenli sınırlar eklenerek robot davranışı güçlü bir temele oturur.