Arduino otomatik drift aracı

J
E2'yi High yapmayı ve pin değiştirmeyi denedim. Ne yazık ki durum aynı.
Bu arada in3 ve in4 ve e2'yi define ile yazdığımda " = işaretinden önce açıklama beklenir" gibi bir uyarı geldi.

#define in3 = 2; . Yazmıştım.

Define ile servo pini tanımlama da sorun çıkmadı.
Benim dediğim şeyleri denediniz mi?
Servo kütüphanesi iptal edip pwm ile sürmeyi deneyin veya motor sürücü Analog çıkışa bağlamayı deneyin
 
  • Beğen
Tepkiler: FERDİ İKİZ
J

Benim dediğim şeyleri denediniz mi?
Servo kütüphanesi iptal edip pwm ile sürmeyi deneyin veya motor sürücü Analog çıkışa bağlamayı deneyin
Analog çıkış eğer dijital giriş/çıkışlardan pwm olmayanlar ise evet denedim. Servo kütüphanesini silince servoyu nasıl yönetebilirim, burayı biraz açar mısınız? Çünkü servonun 0 ile 180 derecenin dışına çıkması zorlanma yada dişli sıyrılmasına neden olabilir.
 
Önce #define konusunu ele alalım.
Kullanımı şu şekilde:

#define servoPin 9

Satır sonunda noktalı virgül yok.
Aslında kodla da bir alakası yok bu ifadenin. Sadece derleyiciye diyor ki "servoPin" yazısını gördüğün her yere "9" koy. Belki böyle basit bir kodda sorun değil ama işlemci sınırlarını zorlayacak bir kodda gereksiz değişken tanımlamak istemezsin.
 
Kodunu incelediğimde motor hareketini kontrol için in3, in4 ve e2 pinlerini kullandığını düşünüyorum. Anladığım kadarıyla in3 ve in4 yönü, e2 ise PWM ile motor hızını belirliyor.
Kod yazmanın en önemli aşaması "troubleshooting"'dir. Eğer bunu sistematik bir şekilde yapmazsan işin içinden çıkamayabilirsin. Şimdi, ilk mesajda yazdığına göre servo hareketleri istediğin şekilde oluyor ama motorun çalışmıyor.
O halde en baştaki şu satırları başlarına "//" koyarak iptal et.
#include <Servo.h>
Servo servo;

Sonra şu satırı iptal et:
servo.attach(9);

Ana loop içindeki tüm servo komutlarının başına "//" koyarak iptal et.
Kodu bu şekilde test et. Bakalım motor istenilen şekilde çalışıyor mu.
Sonra sonucu buraya yaz.

Bak test edeceğin kodu yazıyorum:
//#include <Servo.h> //Servo servo; #define servoPin 9 #define in3 6 #define in4 7 #define e2 10 void setup() { //servo.attach(9); pinMode(in3,OUTPUT); pinMode(in4,OUTPUT); //MEKANİK İÇİN TEST HAREKETLERİ /* servo.write(0); delay(1000); servo.write(180); delay(1000); servo.write(90); */ analogWrite(e2, 60); //FORWARD: in3, low and in4, high digitalWrite(in3, LOW); digitalWrite(in4, HIGH); delay(1000); analogWrite(e2, 60); digitalWrite(in3, HIGH); digitalWrite(in4, LOW); delay(1000); //MEKANİK İÇİN TEST HAREKETLERİ BİTTİ } void loop() { //FİGÜR 1 KODLAR(SIFIR ÇİZME) //servo.write(0); //delay(15); analogWrite(e2,60); //Forward in3,LOW in4,HIGH digitalWrite(in3, LOW); digitalWrite(in4, HIGH); delay(3000); //servo.write(180); delay(500); //servo.write(90); delay(15); analogWrite(e2,60); digitalWrite(in3, LOW); digitalWrite(in4, LOW); delay(10); }
 
Analog çıkış eğer dijital giriş/çıkışlardan pwm olmayanlar ise evet denedim. Servo kütüphanesini silince servoyu nasıl yönetebilirim, burayı biraz açar mısınız? Çünkü servonun 0 ile 180 derecenin dışına çıkması zorlanma yada dişli sıyrılmasına neden olabilir.
Servo yönetmenin çok sayıda yolu var ve hemen tümü o kullandığın Servo kütüphanesinden iyidir.
Servolar çalışabilmek için her 20 milisaniyede bir 1 ile 2 milisaniye arasında darbe beklerler. Bunu sağlarsan servoyu istediğin konuma getirebilirsin.
Bunu interruptlar ve timerlar ile yapmak en doğrusudur. Servo kütüphanesi de bunu yapıyor zaten. Ama bu kadar basit bir kodda hiç gerekli değil.
Servo pinine high yazılır. En basitinden delayMicroseconds() komutu ile darbe genişliği mikrosaniye olarak verilir ve servo pinine LOW yazılarak pulse oluşturulur. Burada seni zorlayacak şey bu döngünün 20 milisaniyede bir tekrarlanmasıdır. Onu da bir timer interrupt kullanarak halletmek mümkün. Ancak servoyu nasıl kontrol edeceğini sorduğuna göre interrupt ve timer sana biraz fazla gelebilir. O zaman farklı bir yol izleyebilirsin.
Kullandığın tüm delay() komutlarının yerine başka bir komut dizisi yazabilirsin.
Örneğin...
delay(1000) yerine...
1000 / 20 = 50 olduğuna göre

