Arduino
OKUDUĞUNUZ KONU
ARDUINO – TINKERCAD Proje Özelleştirme #2
0

ARDUINO – TINKERCAD Proje Özelleştirme #2

Yazar : Turgut Güneysu31 Ağustos 2018
UNO'dan UNO'ya sanal seri port'tan mesaj yollama.

Merhaba,

İkinci özelleştirme projemize hoş geldiniz. İlk projemizi daha görmediyseniz, buradan ulaşabilirsiniz: ARDUINO – TINKERCAD PROJE ÖZELLEŞTİRME #1

Bu sefer bloklarla çalışmayı basit bulan arkadaşlara hitaben projemizi tamamen METİN modunda Arduino C++ la geliştireceğiz. Biraz çetin bir çalışma olacak ama umarım sonuç hoşunuza gider.

Bu bir özelleştirme projesi olduğundan yine Tinkercad’deki Arduino hazır devrelerden başlayıp, hem donanım hem de yazılım değişikliklerimizi uygulayarak projemizi yaratacağız.

Amacımız: birinci Arduino’nun Seri Monitörüne yazdığımız mesajları ikinci Arduino’ya yollayıp LCD paneline yazmak.

Halen yapmadıysanız, başlangıç noktamız olan hazır LCD devresini bir gözden geçirin ve çalışmasını izleyin. Bu devre biraz komplike olan LCD kütüphanesi ile çalıştığından ve blok kodlama komutları LCD çalıştıran fonksiyonları kapsamadığından direkt olarak Arduino C++’a dalarak çalışacağız.

ÖZELLEŞTİRME:

Projemizi geliştirmek için önce hazır LCD devresini alıp bazı donanım değişiklikleri uygulayacağız. Sonra bir ARDUINO ekleyerek ikisi arasında bağlantı oluşturacağız. Son kademede kodlarımızı geliştirerek ikisi arasında bir iletişim sağlayacak şekilde sonuçlandıracağız. İki Arduino arasındaki iletişimi SoftwareSerial (Sanal Seri) kütüphanesi ile yapacağız.

1. LCD Donanım Değişiklikleri

Yeni proje sayfanızı açıp üzerine hazır LCD devresini kopyalayın. Bu devrenin ortasında bir potansiyometre göreceksiniz. Bunun işi LCD panelinin kontrast ayarını yapmak. Bu bize lazım olan bir şey değil. Onun için bunu kaldırıp bağlantılarını düzenleyeceğiz.

Aşağıdaki resimlerde gördüğünüz gibi pot’u silin ve üç ayak bağlantılarını ikinci resimde görüldüğü gibi ayarlayın. Silme işlemi için pot’u tıklayıp seçin ve silin. Bağlantıları silip yeniden yapmak daha kolay olabilir, ama size kalmış.

Orijinal POT bağlantısı

POT’suz bağlantı ayarları.

 

 

 

 

 

 

 

 

 

 

Pot’u ve bağlantılarını silmek dışında LCD devresine yapılacak başka bir değişiklik yok.

2. Yeni ARDUINO ekliyoruz.

Şimdi aşağıdaki resimde gördüğünüz gibi, ikinci bir Arduino’yu ekrana ekleyin ve bağlantılarını aynen tamamlayın.

Sadece üç bağlantı gerekecektir:

Kablo bağlantılarınızı kontrol edin. Her şey yolunda ise kodlamaya başlayacağız.

3. YAZILIM planlaması.

