Arduino İle Uzaktan Kumandalı Araba Yapımı
Bu yazımızda, Arduino İle Uzaktan Kumandalı Araba yapacağız. Uzaktan kumandalı arabamızı yaparken kablosuz haberleşme modülü olarak nrf24l01 modülünü kullanacağız. Ayrıca arabamızı kontrol edecek olan kumanda olarak joystick shield kullanacağız. Hadi projemize başlayalım.
Malzeme Listesi
- 2 adet Arduino Uno
- 2 adet NRF24L01 + PA + LNA
- 1 adet NRF24L01 Adaptörü
- 2 adet Tekerlek ve Dc Motor Seti
- 1 adet Sarhoş Tekerlek
- 1 adet L298N Motor Sürücü
- 12V LiPo Pil(Siz 2 adet 9v pil veya 1 adet 12V LiOn pil kullanabilirsiniz)
- 2.1 mm Erkek Barrel Jack(İsteğe bağlı. Siz direk Vin pinine de bağlayabilirsiniz)
- Dişi-Erkek Jumper Kablolar
- 1 adet Joystick Shield
- 1 Adet Power Bank(Kumandamızı beslemek için. 9v pilde kullanabilirsiniz.)
- 15cmx20cm 3mm mdf(Motorlarımızı ve arduinomuzu sabitleyeceğimiz kısım.)
Kumada Bağlantı Şeması
Joystick shield ile arduinomuzu aşağıdaki gibi birbirine geçirelim. Bende ki joystick shield eski versiyon, sizinkinde bir kaç farklılık olabilir ama bu sorun değil çünkü pin bağlantıları eski versiyondada yeni versiyondada aynı.
Araba Bağlantı Şeması
Arabanın bağlantılarını aşağıdaki gibi yapalım.
Araba Pin Bağlantıları
Modül | Arduino |
NRF24L01 Adaptör CE | 8 |
NRF24L01 Adaptör CSN | 7 |
NRF24L01 Adaptör VCC | 5V |
NRF24L01 Adaptör GND | GND |
NRF24L01 Adaptör MOSI | 11 |
NRF24L01 Adaptör MISO | 12 |
NRF24L01 Adaptör SCK | 13 |
L298N Motor Sürücü IN1 | 3 |
L298N Motor Sürücü IN2 | 4 |
L298N Motor Sürücü IN3 | 5 |
L298N Motor Sürücü IN4 | 6 |
L298N Motor Sürücü GND | GND |
L298N Motor Sürücü 12V | VIN |
Eğer bağlantılarımızı yaptıysanız aşağıdaki gibi mdf’ye aşağıdaki gibi yapıştıralım.
Dc motor setlerini mdfmizin arka kısmına koyun ve motor setimizin bitimine 2 adet delik açın ve cırt ile motorumuzu mdfye sabitleyin diğer modüllerimizi sıcak silikon ile mdfye yapıştırın.
Mdf’nin alt kısmında uç kısmının ortasına sıcak silikonla sarhoş tekerleği yapıştıralım.
Not: Neden sıcak silikon kullandınız derseniz. İstediğiniz zaman arabamızı bozabilir ve parçaları başka projede kullanabilirsiniz.
Arabamızda bir şeye dikkat ettiniz mi? Arduinomuzu ve L298N motor sürücümüzü tek bir yerden besliyoruz. Ben burada arduinomuzu barrel jack ile besledim ve l298n motor sürücü ile birleştridim. Siz verdiğim devre şemasındaki gibi Vin pininden de yapabilirsiniz.
Arabamızın montajını bitirdiyseniz kodumuzu yükleyebiliriz artık.
Arduino kodumuzu yüklemeden önce eğer nrf24l01 kütüphanesini yüklemediyseniz aşağıdaki linkten indirin ve Arduino IDE kütüphanesine ekleyin.
- NRF24L01 kütüphanesini indirmek için buraya tıklayın!
Kumanda Kodu
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN
const byte addresses [][6] = {"00001", "00002"}; //alıcı ve verici adresleri
char b[32];
int butonA=2;
int butonB=3;
int butonC=4;
int butonD=5;
int butonE=6;
int butonF=7;
int butonJoystick=8;
int joystickX=A0;
int joystickY=A1;
int butonlar[7]={butonA,butonB,butonC,butonD,butonE,butonF,butonJoystick};
int kordinatlar[2]={joystickX,joystickY};
void setup() {
Serial.begin(115200);
pinMode(butonA,INPUT);
pinMode(butonB,INPUT);
pinMode(butonC,INPUT);
pinMode(butonD,INPUT);
pinMode(butonE,INPUT);
pinMode(butonF,INPUT);
pinMode(butonJoystick,INPUT);
radio.begin(); //Telsiz iletişiminin başlatılması
radio.openWritingPipe(addresses[1]); //Verileri göndereceğimiz adresin ayarlanması
radio.openReadingPipe(1, addresses[0]); //Verileri alacağımız adresin ayarlanması
radio.setPALevel(RF24_PA_MIN); //Verici ve alıcı arasındaki mesafeye göre minimum veya maksimum olarak ayarlayabilirsiniz.
}
void loop()
{
radio.stopListening();
delay(5);
String veri="";
int durum=digitalRead(butonA);
int durum1=digitalRead(butonA);
int durum2=digitalRead(butonB);
int durum3=digitalRead(butonC);
int durum4=digitalRead(butonD);
int durum5=digitalRead(butonE);
int durum6=digitalRead(butonF);
int durum7=digitalRead(butonJoystick);
veri+=(String(durum1)+";"+String(durum2)+";"+String(durum3)+";"+String(durum4)+";"+String(durum5)+";"+String(durum6)+";"+String(durum7)+";");
for(int i=0;i<2;i++){
int durum=analogRead(kordinatlar[i]);
veri+=(String(durum)+";");
}
veri.toCharArray(b,32);
radio.write(&b, 32); //veri gönderilir.
Serial.println(String(b)+" gonderildi");
//Verinin gönderildiği seri monitöre yazdırılır.
delay(10);
//delay(100);
}
Araba Kodu
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(8, 7); // CE, CSN
const byte addresses [][6] = {"00001", "00002"}; //İki adresin ayarlanması. Biri iletmek ve biri almak için
char b[32];
// H köprüsü için pin tanımları
int IN1 = 3;
int IN2 = 4;
int IN3 = 5;
int IN4 = 6;
String dataa;
String seperated_data[9];
int datacount=0;
int number=0;
void setup() {
Serial.begin(115200);
// Çıkış Pinlerini ayarlıyoruz
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
radio.begin(); //Telsiz iletişiminin başlatılması
radio.openWritingPipe(addresses[0]); //Verileri göndereceğimiz adresin ayarlanması
radio.openReadingPipe(1, addresses[1]); //Verileri alacağımız adresin ayarlanması
radio.setPALevel(RF24_PA_MIN); //Verici ve alıcı arasındaki mesafeye göre minimum veya maksimum olarak ayarlayabilirsiniz.
}
void loop()
{
delay(5); //5 mikrosaniye bekliyoruz.
radio.startListening(); //Bu, modülü alıcı olarak ayarlar
if (radio.available()) //Eğer gelen veri varsa
{
datacount=0;
number=0;
radio.read(&b, 32); // gelen veriyi oku ve b değişkenine kaydet
Serial.println(String(b)+" geldi"); //b char dizisini stringe çevir.
dataa=String(b);
for(int i=0;i<dataa.length();i++){
if(dataa[i]==';'){
seperated_data[datacount]=dataa.substring(number,i);
datacount+=1;
number=i+1;
}
}
String gelenveri="";
for(int i=0;i<9;i++){
gelenveri+=seperated_data[i];
}
Serial.println("Alinan data: "+gelenveri);
delay(5); //5 mikrosaniye bekle
}
if(seperated_data[0]=="0"){
ileri();
}
if(seperated_data[1]=="0"){
sag();
}
if(seperated_data[2]=="0"){
geri();
}
if(seperated_data[3]=="0"){
sol();
}
if(seperated_data[7].toInt()>600){
sag();
}
if(seperated_data[7].toInt()<500){
sol();
}
if(seperated_data[8].toInt()>600){
ileri();
}
if(seperated_data[8].toInt()<500){
geri();
}
if(seperated_data[0]=="1" && seperated_data[1]=="1" && seperated_data[2]=="1" && seperated_data[3]=="1" && seperated_data[7].toInt()>500 && seperated_data[7].toInt()<600 && seperated_data[8].toInt()>500 && seperated_data[8].toInt()<600){
dur();
}
}
void sag(){
//Araba ileri gitsin
//Motor a saat yönünde dönsün
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
//Motor b saat yönünde dönsün
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
void sol(){
//Araba geri gitsin
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
//Motor b saat yönünde dönsün
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
void geri(){
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
//Motor b saat yönünde dönsün
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
void ileri(){
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
//Motor b saat yönünde dönsün
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
void dur(){
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}
Araba Analog Kontrol Kodu
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(8, 7); // CE, CSN
const byte addresses [][6] = {"00001", "00002"}; //İki adresin ayarlanması. Biri iletmek ve biri almak için
char b[32];
// H köprüsü için pin tanımları
int IN1 = 3;
int IN2 = 4;
int IN3 = 5;
int IN4 = 6;
int motor_ENA=9;// sağ motor aktif edici(pwm) pini
int motor_ENB=10;// sol motor aktif edici(pwm) pini
String dataa="1;1;1;1;1;1;1;535;514;";
String seperated_data[9]={"1","1","1","1","1","1","1","535","514"};
int datacount=0;
int number=0;
void setup() {
Serial.begin(115200);
// Çıkış Pinlerini ayarlıyoruz
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(motor_ENA, OUTPUT);
pinMode(motor_ENB, OUTPUT);
radio.begin(); //Telsiz iletişiminin başlatılması
radio.openWritingPipe(addresses[0]); //Verileri göndereceğimiz adresin ayarlanması
radio.openReadingPipe(1, addresses[1]); //Verileri alacağımız adresin ayarlanması
radio.setPALevel(RF24_PA_MIN); //Verici ve alıcı arasındaki mesafeye göre minimum veya maksimum olarak ayarlayabilirsiniz.
}
void loop()
{
delay(5); //5 mikrosaniye bekliyoruz.
radio.startListening(); //Bu, modülü alıcı olarak ayarlar
if (radio.available()) //Eğer gelen veri varsa
{
datacount=0;
number=0;
analogWrite(motor_ENA,0);
analogWrite(motor_ENB,0);
radio.read(&b, 32); // gelen veriyi oku ve b değişkenine kaydet
Serial.println(String(b)+" geldi"); //b char dizisini stringe çevir.
dataa=String(b);
for(int i=0;i<dataa.length();i++){
if(dataa[i]==';'){
seperated_data[datacount]=dataa.substring(number,i);
datacount+=1;
number=i+1;
}
}
String gelenveri="";
for(int i=0;i<9;i++){
gelenveri+=seperated_data[i];
}
Serial.println("Alinan data: "+gelenveri);
delay(5); //5 mikrosaniye bekle
}
if(seperated_data[0]=="0"){
ileri();
}
if(seperated_data[1]=="0"){
sag();
}
if(seperated_data[2]=="0"){
geri();
}
if(seperated_data[3]=="0"){
sol();
}
//--------------------------------------------------------------
int potx=seperated_data[7].toInt();
int poty=seperated_data[8].toInt();
if(potx<=500){
int deger=500-potx;
int potxpwm=map(deger,0,500,0,255);
analogWrite(motor_ENA,potxpwm);
analogWrite(motor_ENB,potxpwm);
sol();
}else if(potx>600){
int deger=potx-600;
int potxpwm=map(deger,600,1023,0,255);
analogWrite(motor_ENA,potxpwm);
analogWrite(motor_ENB,potxpwm);
sag();
}
if(poty<=500){
int deger=500-poty;
int potypwm=map(deger,0,500,0,255);
analogWrite(motor_ENA,potypwm);
analogWrite(motor_ENB,potypwm);
geri();
}else if(poty>600){
int deger=poty-600;
int potypwm=map(deger,600,1023,0,255);
analogWrite(motor_ENA,potypwm);
analogWrite(motor_ENB,potypwm);
ileri();
}
//-----------------------------------------------------------------
if(seperated_data[0]=="1" && seperated_data[1]=="1" && seperated_data[2]=="1" && seperated_data[3]=="1" && seperated_data[7].toInt()>500 && seperated_data[7].toInt()<600 && seperated_data[8].toInt()>500 && seperated_data[8].toInt()<600){
dur();
}
}
void sag(){
//Araba ileri gitsin
//Motor a saat yönünde dönsün
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
//Motor b saat yönünde dönsün
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
void sol(){
//Araba geri gitsin
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
//Motor b saat yönünde dönsün
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
void geri(){
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
//Motor b saat yönünde dönsün
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
void ileri(){
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
//Motor b saat yönünde dönsün
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
void dur(){
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}
Kodların açıklamasını ve projenin yapılışını aşağıdaki videodan izleyebilirsiniz.