for(int n = 0; n < 50; n++)
{
digitalWrite(servoPin, HIGH);
delayMicroseconds(servoValue); // servoValue 1000 ile 2000 arasında olacak. Dereceden hesaplatabilirsin. 0 derece 1000, 180 derece 2000.
digitalWrite(servoPin, LOW);
unsigned long timer = millis() //Burada bir zamanlayıcı ayarlıyoruz
while((millis() - timer) < 20); // Yaklaşık 20 milisaniye bekliyoruz. Bu süre çok kritik değil.
}

Servo çalışması için gerekli pulse için genişlik çok önemli ama iki pulse arasındaki süre çok da kritik değil. Hele digital servo kullanırsan hiç kritik değil.
 
Özet olarak sistem şu an çalışıyor.:) Motor hızını sesten dolayı sınırladım, şu an drift ile alakasız hareketler yapıyor. Gürültü yapabileceğim gündüz saatlerinde figürleri test edeceğim.:saygilar:

Çözüme ulaşana kadar;

1. Pinler değiştirildi

2. Motor enable değeri farklı değerlerle denendi

3. Define ile pin tanıtmanın hem daha kolay hem de daha şık olduğu öğrenildi. (Teşekkürler Sümer abi:))

4. Servo komutlarını yoruma çevirince motorun çalıştığı gözlendi. Kodların bu haliyle bir iki defa motorun kesintili döndüğünü gözledim. Bunun sebebi deneme aşamasında nispeten gevşek kablolama olabilir. Ayrıca bir defa olarak motorun tanımladığımdan yüksek bir hızda döndüğünü gözledim. Bu Arduino'ya enerji veren soketi yerleştirme sırasında olduğu için bir iletim sorunu olabilir.

5. Servo komutları normale döndürüldü ve motor hız değeri (e2,70) olarak değiştirildi. 60 değerinde yerinden zor kımıldıyordu. Programın bu haliyle herşey çalışıyor.

Arduino harika birşeymiş :)

Fikir verdiğiniz için, yönlendirdiğiniz için özellikle de kodlama konusunda çok teşekkür ediyorum.
Uygulama artık figürler üzerinde çalışacak noktaya geldi. Yeni görsellerle hatta videolarla konuyu biraz şenlendirmeyi düşünebilirim şimdi:RCKolik:


Kıyas yapmak açışından çalışan kodlar:

#include <Servo.h>
Servo servo;

#define servoPin 9
#define in3 2
#define in4 4
#define e2 11
void setup() {
servo.attach(9);
pinMode(in3,OUTPUT);
pinMode(in4,OUTPUT);

//MEKANİK İÇİN TEST HAREKETLERİ

servo.write(0);
delay(1000);
servo.write(180);
delay(1000);
servo.write(90);

analogWrite(e2, 70);
//FORWARD: in3, low and mPin_in4, high
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
delay(1000);
analogWrite(e2, 70);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
delay(1000);
//MEKANİK İÇİN TEST HAREKETLERİ BİTTİ
}


void loop() {

//FİGÜR 1 KODLAR(SIFIR ÇİZME)
servo.write(0);
delay(15);
analogWrite(e2,70);
//Forward in3,LOW in4,HIGH
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
delay(3000);
servo.write(180);
delay(500);
servo.write(90);
delay(15);
analogWrite(e2,70);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
delay(10);
}
 
  • Beğen
Tepkiler: Mehmet Kucuksari
Kodları birkaç sefer incelememe rağmen pin değişimi dışında bir fark göremedim. Pin değişimin tek başına denediğimde de sorun çözülmemişti. Kodlar çalışıyor ama arızayı çözen farkı bulamadım. "Sorun giderme" de kod parçalarını yoruma çevirip denemek bir metot mu? Arduino yüksek seviyeli olduğu için mi böyle şeyler oluyor?
 
Kodları birkaç sefer incelememe rağmen pin değişimi dışında bir fark göremedim. Pin değişimin tek başına denediğimde de sorun çözülmemişti. Kodlar çalışıyor ama arızayı çözen farkı bulamadım. "Sorun giderme" de kod parçalarını yoruma çevirip denemek bir metot mu? Arduino yüksek seviyeli olduğu için mi böyle şeyler oluyor?
Hocam şunu anlamadım şuan hem servo hem motor aynı anda çalışıyor mu yoksa sadece servo iptal olduğundamı motor çalışıyor.
Benim önerim şu hiç servo kütüphanesi kullanmadan servoyu sürme.
Servolar pwm sinyali ile çalışır. Arduino uno da 3-5-6-9-10-11 numaralı dijital Giriş/Çıkış pinlerinden pwm çıkışı almak mümkündür pwm sinyali almak için temel olarak analogWrite() fonksiyonu kullanılıyor.
aşağıya bir örnek kod ekliyorum koddaki 125 değerini değiştirerek açıyı değiştirebilirsin
tahminimce servo kütüphanesi bunu yapmayı sağlıyor.

