Məsafədən İdarəetməli Robot Maşın #2 – Proqramlama

Salam, əziz “Maker”-lər. Ötən məqaləmizdə məsafədən idarəetməli robot maşının gövdəsini və elektrik kabeləşməsini aparmışdıq. İndi isə növbə robotun idarəetmə alqoritmini yazmaqda və mikrokontrolleri proqramlamaqdadır ki, robotumuz bizim göndərəcəyimiz sadə hərəkət əmrlərini (irəli, geri, sağa, sola və s. ) yerinə yetirsin.

Mikrokontroller kimi bu proyektə biz Arduino Uno R3 istifadə etmişik, amma buna baxmayaraq yazdığımız C kodu bir çox digər mikrokontroller növlərinə adaptasiya oluna bilər. Arduino seçməyimizə səbəb bu platformaya olan maraq, proqramlama prosedurlarının sadəliyi və bu kart haqqında internetdə bolluca məlumat olmasıdır. Bununla da robot və ya bənzər proyektlər qurarkən hansısa problemlə üzləşsəniz rahatlıqla internetdən eləcə də bizə müraciət edib suallarınıza cavab tapa bilərsiniz.

Gəlin sistemimizin ümumi blok diaqramına nəzər salaq. Smartfona yüklənmiş app vasitəsilə biz hərəkət əmrlərini Bluetooth üzərindən mikrokontrollerə ötürəcik və o isə öz növbəsində bu əmrlərə uyğun motor sürücü inteqral sxemə müvafiq əmrlər göndərəcək, bununla da bizim sadə robotumuz hərəkətə gələcək.

Blok diaqram RC car

İlk növbədə robotumuzda kabelləşməni düzgün apardığımızdan əmin olduqdan sonra sonuncu çıxardığımız batareyanı qabına taxıb, sistemə qida veririk. Arduino üzərindəki yaşıl Power LED-i yanırsa və Bluetooth modulunun da qırmızı LED-i yanıb-sönürsə “Əhsən!”, deməli hər şey qaydasında gedib.

Daha sonra smartfonumuza Arduino Bluetooth RC Car proqramını yükləyirik. Android App proqramlaya bilənlər istəsələr öz istəklərinə uyğun proqram yazıb, robotu idarə edə bilərlər, lakin mənim bu sahədə biliyim baza səviyyəsində olduğundan və artıq yazılmış olan bir proqramı yenidən yazmaq kimi bir əziyyətə ehtiyac olmadığından bu proqramı istifadə etmək qərarına gəldim. Proqramı işə saldıqda sizdən Bluetoothu işə salmağınızı soruşacaq, işə salırıq və belə bir pəncərə çıxır, ortadakı “Settings” menyusundan “Connect”-ə keçib siyahıdan bizim Bluetooth modulunu tapırıq. Adı çox güman ki, “HC-06” olacaq. Modula qoşulan zaman PİN kod soruşa bilər, bu zaman ya 1234 ya da 0000 daxil edib, qoşulun. Daha sonra PİN kodu və modulun cihaz adını necə dəyişəcəyimizə birlikdə baxacağıq.

Arduino Bluetooth RC Car App interfeysi

Smartfonla Bluetooth modulu arasında simsiz əlaqə uğurla qurulduqdan sonra moduldakı sayrışan işıq daimi yanılı vəziyyətdə qalacaq. İndi isə modulu ilkin test etməyin vaxtıdır. Bunun üçün Arduinoya sadə bir proqram yükləyəcik ki, Smartfondakı App-dan göndərilən əmrləri kompüterdə Arduino İDE proqramının Serial Monitor pəncərəsinə ötürə bilək. Bu proqramın kodunu aşağıda vermişik. Kodda sətrlər arasına bacardığımız qədər şərh əlavə etmişik, amma hansısa qaranlıq qalan məqam olsa məqalənin aşağısında olan şərh hissəsinə yaza bilərsiniz.

Bu proqram Smartfon – Bluetooth modul və PC arasında körpü yaradır, belə ki, əgər smartfondan hansısa simvol gəlirsə onu PC-ə və geri yollayır. Bu proqram vasitəsilə biz həmçinin PC-dən müəyyən simvollar ardıcıllığı yollayıb Bluetooth modulunu sazlaya bilərik. Buna “AT” əmrləri deyilir. İlk öncə Smartfonla Bluetooth arasında əvvəlcədən qurduğumuz əlaqəni kəsirik və bu proqramı Arduinoya yükləyib (Upload) daha sonra Serial Monitoru açırıq. Bu kodu .ino formatında Github səhifəmizdən yükləyə bilərsiniz.

