Ardunio ve NRF24, Joystick ile servo motor kontrolü

Katılım
30 Mart 2023
Mesajlar
11
Merhaba arkadaşlar, ardunio ve nrf24 modül kullanarak kumanda yapmak istiyorum. Amacım uzaktan motor kontrol etmek fakat devreyi kurduğumda joystick ile oynamadığım halde servo ufak hareketler yapıyor. Joystick ile ileri geri yaptığımda ise yaklaşık 3-5 saniye sonra servo hareket ediyor. Bunun sebebi nedir acaba ? .zip dosyası içerisinde kodlar, devre şeması ve video mevcuttur.
 

Ekler

  • joystickServoKontrol.zip
    11.8 MB · Görüntüleme: 74
@oalikorkmaz foruma hoşgeldin.

Projeni zip olarak değil de aşağıdaki gibi paylaşırsan yorum yapmak isteyenler için çok daha kolay olur. Bu şekilde insanlar zip dosyasını bilgisayarına indirmek istemeyebilir, dolayısıyla yardım etmez.

Devre şeması:

1680223205536.png


Eğlence Çubuğu Kontrol Alıcısı:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>
Servo servo;
#define CE_PIN 9
#define CSN_PIN 10
#define led 4
const uint64_t pipe = 0xE8E8F0F0E1LL;
RF24 radio(CE_PIN, CSN_PIN);
int joystickData[3];
void setup()
{
  pinMode(4, OUTPUT);
  radio.begin();
  radio.openReadingPipe(1, pipe);
  radio.startListening();
  servo.attach(6);
  Serial.begin(9600);
}

void loop()
{

  if (radio.available())
  {
    radio.read(joystickData, sizeof(joystickData));

    int xpos = joystickData[1];
    int button = joystickData[2];
    int xpos1 = map(xpos, 0, 1023, 0, 180);
    bool done = false;
    while (!done)
    {
      done = radio.read(joystickData, 1);
      servo.write(xpos1);
      delay(10);
    }
    if (button == 0)
    { // led
      digitalWrite(4, HIGH);
    }
    else
    {
      digitalWrite(4, LOW);
    }
  }
}


Eğlence Çubuğu Kontrol Vericisi:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

// Pins....
#define CE_PIN 9
#define CSN_PIN 10
#define JOYSTICKX A0
#define JOYSTICKY A1
#define BUTTON 8

const uint64_t pipe = 0xE8E8F0F0E1LL;
RF24 radio(CE_PIN, CSN_PIN);
int joystick[3];

void setup()
{
  radio.begin();
  radio.openWritingPipe(pipe);
  pinMode(BUTTON, INPUT);
}

void loop()
{
  joystick[0] = analogRead(JOYSTICKX);
  joystick[1] = analogRead(JOYSTICKY);
  joystick[2] = digitalRead(BUTTON);
  radio.write(joystick, sizeof(joystick));
}

 

Ekler

  • joystickIleServoKontrol.pdf
    1.1 MB · Görüntüleme: 70
@Sercan hoşbuldum.

Haklısınız, bir kaç yer kurcaladım ama bulamadım bende zip atayım dedim. Bir dahaki konumda örnekteki gibi yapacağım. Yardımcı olup uğraştığınız için teşekkür ederim.
 
Benim yorumuma gelecek olursak; Kodlarını ya da projeni incelemedim çünkü ben olaya yaklaşımını değiştirmen gerektiğini düşünüyorum.

Tavsiyem öncelikle servoyu Arduino ile doğrudan çalıştırıp, seri terminalden verdiğin komutlara doğru cevaplar verdiğini gözlemlemelisin.

İkinci adım ise diğer Arduino'nun joystick modülünden gelen komutları doğru işlediğinden, yine seri terminal ile kontrol ederek emin olman gerekiyor.

Buraya kadar proje doğru ilerlediyse, NRF24 ile haberleştirdiğinde projenin bahsettiğin bölümü tamamlanmış olacak.

Bu adımları izlersen sorduğun sorularda daha net bilgi ve tecrübeye dayalı olacaktır. Şu an servonun neden çalışmadığı ile ilgili bir sürü senaryo var. Ayrıca sana da müthiş katkısı olur.

Bir bütünde sorun aramak her zaman çok zahmetlidir.
 
Bir, iki yorum da ben ekleyeyim.

