Robotik
OKUDUĞUNUZ KONU
Arduino Kendini Dengeleyen Robot
90

Arduino Kendini Dengeleyen Robot

Yazar : Murat Duran25 Ekim 2015
Projeyi Satın Al
Bu projeyi kurulu çalışır halde yada isterseniz demonte halde satın alabilirsiniz.Proje ile birlikle yapım aşaması resimleri bağlantı şemaları ve kodları açık kaynak olarak gönderilir. "Satın Almak İçin Yukarıda Butona Basınız"

Daha önceden kendini dengeleyen robot projesi paylaşmıştık , bu robotumuz çok katlı ve dengede durması biraz daha zor.Bu yüzden kodlamada gelişmiş PID algoritma kullanıldı.Bu tarz robotlarda normalde enkoderli motor kullanılır ama bu motorlar pahalı olduğundan tercih etmedik piyasada 15-16 tl ye bulabileceğiniz ucuz motorları kullandık.Plastik için saklama kabı , demirler içinde M3 gijon kullanıldı.Herhangi bir hırdavatçıdan temin edebileceğiniz malzemeler

Kontrol kartı olarak Arduino UNO , motor sürücü için L298N modeli tercih edildi.Bu model sinyallere gayet iyi tepki veriyor.Ayırıca piyasada bulunur ve ucuz.İvme ölçer için MPU6050 kullanıldı.Kendinden 3 eksen GYRO da var.

Malzemeler

Öncelikle aşağıdaki resimlere bakarak benzer bir iskelet oluşturmaya çalışın.Motorları yerleştirirken denge merkezine koymaya çalışın.Ne kadar düzgün olursa robotunuz o kadar verimli çalışır.

Ortama 20×8 cm boyutlarında 3 tane plastik tabaka kesin.Ardından gijonu 20 cm uzunluklara bölün.Plastik tabakaların köşelerinden delerek giyonları yerleştirin ve robotunuzu 3 kalı şekilde ayarlayın.

Projenin mekanik kısmını hazırladıktan sonra elektronik bölümünü eklemeniz gerekiyor.Arduino , motor sürücü gibi kartları yerleştirirken yine ağırlık merkezine dikkat ederek yerleştirin.L928N Motor sürücü ve MOU6050 ivme ölçer bağlantısı aşağıdaki gibidir.

Ardından gijonların üzerine 3 tane potansiyemetreyi silikonla tutturun ve bu potansiyemetereli arduinoda sırasyıyla A0 , A1 ve A2 girişlerine bağlıyoruz.Ayarlarla oynadığımızda KP , KD ve Kİ değerleri değişmektedir.Robotumuzun son halleri.

Kendini Dengeleyen Robot Kütüphaneleri İndir , Projemizin arduino kodları –>

//Proje Hocam - Kendini Dengeleyen Robot
//www.projehocam.com
#include <PID_v1.h>
#include <LMotorController.h>
#include "I2Cdev.h"

#include "MPU6050_6Axis_MotionApps20.h"

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif


#define LOG_INPUT 0
#define MANUAL_TUNING 0
#define LOG_PID_CONSTANTS 0 
#define MOVE_BACK_FORTH 0

#define MIN_ABS_SPEED 30 // Minumum Başlangıç Hızı

//MPU


MPU6050 mpu;

// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorFloat gravity;    // [x, y, z]            gravity vector
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector


//PID


#if MANUAL_TUNING
  double kp , ki, kd;
  double prevKp, prevKi, prevKd;
#endif
double originalSetpoint = 174.29;
double setpoint = originalSetpoint;
double movingAngleOffset = 0.3;
double input, output;
int moveState=0; //0 = denge ; 1 = geri ; 2 = ileri

#if MANUAL_TUNING
  PID pid(&input, &output, &setpoint, 0, 0, 0, DIRECT);
#else
  PID pid(&input, &output, &setpoint, 70, 240, 1.9, DIRECT);
#endif


//MOTOR SURUCU


int ENA = 3;
int IN1 = 4;
int IN2 = 8;
int IN3 = 5;
int IN4 = 7;
int ENB = 6;


LMotorController motorController(ENA, IN1, IN2, ENB, IN3, IN4, 0.6, 1);


//Zamanlama


long time1Hz = 0;
long time5Hz = 0;


volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady()
{
    mpuInterrupt = true;
}