/* Sade elaqe proqrami, Smartfondan gelen simvollari PC-e gonder*/
#include <SoftwareSerial.h>;

#define Rx 2          // BT modulun TX pinine qoshulur     
#define Tx 3          // Gerginlik bolucu rezistorlarla BT modulun RX pinine qoshulur

// deyishenlar ve sabitler
char BT_RECEIVED;   // BT-dan gelen simvol
char PC_RECEIVED;   // PC-den gelen simvol

// Hardware serial PC ile kommunikasiya ucun lazim oldughu ucun SoftwareSerial ishledirik
SoftwareSerial BTserial(Rx, Tx);
             
// bu funksiya cemi bir defe program ishe dushende icra olunur                                   
void setup() 
{ 
  Serial.begin(9600);
  BTserial.begin(9600); // SoftwareSerial baud qiymeti HC-06 BT modulu ucun 9600.
  
  Serial.println("AT emrleri daxil edin!");
  delay(50);
} 

// Bu funksiya sonsuz olaraq tekrarlanir. 
void loop()
{
  if(Serial.available())
  {
      PC_RECEIVED = (char)Serial.read();  // PC-ni oxu
      BTserial.write(PC_RECEIVED);        // Eger PC-den nese gonderilibse, somvolu BT modula gonder
  }

  if(BTserial.available())
  {
     while(BTserial.available())
     {
        BT_RECEIVED = (char)BTserial.read();   // BT-u oxu
        Serial.write(BT_RECEIVED);             // PC-e gonder
     }
  }

  delay(10);  // Serial.write ele de suretli olmadighindan biraz gozlemek stabilliyi artirir. 
}

Serial monitoru açdıqdan sonra Arduino bizə belə bir mesaj göndərəcək

Serial monitor 1Yuxarıdakı xanaya “AT” yazıb “Send” etsək, əgər hər şey qaydasındadırsa o zaman Bluetooth modulu bizə “OK” cavabını verəcək. Əsas “AT” əmrlərinin siyahısı aşağıdakı cədvəldə vermişik, bu əmrlər vasitəsilə yuxarıda qeyd etdiyimiz kimi PİN kodu və cihaz adını dəyişə bilərik.

AT əmri

Modulun cavabı

Əmrin etdiyi təsir

 

AT+VERSION

OKlinvorV1.6

cihaz işçi proqram (firmware) versiyası

 

AT+NAMExyz

OKsetname

 Cihaz adını “xyz” olaraq dəyiş

 

AT+PIN1234

OKsetPIN

PIN kodu 1234 olaraq dəyiş

 

AT+BAUD4

OK9600

Baud dəyərini 9600 bit saniyə (bs) olaraq dəyiş

digər variantlar (9600 default)

1  – 1200 bs
2 – 2400 bs
3  – 4800 bs
4  – 9600 bs
5  – 19200 bs
6 –  38400 bs
7 –  57600 bs
8 – 115200 bs

Cihaz adının dəyişmək üçün nümunə “AT” əmri aşağıdakı kimi olacaq və ad dəyişdirildikdən sonra cihaz bizə “OKsetname” təsdiq mesajını göndərir.

Serial Monitor 2Əgər biz indi Smartfonumuzdakı Bluetooth RC Car app-ni işə salıb və BT moduluna qoşulsaq, bu zaman Serial Monitor pəncərəsində qəribə simvolların peyda olduğunu görərik. Əgəd heç bir düyməyə toxunmuruqsa bu zaman “S”, müxtəlif düymələrə toxunduqda isə “F”, “B”, “L”, “R” və s. hərflər gəlməyə başlayır. Bu hərflərin nə mənaya gəldiyi və digər hansı hərflərin də göndərildiyini yaxşı olar ki, müxtəlif düymə konfiqurasiyalarını basaraq hansı simvolların göndərildiyini müşahidə edəsiniz.

serial monitor 3