Kod:
void setup() {

  pinMode(9,OUTPUT);

}

 

void loop() {

  analogWrite(9, 125);

}
 
  • Beğen
Tepkiler: FERDİ İKİZ
Hocam şunu anlamadım şuan hem servo hem motor aynı anda çalışıyor mu yoksa sadece servo iptal olduğundamı motor çalışıyor.
Benim önerim şu hiç servo kütüphanesi kullanmadan servoyu sürme.
Servolar pwm sinyali ile çalışır. Arduino uno da 3-5-6-9-10-11 numaralı dijital Giriş/Çıkış pinlerinden pwm çıkışı almak mümkündür pwm sinyali almak için temel olarak analogWrite() fonksiyonu kullanılıyor.
aşağıya bir örnek kod ekliyorum koddaki 125 değerini değiştirerek açıyı değiştirebilirsin
tahminimce servo kütüphanesi bunu yapmayı sağlıyor.

Kod:
void setup() {

  pinMode(9,OUTPUT);

}



void loop() {

  analogWrite(9, 125);

}
İkisi beraber çalışıyor. Aynı zamanda çalışma olarak değerlendiremeyiz sanırım. Çünkü arada delay var.

Bu bahsettiğiniz metotu deneyeceğim mutlaka. Motor kontrolüne benziyor ve daha anlaşılır duruyor.
 
Hocam şunu anlamadım şuan hem servo hem motor aynı anda çalışıyor mu yoksa sadece servo iptal olduğundamı motor çalışıyor.
Benim önerim şu hiç servo kütüphanesi kullanmadan servoyu sürme.
Servolar pwm sinyali ile çalışır. Arduino uno da 3-5-6-9-10-11 numaralı dijital Giriş/Çıkış pinlerinden pwm çıkışı almak mümkündür pwm sinyali almak için temel olarak analogWrite() fonksiyonu kullanılıyor.
aşağıya bir örnek kod ekliyorum koddaki 125 değerini değiştirerek açıyı değiştirebilirsin
tahminimce servo kütüphanesi bunu yapmayı sağlıyor.

Kod:
void setup() {

  pinMode(9,OUTPUT);

}



void loop() {

  analogWrite(9, 125);

}
Ne yazık ki o iş öyle yürümüyor. Her ne kadar adı "PWM" olsa da ikisi farklı şeyler.
Servo sinyali üretmek için analogWrite() işlevi kullanılmaz.

PWM yani pulse width modulation, kare dalganın ON olduğu sürenin total periyoda oranı (duty cycle) değiştirilmesi ile aktarılan gücün modülasyonuna dayanır. Bir motoru bu şekilde sürerek istediğimiz hızda dönmesini sağlayabiliriz, bir LED'in parlaklığını değiştirebiliriz.
Bir servo ise duty cycle ile kumanda edilmez. HIGH darbenin süresi ile kumanda edilir. Yani farklı bir PWM mantığı ile çalışır. Doğrudur, Arduino ile PWM kullanılarak servo kontrol edilebilir ama analogWrite() ile değil. Bunun için datasheet'i güzelce inceleyip Timer1'in derinliklerine inilmesi, uygun prescaler ayarlanıp istenilen darbe süresinin, kullanılacak pine göre OCR1A ve OCR1B registerleri aracılığı ile ayarlanması gerekir.

Arduino için küçük bir not. Eğer analogWrite() kullanacaksanız ilgili pini OUTPUT olarak deklare etmeniz gerekmez.
 
Son düzenleme:
  • Beğen
Tepkiler: Mehmet Kucuksari
Kodları birkaç sefer incelememe rağmen pin değişimi dışında bir fark göremedim. Pin değişimin tek başına denediğimde de sorun çözülmemişti. Kodlar çalışıyor ama arızayı çözen farkı bulamadım. "Sorun giderme" de kod parçalarını yoruma çevirip denemek bir metot mu? Arduino yüksek seviyeli olduğu için mi böyle şeyler oluyor?
Daha önce de açıkladım. Servo kütüphanesinin Timer1 ve bazı interruptları ele geçirmesi nedeniyle kodun çalışmıyor. Servo kütüphanesi ile ilgili satırları "comment out" ettiğinde motorun çalışıyor.
 
  • Beğen
Tepkiler: FERDİ İKİZ
Sıfır çizme figürünü bugün test ettim. Tekerleklerin yol tutuşu biraz fazla. Buna birşeyler düşünebilirim.

Bu VIDEOYU görmek için izniniz yok. Giriş yap veya üye ol
 
  • Sevdim
Tepkiler: Mehmet Kucuksari
Motor servo Sorununu nasıl çözdünüz
Üstte yazmıştım ama oraya biraz karışık yazmışım. İlk olarak pin değiştim. Ardından servo komutlarını yoruma çevirip motoru test ettim. Çalıştı. Servo komutlarını normale çevirdim, istediğim hareketleri yapmaya başladı.

Umarım sorunuzu yanıtlamışımdır.