Joystick durumunu sürekli göndererek radyo iletişimini boğmayın. Sadece değerler (X,Y ve buton) değiştiğinde yollayın. Bunun için gönderici kodunda bu üç değeri değişkenlerde saklayacaksınız ve sadece herhangi birinde değişiklik olursa üçünü birden göndereceksiniz.

Diğer bir konu ise şu. Bu joysticklerden daha önce kullandım. Çok mekanik yaylı bir şey. Stabil bir şekilde voltajı tutması zor.
Diğer bir problem de kablolama ve ADC gürültüsü. Bunların etkisiyle siz joysticke dokunmasanızda X ve Y eksenlerindeki değer sürekli küçük aralıklarla gezinecektir. Gereksiz yere hareket komutu göndermeye devam edecektir. Bunu özmek için de X ve Y eksenlerinin değeri belli bir miktar değişmeden göndermeyin. Böylece gürültüyü büyük çlçüde filtrelemiş olursunuz.
 
Merhaba, dediklerinizi uyguladım ve adım adım ilerledim. Öncelikle buton ile vericiden alıcıya veri gönderdim ve serial ekranda bunu gözlemledim. 0 veya 1 gönderdiğimde alabiliyorum. Daha sonra potansiyometre ile denedim ve potansiyometrenin değerlerini de gözlemledim. Son olarak joystick değerlerini gözlemlemek istediğimde ise veriler Şekil-1'deki gibi bir veya iki kez geliyor ve duruyor daha fazla haberleşme yapmıyor. Tahminimce alıcı kodumda sorun var.


joystickAlınanVeri.png

Şekil-1

Verici Kod:
#include <RF24.h>
#include <RF24_config.h>
#include <nRF24L01.h>
#include<SPI.h>

RF24 verici(9,10);
const uint64_t kod = 0xE8E8F0F0E1LL;
const byte joystickX = A0;
const byte joystickY = A1;


int joystick[3];
int buton = 2;



void setup() {
  Serial.begin(9600);
  verici.begin();
  verici.openWritingPipe(kod);
  verici.stopListening();
  pinMode(buton, INPUT);

}

void loop() {
 
  joystick[0] = analogRead(joystickX);
  joystick[1] = analogRead(joystickY);
  joystick[2] = digitalRead(buton);

  delay(50);
  Serial.print("X: ");
  Serial.println(joystick[0]);
  Serial.print("Y: ");
  Serial.println(joystick[1]);
  Serial.print("Buton: ");
  Serial.println(joystick[2]);
  delay(50);
  verici.write(&joystick, sizeof(joystick));

}

Alıcı Kod:
#include <RF24.h>
#include <RF24_config.h>
#include <nRF24L01.h>
#include <SPI.h>
#include <Servo.h>

RF24 alici(9,10);
const uint64_t kod = 0xE8E8F0F0E1LL;

int joystickData[3];
Servo servo;



void setup() {
  Serial.begin(9600);
  alici.begin();
  alici.openReadingPipe(1, kod);
  alici.startListening();
  servo.attach(3);
}

void loop() {
  if(alici.available()){

    alici.read(&joystickData, sizeof(joystickData));

    int xpos = joystickData[0];
    int ypos = joystickData[1];
    int buton = joystickData[2];

      delay(50);

      Serial.print("X: ");
      Serial.println(xpos);

      Serial.print("Y: ");
      Serial.println(ypos);

      Serial.print("Buton: ");
      Serial.println(buton);

      delay(50);

  }

}
 
Aşağıdaki örnek kod ile Joystick'i hareket ettirdiğinde seri terminalde aşağıdaki gibi çıktı alabiliyor musun? Bu çıktı hızlı ve sürekli olmalı.

Joystick Test:
#define VRX A0
#define VRY A1

int xDegeri = 0;
int yDegeri = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  xDegeri = analogRead(VRX);
  yDegeri = analogRead(VRY);

  Serial.print("x = ");
  Serial.print(xDegeri);
  Serial.print(", y = ");
  Serial.println(yDegeri);
  delay(50);
}

1680482625272.png
 
Ben yukarıdaki testi aşağıdaki gibi basit bir düzenek ile test ettim.

5V - 5V
A0 - VRX
A1 - VRY
GND - GND

20230403_034107.jpg
 