İndi isə əsas robot idarə alqoritminini əvvəlki proqramımızın əsasında yazmağa başlaya bilərik. Kodumuzun əsas funksiyası  driveRobot() funksiyasıdır.  Bu funksiya BT modulundan gələn simvollara uyğun olaraq sürət dəyişəninin (SET_SPEED) qiymətini dəyişir və robotun sağ və sol təkərlərinin fırlanma sürətini və istiqamətini göndərilən simvola uyğun təyin edir. Burada əsas fikir verin ki, maşınımızda dönmə əməliyyatları necə aparılıb. Sağa və sola dönmələr birbaşa sağ və soldakı təkərlərin fırlanma istiqamətini bir-birinə əks seçməklə, sağ-irəli, sağ-geri, sol-irəli və s. tipli maneverlər isə sürətin sağ və soldakı təkərlərə qeyri-bərabər paylanması ilə həyata keçirilir. Belədə maşınımız sadə manevrləri çevik bir şəkildə icra edir. Siz istəsəniz bu parametrləri öz istəyinizə görə dəyişə bilərsiniz.  Yekun kodumuzu da .ino formatında Github səhifəsində yerləşdirmişik.

/*
 * www.Makerspace-Az.org
 * Arduino Sketch: 4X4 Robot mashin kontroller
 * Kommunikasiya: Bluetooth (BT)
 * Android App: Bluetooth RC
 * son modifikasiya: 26 Dekabr 2015
 * (azerimaker)
*/

#include <SoftwareSerial.h>;

#define Rx 2          // BT modulun TX pinine qoshulur     
#define Tx 3          // Gerginlik bolucu rezistorlarla BT modulun RX pinine qoshulur

#define motor1A 11    // INA
#define motor1B 10    // INB
#define motor2A 9     // INC
#define motor2B 6     // IND

// deyishenlar ve sabitler
char BT_RECEIVED;   // BT-dan gelen simvol
char PC_RECEIVED;   // PC-den gelen simvol
 
volatile unsigned char SPEED_MIX = 0;
volatile unsigned char SET_SPEED = 100; // bashlangic suret 100 

boolean FORWARD = false; // ireli
boolean BACKWARD = true; // geri
  
// Hardware serial PC ile kommunikasiya ucun lazim oldughu ucun SoftwareSerial ishledirik
SoftwareSerial BTserial(Rx, Tx);
             
// bu funksiya cemi bir defe program ishe dushende icra olunur                                   
void setup() 
{
  pinMode(Rx, INPUT);  // pinleri girish/cixish kimi teyin et
  pinMode(Tx, OUTPUT);
  pinMode(motor1A, OUTPUT);
  pinMode(motor1B, OUTPUT);
  pinMode(motor2A, OUTPUT);
  pinMode(motor2B, OUTPUT);
  
  brakeMotor(); // tekerleri tormozla, ehtiyat ucun
  
  Serial.begin(9600);
  BTserial.begin(9600); // SoftwareSerial baud qiymeti HC-06 BT modulu ucun 9600.
  
  delay(50);
  Serial.println("AT emrleri daxil edin!");

  BTserial.print("AT"); // status oyrenme emrini BT modula gonder
  //BTserial.print("AT\r\n"); // HC-05 modullari ucun bu emrden istifade edin

  while(BTserial.available())
  { 
      Serial.write(BTserial.read()); // sorgunun cavabini PC-e gonder
  }

  delay(50);
} 

// Bu funksiya sonsuz olaraq tekrarlanir. 
void loop()
{
	if(Serial.available())
	  {
	      PC_RECEIVED = (char)Serial.read();  // PC-ni oxu
	      BTserial.write(PC_RECEIVED);        // BT moduluna gonder
	  }

	if(BTserial.available())
	  {
	     while(BTserial.available())
	     {
	        BT_RECEIVED = (char)BTserial.read();   // BT-u oxu
	        Serial.write(BT_RECEIVED);             // PC-e gonder
	        driveRobot(BT_RECEIVED);   // Simvolu hemcinin Robotu idare funksiyasina gonder
	     }
	  }

    delay(10);
}