Kod yazmaya başlamadan önce projemizi nasıl özelleştirmek istediğimizi kısaca kayıtlayıp, ufak bir planlama yapalım:

  1. Ana çalışma prensibimiz birinci Arduino’dan LCD’li Arduino’ya mesaj yollamak ve mesajı LCD paneline yazmak.
  2. Program çalışmaya başladığında:
    * LCD’yi ilklendirip panelin birinci satırına ‘LCD Hazır’ mesajını yazmak.
    * Panelin ikinci satırına kendi etrafında dönen bir İMLEÇ uygulaması yapmak.
    * UNO-1 Seri Monitörüne ‘SERI port HAZIR!’ mesajını yazmak.
  3. UNO-2’ye yollanacak mesajlar UNO-1’in Seri Monitörüne yazılır.
    * Eğer girilen mesajın uzunluğu 16 harften fazlaysa, ‘HATA: Mesaj 16 harften uzun.’ mesajı Seri monitör ekranına yazılır ve UNO-1 kilitlenir.
    * Bu durumda UNO-1’in RESET butonuna basıp yeniden başlatmanız gerekir. UNO-1 tekrar çalışmaya başladığında Seri Monitöründe ‘SERI port HAZIR!’ mesajını görürsünüz.
  4. Geçerli mesaj softwareSerial (Sanal Seri) portundan UNO-2’ye yollanır ve LCD paneline yazılır.

4. KOD’lamaya başlıyoruz.

Projemizde iki tane Arduino kullandığımız için iki ayrı yazılım geliştireceğiz. Birinci yazılım mesaj yollayan UNO-1 adlı Arduino’ya yüklenecek. İkinci yazılım UNO-2 adlı Arduino’ya yüklenecek ve gelen mesajları bekleyip, alınca LCD panele yazacak.

Kodunuzu yazmak için önce üstüne tıklıyarak birinci Arduino’yu seçin. Sonra mavi ‘Code’ butonu tıklayıp kod yazma panelini açın. Kodlama modunu ‘Text’ (Metin) olarak ayarlayın ve yazmaya başlayın.

Detaylarına bakalım.

UNO-1: Bu Arduino seri monitör girişini devamlı yoklayıp mesaj var mı yok mu diyen bir döngü içinde çalışır. Eğer bir mesaj algılarsa, hemen mesajın 16 harften uzun olup olmadığını kontrol eder. Eğer mesaj 16 harften uzunsa seri monitöre ‘HATA: Mesaj 16 harften uzun.’ yazıp sistemi kilitler. Yukarıda belirtildiği gibi bir RESET yapıp programı yeniden çalıştırmak gerekir. Hata yoksa mesajın harfleri teker teker öteki Arduino’ya yollanır.

Şimdi kodumuzu satır satır inceleyelim:

/*
 UNO_1
 
 Bu ARDUINO ve program başka bir ARDUINO'ya SANAL Seri 
 porttan bağlanıp seri monitöre yazılan mesajları yolluyor. 
 Öteki ARDUINO'da yollanan mesaj LCD panele yazılıyor.
 Mesaj uzunluğu 16 harften büyükse hata oluşturuluyor.
*/

Birkaç satırdan oluşan bir açıklama bloku programımızı kısaca tanıtıyor.

#include <SoftwareSerial.h>

Sanal Seri port kütüphanesini kullanmak içi bu satırı programımıza ekliyoruz.

// Sanal SERI Port atamalari
const byte rxPin = 7;
const byte txPin = 8;
SoftwareSerial uno1SER(rxPin, txPin);

Sanal seri port nesnesini oluşturmak için gereken RX ve TX pinleri burada tanımlanıyor ve pin değerleri atanıyor. Arkasından sanal seri port nesnemize uno1SER adını vererek belirliyoruz ve kullanacağımız pinler de nesnemize atanıyor.

byte girdi; // Buffer

Seri porttan okuyacağımız mesajları işleyebilmek için bir girdi değişkeni tanımlıyoruz. Bu değişken bir harf boyutunda olup, mesajın harflerini teker teker öteki Arduino’ya yollamamıza yardımcı olacaktır. Değer yayılma aralığı 0 – 255 tir.

void setup(){
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  Serial.begin(9600); // Mesajlarin geldigi seri port
  uno1SER.begin(4800); // Mesajlarin yollandigi sanal seri port
  Serial.println("SERI port HAZIR!");
}