Adım adım gidelim.

@Sercan 'ın önerdiği gibi sadece verici kartınızı çalıştırıp bilgisayarınıza bağlayın ve 10-15 saniyelik SerialMonitor çıktısını paylaşın.
 
joystick'e dokunmadığım da aldığım değer x için 433 y için 450 sürekli alıyorum ve oynattığımda değerler değişiyor.

not: verici kartım ile yaptım

1680516597008.png
 
Nano'nun 10 bit ADC'si var. Tam 0 ya da tepe noktasını okuyamıyorsun.

Normalde 0 ila 1023 arasında değer görmen lazım. Senin değerlere göre en çok (850) 4.1V iletim var gibi.

Bekleme konumunda ise 512 civarında değerler olmalı. Bence 490 - 532 (2.4V - 2.6V) aralığı ölü bölge kabul edilebilir. Senin şu an bir eksen 433 (2.1V) diğer eksen 450 (2.2V) gibi duruyor.

5V'u ölçtün mü? Bir şeyler tuhaf duruyor.
 
Araştırmama göre dizüstü bilgisayarların usb çıkışları dengesiz oluyor. Güç kaynağı bağladığım zaman bir problem yok joystickten 0 ila 1023 arası veri alabiliyorum. İşte aşağıdaki gibi
not: deneylerimi güç kaynağı bağlayarak test ediyorum. Pcden sadece veri okuyorum.

1680532445517.png
 
O zaman bütün testlerde güç kaynağı bağlamalısın. Diğer türlü güç tüketimi arttıkça seni yanıltacak bir sürü senaryo var.

Joystick testini yaptığında kararlı çalıştığını görüyorsan motor testine geçmelisin.
 
Ben bu testi aşağıdaki kod ile yaptım. Alıcı tarafında herhangi bir bağlantı değiştirmene gerek yok. 6 numaralı dijital port ile verdiğin komuta göre pozisyonu ayarlaması gerekiyor.

Seri terminal ile servo testi:
#include <Servo.h>
Servo servo;
int konum = 0;
void setup() {
  Serial.begin(9600);
  servo.attach(6);
  Serial.println("Servo test ediliyor.");
  for (konum = 0; konum <= 180; konum += 1)
    servo.write(0);
  delay(500);
  servo.write(180);
  delay(500);
  servo.write(90);
  delay(500);
  Serial.println("servo testi bitti.");
  Serial.println("0 ile 180° arasında bir değer giriniz.");
}
void loop() {
  if (Serial.available()) {
    int emir = Serial.parseInt();
    if (emir < 0 || emir > 180) {
      Serial.print(">");
      Serial.println(emir);
      Serial.println("Dikkat! 0 ile 180° aralığında değer girmelisiniz.");
      Serial.read();
    }
    if (emir >= 0 && emir <= 180) {
      Serial.print(">");
      Serial.println(emir);
      Serial.print("Açı ");
      Serial.print(emir);
      Serial.println("° ayarlandı.");
      servo.write(emir);
      Serial.read();
    }
  }
}
 
Yukarıdaki kod ile aynı testi yaptığımda aşağıdaki gibi gayet kararlı çalışıyor.

 
Arduino'larda ADC referans voltajı giriş voltajından sağlanıyor. O dengesiz beslemede yüzden bu tür sapmalar normal.

Verici kodu dalgalanma konusu dışında normal çalışıyor gibi görünüyor.
Simdi acaba alıcı kodunuzdaki delay() satırlarını yorumlayıp alıcı ve verici kodlarınızı beraber çalıştırır mısınız?
Ancak bu sefer bilgisayarınıza alıcı kart bağlı olsun. Servoyu şimdilik bağlamayın. Ve yine Serial Monitor görüntüsünü paylaşın.
 
Kablosuz olarak joystick verilerini iletebiliyorum artık servo bağlı değilken veri akışı kesilmiyor ancak servoyu bağladığımda işler değişiyor. Videoda da görüldüğü gibi servo belli süre joystickten gelen verileri alıyor ve ona göre dönüyor. Ancak daha sonra veri akışı kesiliyor. Şimdi ki sorunum veri akışının kesilmesini önlemek. Araştırmalara devam ediyorum. Titremeler ve kendi kendine oynamalar kesildi. Doğru yolda emin adımlarla ilerlemekteyim. Sizlerin yardımı büyük size çok teşekkür ederim @Sercan @ozkarah