void setup()
{
    // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    // initialize serial communication
    // (115200 chosen because it is required for Teapot Demo output, but it's
    // really up to you depending on your project)
    Serial.begin(115200);
    while (!Serial); // wait for Leonardo enumeration, others continue immediately

    // initialize device
    Serial.println(F("I2C Kuruluyor..."));
    mpu.initialize();

    // verify connection
    Serial.println(F("Suruculer test ediliyor..."));
    Serial.println(mpu.testConnection() ? F("MPU6050 baglanti basarili") : F("MPU6050 baglanti basarisiz"));

    // load and configure the DMP
    Serial.println(F("DMP kuruluyor..."));
    devStatus = mpu.dmpInitialize();

    // supply your own gyro offsets here, scaled for min sensitivity
    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

    // make sure it worked (returns 0 if so)
    if (devStatus == 0)
    {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);

        // enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();

        // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;

        // get expected DMP packet size for later comparison
        packetSize = mpu.dmpGetFIFOPacketSize();
        
        //setup PID
        
        pid.SetMode(AUTOMATIC);
        pid.SetSampleTime(10);
        pid.SetOutputLimits(-255, 255);  
    }
    else
    {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }
}


void loop()
{
    // if programming failed, don't try to do anything
    if (!dmpReady) return;

    // wait for MPU interrupt or extra packet(s) available
    while (!mpuInterrupt && fifoCount < packetSize) { //no mpu data - performing PID calculations and output to motors pid.Compute(); motorController.move(output, MIN_ABS_SPEED); unsigned long currentMillis = millis(); if (currentMillis - time1Hz >= 1000)
        {
            loopAt1Hz();
            time1Hz = currentMillis;
        }
        
        if (currentMillis - time5Hz >= 5000)
        {
            loopAt5Hz();
            time5Hz = currentMillis;
        }
    }

    // reset interrupt flag and get INT_STATUS byte
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count
    fifoCount = mpu.getFIFOCount();

    // check for overflow (this should never happen unless our code is too inefficient)
    if ((mpuIntStatus & 0x10) || fifoCount == 1024)
    {
        // reset so we can continue cleanly
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!"));

    // otherwise, check for DMP data ready interrupt (this should happen frequently)
    }
    else if (mpuIntStatus & 0x02)
    {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); // read a packet from FIFO mpu.getFIFOBytes(fifoBuffer, packetSize); // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;

        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        #if LOG_INPUT
            Serial.print("ypr\t");
            Serial.print(ypr[0] * 180/M_PI);
            Serial.print("\t");
            Serial.print(ypr[1] * 180/M_PI);
            Serial.print("\t");
            Serial.println(ypr[2] * 180/M_PI);
        #endif
        input = ypr[1] * 180/M_PI + 180;
   }
}


void loopAt1Hz()
{
#if MANUAL_TUNING
    setPIDTuningValues();
#endif
}


void loopAt5Hz()
{
    #if MOVE_BACK_FORTH
        moveBackForth();
    #endif
}


//move back and forth


void moveBackForth()
{
    moveState++;
    if (moveState > 2) moveState = 0;
    
    if (moveState == 0)
      setpoint = originalSetpoint;
    else if (moveState == 1)
      setpoint = originalSetpoint - movingAngleOffset;
    else
      setpoint = originalSetpoint + movingAngleOffset;
}


//PID Tuning (3 potentiometers)

#if MANUAL_TUNING
void setPIDTuningValues()
{
    readPIDTuningValues();
    
    if (kp != prevKp || ki != prevKi || kd != prevKd)
    {
#if LOG_PID_CONSTANTS
        Serial.print(kp);Serial.print(", ");Serial.print(ki);Serial.print(", ");Serial.println(kd);
#endif

        pid.SetTunings(kp, ki, kd);
        prevKp = kp; prevKi = ki; prevKd = kd;
    }
}