Arduino kodlarında setup()  fonksiyonu tek defa işlenir ve programın temel çalışma ayarları burada yapılır.

  • Bu kısımda önce RX pinini INPUT (girdi) ve TX pinini OUTPUT (çıktı) olarak tanımlıyoruz. Sonra seri port çalışma hızını 9600 baud’a ayarlıyoruz.
  • Arkasından sanal seri port hızımızı 4800 baud’a ayarlıyoruz.
  • Normalde bu ayarlar 1115200 e kadar olmasına rağmen, simulasyon olarak çalıştığımızdan hızları düşük tutmak daha kontrollü bir çalışma ortamı sağlıyor. Hakiki Arduino ile çalıştığınızda bunları yükseltebilirisiniz.
  • Son olarak da Seri monitörüne mesaj yazarak normal çalışma döngüsüne girmeye hazır olduğumuzu belirtiyoruz.
void loop() {
// SERI port arabellek 64 harftir.
// SERI monitore yazilan harfler SEND e basinca ara bellege girer.
// Arabellekte harf oldugu surece Serial.available() > 0.
// Her okunan harf Serial.available() degerini bir azaltir.

loop() fonksiyon sonsuz döngüsü Arduino kodlarının esas işlemlerinin yapıldığı yerdir.

Burada kısa bir kaç açıklama ile seri port çalışma prensiplerini belirttik.

  while (Serial.available()) { // SERI portta mesaj varsa
    delay(20);

Açıklamada anlatıldığı gibi seri port 64 baytlık ara bellekle çalışan bir iç yapıdır. Burada Serial.available() fonksiyonu doğru olduğunda klavyeden girdiğimiz harflerin en az biri ara belleğe ulaşmış demektir. 20 mili saniye bekleyerek yazılmış olan en fazla 16 harfin de belleğe dolmasını garantiliyoruz. Böylece mesajı bütün bir blok olarak işleme imkanımız daha yüksek oluyor. Aslında bu muhakkak yapılması gereken bir şey değildir. Ama görüntü olarak kesintisiz bir şekilde mesajımızın LCD panelde gözükmesini sağlıyor. İsterseniz bu değerle oynayarak etkilerini inceleyebilirsiniz.

    if (Serial.available() > 16) { // Uzunluk kontrolu
      Serial.println("\nHATA: Mesaj 16 harften uzun.");
      while(true){}; // DUR !!! RESET Lazim.
    }

Mesajımızı ara belleğe aktardıktan sonra ilk yapmamız gerek şey uzunluğu kontrol ederek ekran boyutları dışında olmasını önlemek. Bu da aslında 100% yapılması gereken bir şey değildir. Ama bu tip kontrolleri kodumuzda kullandığımızda hem görüntü kalite kontrolü bizde oluyor hem de daha sağlam kod yazmış oluyoruz. Programlardaki değişken değer limitlerini kontrol etmeyi alışkanlık ederseniz kodlarınızın kalitesi ve doğru çalışma orantısı yükselir.

Burada eğer mesaj 16 harften uzunsa seri monitöre bir mesaj yazıp programı sonsuz bir while(true) {} döngüsüne sokup kilitliyoruz. Bunu yapmamızın sebebi bu kodları kapsayan loop() döngüsünün sonsuz çalışması ve programı durdurma imkanımızın olmamasıdır. Durduramadığımıza göre yapabileceğimiz tek şey sonsuz bir döngüyü devreye almaktır.

Eğer bu koşul oluşmuşsa, bundan programın kendi kendine çıkması imkansız olduğundan, yapılacak tek şey RESET butonuna basıp işlemciyi ve programımızı yeniden başlatmaktır.

    while (Serial.available() > 0) {
      girdi = Serial.read(); // Bir harf oku
      uno1SER.write(girdi); // SANAL porta yolla
      Serial.write(girdi); // SERI monitore yaz
    }
  }
}

Mesaj uzunluğunda bir problem yoksa kodumuzun ana döngüsüne ulaşmış oluyoruz. Burada seri bellekte harfler olduğu sürece (Serial.available() > 0) harfleri teker teker okuyup hem sanal seri port’a (uno1SER) yolluyoruz hem de seri monitöre yazıyoruz.