Verici Kod:
#include <RF24.h>
#include <RF24_config.h>
#include <nRF24L01.h>
#include<SPI.h>

RF24 verici(9,10);
const byte address[6] = "00001";

int joystick[3];
int buton = 0;
int X = 0;
int Y = 0;


void setup() {
  Serial.begin(9600);
  verici.begin();
  verici.openWritingPipe(address);
  verici.setPALevel(RF24_PA_MAX);
  verici.stopListening();
}

void loop() {
 
  X = analogRead(A0);
  joystick[0] = X;
  Y = analogRead(A1);
  joystick[1] = Y;
  buton = digitalRead(2);
  joystick[2] = buton;
 

  verici.write(&joystick, sizeof(joystick));

 
  Serial.print("X: ");
  Serial.println(joystick[0]);
  Serial.print("Y: ");
  Serial.println(joystick[1]);
  Serial.print("Buton: ");
  Serial.println(joystick[2]);
}

Alıcı Kod:
#include <RF24.h>
#include <RF24_config.h>
#include <nRF24L01.h>
#include <SPI.h>
#include <Servo.h>

RF24 alici(9,10);
const byte address[6] = "00001";

int joystick[3];
Servo servo;

void setup() {
  Serial.begin(9600);
  alici.begin();
  alici.openReadingPipe(0, address);
  alici.setPALevel(RF24_PA_MAX); //Amplify it
  alici.startListening();
  servo.attach(3);
}

void loop() {
  if(alici.available()){
      alici.read(&joystick, sizeof(joystick));
      Serial.print("X: ");
      Serial.println(joystick[0]);

      Serial.print("Y: ");
      Serial.println(joystick[1]);

      Serial.print("Buton: ");
      Serial.println(joystick[2]);

      int xpos = map(joystick[0], 0, 1023, 0, 180);
      Serial.print("xpos: ");
      Serial.println(xpos);
      servo.write(xpos);
      delay(50);
      
      
    
  }

}


 
Güzel. Şimdi mümkün olduğunca veriyi gerektikçe (ilk mesajımda anlatmıştım nasıl yapacağınızı) göndermeye ve delay fonksiyonlarını azaltmaya kurtulmaya odaklanın.
 
@oalikorkmaz sendeki düzenin aynısın kurdum ve test ettim. Aşağıdaki videoda göreceğin üzere ilk durumda seninle aynı sorunu yaşadım.

Mikrodenetleyici ile özellikle etrafta paraztin oluşturabilecek motor, selenoid vb unsurlar varken voltajların temiz olduğundan her zaman emin olmak gerekiyor. Bende bu yüzden öncelikle voltajdan emin olmak istedim. Bunun için ise osiloskopun trigerini düşüşü yakalaması için kurdum.



Motoron çalışıp voltajın düşmeye başladığı andaki sinyal görüntüsü.

ScreenImg.png
 

Çevrimiçi personel

Forum istatistikleri

Konular
5,851
Mesajlar
99,789
Üyeler
2,482
Son üye
ilker29

Son kaynaklar

Son profil mesajları

gruptaki arkadaşlara selamlar. sıteyi bu gün fark ettim. Asansör için 2x7 segment LCD gösterge üretmek istiyorum. acaba bu sayfadaki arkadaşlardan destek alabilirmiyim. LCD nin mantık açılımı ektedir.
deneyci wrote on TA3UIS's profile.
Selam.
Amatör telsiz lisansı nasıl alınıyor?
Lisansı olmayanı forumlarına almıyorlar. :)
Bilgi alamıyoruz.
cemalettin keçeci wrote on HaydarBaris's profile.
barış kardeşim bende bu sene akıllı denizaltı projesine girdim ve sensörleri arastırıyorum tam olarak hangi sensör ve markaları kullandınız yardımcı olabilir misin?
m.white wrote on Altair's profile.
İyi akşamlar.Arabanız ne marka ve sorunu nedir.Ben araba tamircisi değilim ama tamirden anlarım.
* En mühim ve feyizli vazifelerimiz millî eğitim işleridir. Millî eğitim işlerinde mutlaka muzaffer olmak lâzımdır. Bir milletin hakikî kurtuluşu ancak bu suretle olur. (1922)
Back
Top