void readPIDTuningValues()
{
    int potKp = analogRead(A0);
    int potKi = analogRead(A1);
    int potKd = analogRead(A2);
        
    kp = map(potKp, 0, 1023, 0, 25000) / 100.0; //0 - 250
    ki = map(potKi, 0, 1023, 0, 100000) / 100.0; //0 - 1000
    kd = map(potKd, 0, 1023, 0, 500) / 100.0; //0 - 5
}
#endif
SİZCE NASIL OLMUŞ?
Beğendim
66%
İlginç
15%
Eh İşte
10%
Anlamadım
8%
Kötü
0%
Berbat
3%
YAZAR HAKKINDA
Murat Duran
Murat Duran
Açık kaynak donanım ve yazılım geliştiricisiyim , mekanik ve robotik sistemler üzerinde çalışmalar yapmaktayım.Ayrıca bir start-up firması olan Proje Hocam 'ın kurucuyum.
90 YORUMLAR
1 2
  • Cansu Er
    25 Ekim 2015 at 19:38

    Çok güzel olmuş elinize sağlık,bir şey sorucam acaba bu mpu6050 yerine adxl345 kullansak olurmu.

  • Hüseyin AKAR
    26 Ekim 2015 at 16:47

    Hocam motor rpmlerini, lipo bataryanın voltajını ve robotu nasıl kumanda edebileceğimizi paylaşabilir misin ?

  • Gokhan
    5 Kasım 2015 at 19:39

    Hocam benim projemde robot ilk konumuna geri gelecek oneriniz varmi

  • 8 Kasım 2015 at 22:24

    merhaba. hayirli islerdilerim size. bu kodu . kutuphaneden degerleyince. kod ismi. ne oluyor. tesekkurler,
    allaha emanet olun.

  • mehmet
    6 Ocak 2016 at 15:08

    hocam bu proje denendi değil mi?

  • Ramazan Akdağ
    17 Ocak 2016 at 21:04

    Hocam kodları compile ederken currentMillis satırında hata var yardımcı olabilir misim?

  • GökhN
    20 Ocak 2016 at 14:01

    Hocam diğer android kontrollü robotu çalıştıramadık.Bu robota bluetoth yazılımını eklemeye uğraştım amaolmadı..ben bu programda denge robotunu çalıştırdım..üzerine bluetooth nasıl ekleriz yardımcı olurmusunuz

  • gürkan uygun
    21 Ocak 2016 at 18:24

    elinize saglık gayet başarılı motor seti ve tekerlekleri nereden temin ettiniz?

  • gürkan uygun
    23 Ocak 2016 at 03:28

    Bir de kodda sıkıntı mı var acaba derlemede hata veriyor. Ekran görüntüsü aşağıdaki linkte paylaştım… Sorun ne olabilir?
    http://imagizer.imageshack.us/a/img910/5878/ylQfMx.jpg

  • chuck bartowski
    25 Ocak 2016 at 23:12

    Hocam aynı currentmillsdeki hatayı bende alıyorum kütühaneler tam oldugunu sanıyorum
    yardımcı olabilirmsiniz

    • Murat Duran
      26 Ocak 2016 at 08:23

      Kodların üstündeki linkten kendini dengeleyen robot kütüphanelerini indirip eklemeniz lazım.Birde eski sürüm bir arduino programında deneyiniz. Arduino 1.0.5 sürümü tavsiye edilir.

  • Mustafa
    27 Ocak 2016 at 20:40

    robotu telefon ya da kumanda ile kontrol ediliyormu? yoksa sadece dengelmek mi amacı?

  • Eren
    25 Şubat 2016 at 19:47

    potansiyemetreyi Nasıl konumlandırılacağını pek anlamadım.bağlantı şemasını gönderebilirsiniz.

  • Eren
    1 Mart 2016 at 19:16

    Robotu yaptım dengede duruyor. Ancak bazen tekerler bir anda kilitleniyor ya da tek bir yöne doğru kesintisiz hareket ediyor. Ne yapmamı önerirsiniz?

  • Murat İMGA
    3 Mart 2016 at 10:50

    Merhaba;
    Denge robotum çok güzel çalıştı. Paylaşımlarınız için çok teşekkür ederim.

    kodlarda manual tunning ve automatic tunning terimlerinden bahsediliyor. potaniyometreleri manual tunning amacıyla mı bağlıyoruz.

    Seri monitörde “”DMP ready! Waiting for first interrupt…”” satırında bekliyor ve Kp, Ki, değerlerini göremiyorum. buna rağman denge robotu gayet güzel çalışıyor.

  • Murat Yaman
    12 Nisan 2016 at 11:10

    Merhaba hocam,
    Projenin bağlantı şemasını batarya dahil paylaşabilir misiniz?

  • serdar
    17 Nisan 2016 at 12:42

    selmalar hocam bende l 298n motor sürücü var onda ın1 ın2 ın3 ın4 girişleri var yukarıda semada sizin motor surucunun ENA VE ENB GİRİŞLERİ VAR bendeki motor surucusunde bu ena ve en b girişlerini nereye bağlayacağım teşekkürler

    • Rsn yyc
      11 Haziran 2016 at 00:24

      ENA PWM ozelligi olan pine baglanir birinci motorun HIZ kontorolu
      IN1 IN 2 IN3 IN4 Arduinonuzda digital pinlere baglayin(onerim pwm olsun.)
      EN B PWM ozellikli pine baglanir ikinci motorun HIZ kontrolu icin kullanilir

  • TÜRKER AKSU
    19 Nisan 2016 at 17:56

    Potların kapasitesi önemli mi 1K-10K YA DA 100K

  • Hasan Kazıcı
    22 Mayıs 2016 at 21:34

    Merhabalar , potansiyometreleri nasıl bağlayacağız ?

  • ahmet uğurlu
    ahmet uğurlu
    10 Ekim 2016 at 16:31

    merhaba hocam potansiyometrelerin bağlantısını daha detaylı anlatmanız mümkün mü acaba

    • Murat Duran
      10 Ekim 2016 at 16:39

      potansiyemetreleri A0 , A1 ve A2 ye bağlayacaksınız.Potansiyemetrenin uzun çubuk size bakacak şekilde tutarsanız soldaki bacak + (VCC) ortadaki bacak sinyal sağdaki bacak -(GND) olarak bağlayacaksınız.

  • 20 Ekim 2016 at 20:42

    merhaba hocam Dagu motor yerine servo motor kullansak olurmu

  • Cemil Karabayır
    21 Ekim 2016 at 14:09

    Potansiyometrelerin değerleri nedir acaba?

  • ahmet uğurlu
    ahmet uğurlu
    27 Ekim 2016 at 18:28

    merhaba hocam ben robtu yaptım çalştı fakat sorun tekerler çok az dönüyo bunun sebebi nedir acaba

  • Mustafa Kaan Fergöğce
    1 Kasım 2016 at 21:30

    Biz herşeyi aldık dediğiniz gibi bağladık ama ardiunoya programı atamıyoruz hata veriyor neden?

  • devran deniz
    13 Kasım 2016 at 09:46

    hocam kütüphane eklemede sorun yaşıyorum yardımcı olabilir misiniz?

  • ahmet uğurlu
    ahmet uğurlu
    5 Aralık 2016 at 20:52

    merhaba hocam ben sizin yaptıklarınızın aynısını yaptım motorun teki sürekli aynı yöne dönüyor diğer motor dönmüyor sebebi ne olabilir acaba

  • duhan duman
    24 Aralık 2016 at 14:27

    kod hata veriyor
    verdiği hata bu “exit status 1
    Error compiling for board Arduino/Genuino Uno.”
    nasıl çözebilirim

  • Fatih BAYRAK
    24 Aralık 2016 at 16:04

    selamün alüküm hocam. ben bu projeyi okulda proje olarak yapmak istiyorum ama bi hata aldım.

    HATA= exit status 1
    Error compiling for board Arduino/Genuino Uno.

    bu hatayı nasıl düzeltebilirim.

  • kamil as
    24 Aralık 2016 at 20:40

    Merhaba hocam anlatılanların hepsini yaptı ama motorları döndüremedim sebebi nedir?

  • İdris Akalın
    12 Ocak 2017 at 18:04

    Hocam öncelikle merhabalar yaklaşık bir aydır bu robotu yapmaya ugrasıyorum mekatronk bölümü okuyorum ve projemi acil bi şekilde teslim etmem gerekiyor istenilen butun malzemeleri aldım ve bağlantılarını yaptım fakat motorlrdan biri ileri yönde bir diğeri ise geri yönde dönme olayı yapıyor ve denge alamıyorum yardımcı olur musunuz.

    • Murat Duran
      12 Ocak 2017 at 18:06

      Motorlardan birinin bağlantısını ters takın

      • İdris Akalın
        12 Ocak 2017 at 22:18

        Tamam hocam son olarak o işlemi gerçekleştireceğim ardından dönüş sağlarım birde lipo pili uygun fiyata satın almak için bir site paylaşırmısınz

  • cemil sarsılmaz
    22 Ocak 2017 at 00:25

    merhaba öncelikle paylaşımınız için çok teşekkür ederiz bu robotu bluethoot veya farklı bir modül ile ileri geri sağa sola nasıl hareket ettirebiliriz lütfen yardımcı oun şimdiden teşekkür ederim.

  • Naci ŞENAY
    2 Şubat 2017 at 20:14

    Merhaba ben bu projeyi android kontrollü yapmak istiyorum onun için hangi motorlardan almalıyım hocam enkoderli alamam çok pahalı enkoderli dışında bu motorda işini görür dediğiniz bi motor varmı ??

  • Ahmet AKIŞIK
    15 Şubat 2017 at 18:42

    Hocam en fazla bir sn dengede durmaya çalışıyor sonra sürekli son gaz dönüyor .FİFO overflow! serial monitorden yazısı geliyor ne yapmam lazım

  • Fırat KARA
    22 Şubat 2017 at 16:43

    Hocam merhaba. Ahmet AKIŞIK arkadaşımızın ki gibi be de FIFO overflow! hatası alıyorum. Aynı şekilde ilk 3 saniye bir sorun olmuyor ama daha sonra kontrolü kaybediyor. Ne yapmamızı önerirsiniz?

  • 23 Şubat 2017 at 02:06

    hocam aynı kodları kullanarak ve aynı malzemeleri kullanarak sadece potansıyometreleri kullanmasam devre çalışırmı ?
    ve ayrıca biz bu devrede potansiyometreleri ne için kullanıyoruz yanı kd kp ve ki ne işe yarıyor ?

    ilk sorum benim için çok önemli hocam ..

  • Emir
    6 Mart 2017 at 00:55

    Ben de aynısını yaptım hepsini doğru taktığımdan eminim fakat çalışmadı sorun potansiyometredeki ayarlardan olabilir mi ?

YORUM YAP