Dikkat edilmesi gereken noktalar:

  • Serial.read() fonksiyonu ara bellekten sadece bir harf okur. Bu harf girdi değişkenine atanıyor.
  • Serial.available() ‘ın döndürdüğü ara bellek harf sayısı her Serial.read() kullanıldığında bir azalır. Serial.available() sıfır olunca ara bellek boşalmış, mesaj harfleri bitmiş demektir.
  • Her iki seri port için de write() fonksiyonunu kullanıyoruz. Bu binary (ikili) veri yazan bir fonksiyon ve harfleri doğru transfer etmemizi sağlıyor. Eğer write() yerine print() kullanırsanız, LCD panelde yazılan değerlerin ASCII DEC olduğunu görürsünüz.
    örneğin: ‘ev’ yolladığınızda ‘101118‘ görürsünüz:    e = 101, v = 118 

UNO-1 komple yazılım:
Aşağıdaki bağlantıdan UNO-1 için yazılan kodun tümüne ulaşabilirsiniz:
https://www.projehocam.com/wp-content/uploads/2018/08/TCProj_02UNO1.txt

 

UNO-2: Orijinal hazır LCD devre kodu LCD’yi ilkledikten sonra ilk satırına ‘hello, world!’ yazıp, ikinci satıra her bir saniyede artan mili saniye değerini yazar.

LCD proje orijinal yazılım:
https://www.projehocam.com/wp-content/uploads/2018/08/LCD_Orig.txt

Biz bu kodu değiştirip öteki Arduino’dan gelen mesajları yazacak şekile sokacağız.

Yazacağımız Arduino programı çalışmaya başladığında LCD panelin ilk satırına ‘LCD HAZIR!’ yazacak. Sonra sonsuz döngü olan loop() fonksiyonunda önce ikinci satırın başına kendi etrafında dönen bir imleç yazacak. Arkasından öteki Arduino’dan gelen harfleri bekleyen bir döngüye girecek. Eğer bir harf algılarsa hemen LCD panele yazacak. Bütün mesaj yazıldığında 500 mili saniye mesajı okumamızı bekleyecek. Sonra mesajı silip, tekrar imleç ve mesaj bekleme döngüsüne devam edecek.

Şimdi kodumuzu satır satır inceleyelim:

/*
LiquidCrystal Library - on UNO_2

Bu program öteki Arduino'dan gelen mesajları LCD panele yazıyor.

Devre:
* LCD RS pin to D12
* LCD Enable pin to D11
* LCD D4 pin to D5
* LCD D5 pin to D4
* LCD D6 pin to D3
* LCD D7 pin to D2
* LCD R/W pin to GND
* LCD VSS pin to GND
* LCD VCC pin to 5V
* 10K resistor:
UÇLARI to +5V and GND

Library originally added 18 Apr 2008
by David A. Mellis
library modified 5 Jul 2009
by Limor Fried (http://www.ladyada.net)
example added 9 Jul 2009
by Tom Igoe
modified 22 Nov 2010
by Tom Igoe

This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/LiquidCrystal
*/

Programın başlangıcında bir kaç satır açıklama ile programın ne yaptığını ve LCD bağlantılarını belirtiyoruz. Bu kısmın sonunda orijinal LCD kütüphanesini yazanların adları var.

// KUTUPHANELERI Ekle:
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>

İlk yapmamız gereken iş kullanmak istediğimiz kütüphaneleri programımıza eklemek. Bunu ya direkt yazarak, ya da kodlama panelinin üst ortasında bulunan kütüphane ikonundan    istediğimiz kütüphaneyi tıklayarak yapabiliriz. Unutmayın ki, kütüphaneyi böyle eklerseniz ‘#include’ satırı yazdığınız kodun en başına eklenir. Bunu sonra istediğiniz yere kes yapıştır yapabilirsiniz.

Biz hem LCD hem de sanal seri port kullanacağımız için bu iki kütüphaneyi koda ekliyoruz.

Aşağıda kütüphane ikonuna basıldığında göreceğiniz kütüphane listesini inceleyin:

// LCD panel pin atamalari 
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Sanal SERI Port atamalari
const byte rxPin = 7;
const byte txPin = 8;
SoftwareSerial uno2SER(rxPin, txPin);