// robot idare etme funksiyasi
void driveRobot(char COMMAND)
{  
	// cuzi donmeler aparmaq ucun esas suret deyishenini
  	// texminen 2 defe azalt ve uygun tekerin yeni suretini teyin et
  SPEED_MIX = map(SET_SPEED, 0, 255, 0, 127); 
  // COMMAND deyishenine uyghun addim at
  switch(COMMAND){
        case '0':  
            SET_SPEED = 0;
                break;
        case '1': 
            SET_SPEED = 25;
                break;
        case '2': 
            SET_SPEED = 50;
                break;
        case '3': 
            SET_SPEED = 75;
                break;
        case '4': 
            SET_SPEED = 100;
                break;
        case '5': 
            SET_SPEED = 125;
                break;
        case '6': 
            SET_SPEED = 150;
                break;
        case '7': 
            SET_SPEED = 175;
                break;
        case '8': 
            SET_SPEED = 200;
                break;
        case '9': 
            SET_SPEED = 225;
                break;
        case 'q': 
            SET_SPEED = 255;
                break;
        case 'F': // Forward
            setSpeedRight(SET_SPEED, FORWARD);
            setSpeedLeft( SET_SPEED, FORWARD);
            break;
        case 'B': // Backward
            setSpeedRight(SET_SPEED, BACKWARD);
            setSpeedLeft( SET_SPEED, BACKWARD);
            break;
        case 'R': // Right
            setSpeedRight(SET_SPEED, BACKWARD);
            setSpeedLeft( SET_SPEED, FORWARD);
            break;
        case 'L': // Left
            setSpeedRight(SET_SPEED, FORWARD);
            setSpeedLeft( SET_SPEED, BACKWARD);
            break;
        case 'I': // Right + Forward
            setSpeedRight(SPEED_MIX, FORWARD);
            setSpeedLeft( SET_SPEED, FORWARD);
            break;
        case 'G': // Left + Forward
            setSpeedRight(SET_SPEED, FORWARD);
            setSpeedLeft( SPEED_MIX, FORWARD);
            break;
        case 'J': // Right + Backward
            setSpeedRight(SPEED_MIX, BACKWARD);
            setSpeedLeft( SET_SPEED, BACKWARD);
            break;  
        case 'H': // Left + Backward 
            setSpeedRight(SET_SPEED, BACKWARD);
            setSpeedLeft( SPEED_MIX, BACKWARD);
            break; 
        case 'D': 
              Serial.println("BT elaqesi kesildi");
              break;
        default: 
            brakeMotor(); // istenilen bashqa simvol olduqda tekerleri tormozla
            break;
    }
}

// sag tekerlerin suretini ve istiqametini teyin eden funksiya
void setSpeedRight(unsigned char SPEED, boolean DIR)
{
  if(DIR == true){
      digitalWrite(motor2A, LOW);
      analogWrite (motor2B, SPEED);
  }
  else{
      analogWrite(motor2A, SPEED);
      digitalWrite(motor2B, LOW);
  }
  
}

// sol tekerlerin suretini ve istiqametini teyin eden funksiya
void setSpeedLeft(unsigned char SPEED, boolean DIR)
{
  if(DIR == true){
      digitalWrite(motor1A, LOW);
      analogWrite (motor1B, SPEED);
  }
  else{
      analogWrite(motor1A, SPEED);
      digitalWrite(motor1B, LOW);   
  }
  
}

void brakeMotor(void)
{
    digitalWrite(motor1A, LOW);
    digitalWrite(motor1B, LOW);
    digitalWrite(motor2A, LOW);
    digitalWrite(motor2B, LOW);
}

Kodumuzun yekun halıyla Arduinoyu proqramladıqdan sonra robotumuz məsafədən idarəetməyə hazırıq. Bu qısa videodan da qoşulmanın necə aparıldığını və robotun hansı manevrlər edtiyini əyani görə bilərsiniz.

HC-06 və oxşar Bluetooth modullarla açıq ərazidə təxminən 15-20 metr radiuslu ərazini əhatə etmək mümkündür, bu elə də çox olmasa da başlanğıc üçün kifayət edir. Növbəti məqaləmizdə isə siqnalın çatma məsafəsini necə artırmaq və robotumuzu daha da təkmilləşdirmə yollarına baxacağıq. Məqaləni bəyəndinizsə öz dostlarınızla paylaşmağı unutmayın. Bütün oxucularımıza uğurlar.

 

PaylaşShare on FacebookTweet about this on TwitterShare on LinkedInShare on Google+Email this to someonePin on PinterestShare on RedditShare on TumblrDigg this

Comments

comments

You may also like...

Rəy bildir