Dengede Duran Çubuk (PID Uygulaması)
Amaç
Motorun ucuna bağlanmış olan çubuğu sürekli aynı açıda
tutmak ve açısı değiştirildiğinde en hızlı şekilde istenilen konuma gelmesini
sağlamak.
Kullanılan Malzemeler
Arduino Nano
Micro Servo
SG90
MPU6050
(Gyroscope)
Buton
Direnç (1k)
Yapılışı
İlk resimdeki göründüğü gibi servo motorun ucuna çubuğu
sabitliyoruz. Ardından çubuğun uç kısmına gyroscopeyi sabitliyoruz. Aşağıdaki
şemaya göre devre bağlantılarını gerçekleştiriyoruz. Sonrasında Arduino’ya
aşağıdaki kodları yüklüyoruz. Son olarak sisteminiz için en ideal kazanç
oranlarını deneyerek bulmaya çalışıyorsunuz.Benim yaptığıma göre p=1.2 i=0.01
d=0 olacak şekilde ayarladığımda ideal kazanç oranlarını buldum.
Kodlar
// UYARI: I2CDev, MPU6050, PID_v1 ve Servo kütüphaneleri
Arduino IDE’nize dahil olmalı.
#include "I2Cdev.h"
#include "MPU6050.h"
#include <PID_v1.h>
#include <Servo.h>
#define OUTPUT_READABLE_ACCELGYRO
#define LED_PIN 13
int16_t ax, ay, az;
int16_t gx, gy, gz;
int16_t hax, hay, haz;
double input, output, pk, arch, pos;
bool blinkState = false;
MPU6050 accelgyro;
Servo myservo;
PID myPID(&input, &output, &arch, 1.2, 0.01,
0.0, DIRECT);
void setup() {
#if I2CDEV_IMPLEMENTATION
== I2CDEV_ARDUINO_WIRE
Wire.begin();
#elif
I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
myPID.SetMode(AUTOMATIC);
accelgyro.initialize();
myservo.attach(3);
pinMode (6, INPUT);
pinMode(LED_PIN,
OUTPUT);
}
void loop() {
if (digitalRead(6))
{
while
(digitalRead(6));
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy,
&gz);
hax = ax;
hay = ay;
haz = az;
} else {
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy,
&gz);
}
if (hay > az) {
input = (double)
(ay - hay) / 1000;
} else {
input = (double)
(hay - ay) / 1000;
}
myPID.Compute();
if (hay > ay) {
pos += output;
} else {
pos -= output;
}
if (pos < 0)
pos = 0;
if (pos > 180)
pos = 180;
myservo.write((int)
pos);
blinkState =
!blinkState;
digitalWrite(LED_PIN, blinkState);
delay (50);
}
0 yorum :
Yorum Gönder