Kütüphaneleri kullanabilmek için birer nesne belirleyip bunlara kullanacağımız pinleri atamamız lazım.

LCD panelimiz için lcd adlı nesneyi belirliyoruz. ‘lcd(12, 11, 5, 4, 3, 2);’ de pin atamalarını yapıyor.

Sanal seri port için uno2SER adlı nesneyi belirliyoruz. Öteki UNO-1 programında olduğu gibi RX ve TX pinleri tanımlanıp nesneye atanıyor.

void setup() {
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  uno2SER.begin(4800);

  lcd.begin(16, 2); // LCD ayarlari: kac harf, kac satir
  lcd.clear();
  lcd.print("LCD HAZIR!"); // LCD'ye mesaj yaz
}

setup() döngüsünde önce sanal seri portun (uno2SER) RX ve TX pinlerini girdi çıktı olarak belirliyoruz. Arkasından 4800 baud’da çalıştırma ayarını yapıyoruz. Bu düşük sürati seçme sebebi simülasyonda çalışmamız. Genelde 115200 e kadar seçeneğimiz var. Fakat değişik sistemlerde işlemci ve simülasyon çalışma hızına göre fazla yüksek değerler iyi sonuç vermeyebilir. İsterseniz değiştirip kendi sisteminizde deneyin.

Hemen arkasından da LCD panel ayarlarını yapıyoruz.

lcd.begin() panelin kaç harf ve satır çalıştığını belirliyor.

lcd.clear() paneli siliyor.

lcd.print() ise panelin hazır olduğunu belirten mesajı panele yazıyor.

LCD kütüphanesinde bu üç fonksiyon dahil deneyebileceğiniz bir sürü fonksiyon var:

LiquidCrystal(), begin(), clear(), home(), setCursor(), write(), print(), cursor(),
noCursor(), blink(), noBlink(), display(), noDisplay(), scrollDisplayLeft(),
scrollDisplayRight(), autoscroll(), noAutoscroll(), leftToRight(), rightToLeft(),
createChar().

Bunların nasıl çalıştığını Arduino Referans sayfasından okuyabilirsiniz:
https://www.arduino.cc/en/Reference/LiquidCrystal

 

void imlec() { // Pervane gibi donen IMLEC goster
  byte bekle = 25;
  byte imlec[] = "|/-\|/-\\";
  for (int i=0; i<sizeof(imlec)-1; i++) {
    lcd.setCursor(0, 1);
    lcd.write(imlec[i]);
    delay(bekle);
  }
}

UNO-2 program açıklamamızda yazdığımız gibi LCD panelin ikinci satır başına kendi etrafında dönen bir imleç yapmak istiyoruz. Bunun için bir fonksiyon yazacağız.

Adını void imlec() koyduk. Geriye bir değer döndürmediği için tipi void.

bekle adlı bir bekleme değişkeni yarattık. 25 mili saniye ilk değer atadık.

İmleçin basit grafiği için sekiz karakterden oluşan imlec[] adlı bir dizi yaptık. Buna atanan karakterler sırayla panele yazıldığında imleç dönmeye başlayacak.

for döngüsü imleçi canlandıran kodu içeriyor. Her iterasyonda önce LCD imleç pozisyonunu ikinci satırın başına ayarlıyoruz. Sonra imlec[] dizi karakterlerini sırayla panele yazıp arada ufak bir beklemeden sonra devam ediyoruz.

Bekleme değeri benim izlediğim ve hoşuma giden bir sonuca göre ayarlanmıştır. Sizin sisteminizde başka değerler daha iyi çalışabilir. Deneyin!

void loop() {
  imlec(); // Imlec goster
  if (uno2SER.available()) { // SANAL portta mesaj varsa
    lcd.setCursor(0, 1);
    while (uno2SER.available() > 0) { // SANAL porttaki harfler icin
      lcd.write(uno2SER.read()); // Bir harf oku ve LCD ye yaz
    }
    delay(500); // Bekle ki okunabilsin
    lcd.setCursor(0, 1);
    lcd.print("                "); // 2ci satiri sil
  }
}

Şimdi geldik loop() döngüsüne. Burada yapacağımız iki iş var:
* imleç gösterme.
* öteki Arduino’dan gelen mesajı gösterme ve yarım saniye sonra silme.

imlec() fonksiyonu yukarıda anlattığım gibi imleçi LCD ikinci satırına yazıyor.

Ondan sonra sanal seri portta (uno2SER) mesaj varsa LCD imleçi birinci pozisyona ayarlayıp mesaj harflerini teker teker panele yazıyoruz. Sanal seri port çalışma tekniği yukarıda UNO-1 kısmında izah edilmişti.

Mesaj bitince yarım saniye bekleyip mesajın okunmasını sağlıyoruz.

Sonra ikinci satırı silip tekrar başa dönüyoruz.

NOT:
if (uno2SER.available()) ve while (uno2SER.available() > 0) koşullarının peş peşe kullanılmasını bazıları garip bulabilir. Fakat önce mesaj var mı diye kontrol edip, varsa bütün mesajı işleyip satırı silmek görünüş olarak ve çalışma hızı olarak daha uygun bir sonuç veriyor. Çünkü eğer mesaj yoksa, loop()  fonksiyonu son süratlen imleç göstermeye devam ediyor. Bu kısımla oynayıp değişik sıralamaları deneyebilirsiniz.

UNO-2 komple yazılım:
https://www.projehocam.com/wp-content/uploads/2018/08/TCProj_02UNO2.txt

 

5. Projenin Testi

Buraya kadar takip edip uyguladıysanız kodunuz hazır demektir. Denemek için ‘Start Simulation’ e basıp çalıştırmayı deneyin.

Projenizi test ederken dikkat edeceğiniz bir kaç nokta:

  • Sistemde iki Arduino olduğundan ikisinin de ayrı Seri monitör penceresi vardır.
  • Kodlama alanının altındaki Seri Monitör penceresini açmayı unutmayın. Burada UNO-1 sisteminden gelen mesajları izleyeceksiniz.
  • Mesajınızı giremeden önce birinci Arduino üzerine tıklamayı unutmayın.
  • Sistemin karakter kodu ayarlarından dolayı TÜRKÇE harfler doğru gözükmeyebilir.
  • Eğer monitör alanı yazılarla dolarsa, seri girdi alanının sağ yanındaki    butonuna basarak temizleyin.
  • Eğer fazla uzun mesaj yazıp HATA oluşturursanız, UNO-1’in RESET düğmesine basıp baştan çalıştırmayı unutmayın.

 

Aşağıdaki videodan projenin çalışmasını izleyebilirsiniz:

 

6. Gelişmiş uygulama

Teknik olarak daha ileri bir çalışma yapmak isteyenlere aşağıdaki ileri uygulamanın kodunu yazmayı denemelerini tavsiye ederim.

Girdiğiniz mesaj 16 harften uzun olduğu zaman, hata mesajı verip sistemi kilitlemek yerine LCD panelindeki mesajı sola kaydırıp ekstra harfleri panele yazmaya devam edin.

Başarabilirseniz LCD ve mesaj işleme tekniğiniz gayet iyi demektir.

BONUS: Bu uygulamayı aynen iki tane hakiki Arduino kullanarak da yapabilirsiniz.

İyi Çalışmalar.

 

SİZCE NASIL OLMUŞ?
Beğendim
0%
İlginç
0%
Eh İşte
0%
Anlamadım
0%
Kötü
0%
Berbat
0%
YAZAR HAKKINDA
Turgut Güneysu
Turgut Güneysu
Anadolu'nun tam ortasında ufak bir köyden memleketimizin çocuklarına STEM programlarına uygun bilgisayar, robotik, yazılım, donanım, mikro işlemciler hakkında yardımcı olmaya çalışıp, emekli hayatımın zevkini çıkarıyorum. Gençlerimizin kabiliyetlerinin sonsuz olduğuna ve onları doğru yönlendirirsek değerli katkılarla ortamımızı dünya çapına ulaştıracaklarına inanıyorum.
YORUMLAR

YORUM YAP