UART ile Haberleşme ve Haberleşme Parametreleri
Bir önceki "Asenkron Seri Haberleşme" yazısında python kullanarak Orange pi ve bilgisayar arasında veri alıp ve göndermiştik. Bunun için yazdığımız kodun başında seri haberleşme için gerekli olan parametreleri belirtmemiz gerekiyor. İsteğe bağlı olarak tüm parametreler belirtilmek zorunda değil. Eğer belirtilmezse bu parametreler varsayılan değerleri alır.Bu parametreler:
- Port => Kullanılan UART portu.
- Baud rate => Kullanılan Baud hızı; 9600,112500... olabilir.
- Parity =>Eşlenik biti. Even veya Odd, None olabilir. Varsayılan değer:None.
- Stop bits => Bitiş biti. Bir veya iki bit olabilir. Varsayılan değer, bir bit.
- Byte size =>Veri uzunluğu, yedi bit veya sekiz bit olabilir. Varsayılan değer, sekiz bit.
Yukarıda belirtildiği gibi kodda tüm parametreleri belirtmek zorunda değiliz. Örnek kodumuza bakalım.
Örnek kodda sadece port ve baud oran belirtilmiştir. Bunun için diğer parametreler varsayılan değerlere ayarlanmıştır. Bilgisayar üzerindeki seri arayüz programlarını çalıştırırken bunu dikkate almalıyız.
Burada sadece port ismi ve baud hızı ki bu iki parametrenin varsayılan değeri yoktur, belirttiğimizde geri kalan parametrelerin varsayılan değer olduğunu bilip seri arayüz programında da bunu doğru şekilde ayarladıktan sonra programın çalışmasında, verilerin alışverişinde bir sorun olmuyor.
Peki kodda tüm parametreleri belirtmek istiyorsak ne yaparız, bunun nasıl bir söz dizimi vardır?
ser = serial.Serial(
port=’dev/ttyS1’, baudrate =9600, parity =serial.PARITY_EVEN,
stopbits=serial.STOPBITS_TWO, bytesize= serial.SEVENBITS)
Bu şekilde port adımızı(dev/ttyS1), baud oranını(9600), eşlenik bitini(EVEN), bitiş bitini(iki) ve veri boyutunu(yedi bit) belirtmiş, tanımlamış oluyoruz.
Başka bir gösterim de şu şekildedir.
ser=serial.Serial()
ser.baudrate = ‘9600’
ser.port = ‘dev/ttyS1’
Bütün parametreleri öğrendiğimize göre ve seri haberleşmenin düzgün olabilmesi için bu değerlerin her iki taraf için de aynı olduğunu bildiğimize göre bu değerleri farklı yaparak ne olacağını görelim ve yorumlayalım.
Baud oranının iki cihaz için farklı olması
Örnek kodumuzda baud oranı '9600' dü. Bilgisayardaki seri arayüz programında bu değeri '19200' yapalım. Peki bu ne anlama gelir?
Orange pi'den göndereceğimiz veya alacağımız verinin her bir biti arası 1/9600'den yaklaşık 104 mikrosaniye iletilir. Bilgisayarın ise alacağı ve göndereceği veri 1/19200'den yaklaşık 52 mikrosaniyedir. Yani bilgisayar iki bit gönderdiğinde Orange pi bunu bir bit olarak görecek. En sonunda da bu bitleri birleştirip verinin ne olduğunu anlamaya çalıştığında ortaya bozuk karakterler çıkacak.
Orange pi'den göndereceğimiz veya alacağımız verinin her bir biti arası 1/9600'den yaklaşık 104 mikrosaniye iletilir. Bilgisayarın ise alacağı ve göndereceği veri 1/19200'den yaklaşık 52 mikrosaniyedir. Yani bilgisayar iki bit gönderdiğinde Orange pi bunu bir bit olarak görecek. En sonunda da bu bitleri birleştirip verinin ne olduğunu anlamaya çalıştığında ortaya bozuk karakterler çıkacak.
Gördüğünüz gibi seri ekranda gözüken bizim Orange pi'den gönderdiğimiz veriler değil. Orange pi komut ekranında çıkan "belirlenemeyen bir karakter girişi" yazısı, koddan "print" ile yazıldığından bu veri düzgün.
Baud oranlarının farklı olmasından dolayı bilgisayardan 'n' karakterini girsem bile Orange pi girdiğim bu karakteri düzgün okuyamadığı için program "belirlenemeyen bir karakter girişi" uyarısı veriyor.
Bit sayısının iki cihaz için farklı olması
Örnek kodda bit sayısı belirtilmediği için veri biti sayısını varsayılan olarak sekiz bit olduğunu biliyoruz. Bilgisayardaki seri arayüz programında veri biti sayısını yedi bit yapalım. Peki bu ne anlama gelir? Asenkron seri haberleşmede veri paketi başlangıç biti, veri bitleri ve bitiş bitinden oluşur.(opsiyonel olarak eşlenik biti de olabilir.) Veri de herhangi bir karakterin ASCII karşılığının ikili sayı düzenindeki karşılığıdır. Örnek kodda kullandığımız 'y' ve 'n' karakterlerimizden 'n' karakterine bakalım.
n=> ASCII’ye göre '110' sayısına karşılık gelir. '110' sayısı ikili biçimde '1101110' dır. Bu veriyi bir vericiden bir alıcıya seri olarak göndermeye çalıştığımızda bu veriye başlangıç ve bitiş bitleri de eklenir ve başlangıç bitinden sonra en düşük değerli bitten başlayarak iletilmeye başlar.
Seri haberleşme en düşük önemli bitten başlıyordu. Şimdi adım adım gidelim. Bilgisayardaki seri ekranın klavyesinden girdiğimiz 'n' harfi ilk önce ikili(binary) forma dönüştürülüyor.
n = 1101110
Sonra bilgisayardan Orange pi'ye gönderilecek veri hazırlanıyor. Programda eşlenik biti varsayılan değer "none" olduğu için veriye başlangıç ve bitiş bitleri eklenip bu veri paketi başlangıç bitinden sonra en düşük önemli bitten en önemli bite doğru iletilmeye başlıyor. Son olarak bitiş biti de gönderilip bu verinin gönderilme işlemi gerçekleşmiş oluyor.
Bilgisayardan gönderilen veri "data boyutu=7" olduğundan 7 bit(veri biti) + 2 bit(başlangıç-bitiş biti) olarak toplam 9 bitlik veri paketi şeklinde UART'a geliyor. Bu yüzden Orange pi'ye gönderilen veri paketi " 1'1101110'0 " dır.
Şimdi Orange pi tarafına bakalım. Bu veri paketi geldiğinde bunu nasıl değerlendirecek. Önceki yazıdan normalde UART sinyali '1' konumundaydı. Verinin gelmesi için bu çıkışın '0' olması gerekiyordu. Başlangıç bitinden sonra Orange pi programda belirttiğimiz üzere verinin 8 bit olduğunu biliyor ve bu yüzden 8 bit alıp bunu işleyecek. Peki başlangıç bitinden sonraki 8 bit ne? Bitiş bitininde içinde olduğu " 1'1101110" Peki program iletimin bittiğini nasıl anlatacak. Normalde iletim yokken UART çıkışı 1 olduğu için bir sonraki bit de '1' olur ve UART 8 bit aldıktan ve bitiş bitini de aldığı için iletimin gerçekleştiğini düşünür.

Sonuç olarak Orange pi verinin "11101110" olduğunu düşünür. Bu da ASCII kodu olarak 238' e denk geliyor. Bu ASCII kodu da aşağıdaki tabloda görebileceğiniz bir karaktere denk geliyor.

Buradaki karakterler belirsiz karakterler olduğu için ekranda bunlar okunamaz bir karakter olarak gözükecek.
Buraya kadar teorik olarak ne olabileceğini konuştuk. Şimdi bütün bu işlemleri, Orange pi'ye hangi karakterin geleceğini; bu karakterin, "ASCII", "Binary" ve "Hex" karşılıklarını görebileceğimiz bir python dili ile bir program yazalım ve bu adımları görelim.
Bu python ile yazılmış programda programda Orange pi'ye gelen "karakteri", "ASCII " karşılığını, "Hex" karşılığını ve "Binary" karşılığını; ardından normalde yedi bit gelen ama Orange pi' nin sekiz bit olarak aldığı ve bu sekizinci bitin de '1' olduğunu bildiğimiz için bu bitin sekizinci basamaktaki değeri olan '128' kullanarak gelen değerden '128' çıkarıp gelmesi gereken karakteri buluyoruz.
NOT: Hatta bu bilgilerle bir hata programı bile yazılabilir. Eğer alınan karakterin ASCII kodundan '128' çıkardığımızda mantıklı bir değer çıkıyorsa program hata versin ve sorunun muhtemelen veri uzunluğunun uyuşmadığı ile ilgili uyarı mesajı versin. Bu programı önümüzdeki yazıda paylaşacağım.
Normal konumuza dönecek olursak, örnek koda bazı eklemeler yapıp yukarıda bahsettiğim değerleri görüyoruz. Bu sayede veri uzunluğunun programda ne gibi bir sorun çıkarttığını daha iyi anlayabiliyoruz.

Burada programın "else" kısmı ile ilgileneceğiz. Zaten girdiğiniz doğru okunmadığından program "if" döngüsüne girmiyor.
Programın işleyişi şu şekilde; bilgisayardaki seri arayüz programından girilen her karakteri tek tek "ser.read()" ile alıyoruz. Sonra bu karakterleri belirttiğimiz karakterle karşılaştırıp bir döngüye sokuyoruz. Eğer karakterler birbirini tutmuyorsa Orange pi ekranına bu karakter, bu karakterin Ascii, Hex ve Binary karşılıkları yazılacak. Sonra bu karakterin Ascii kodundan '128' çıkarılıp "gelmesi gereken karakter" yazısının altında bu işlem sonucunda çıkan karakter yazılacak.

Seri haberleşme en düşük önemli bitten başlıyordu. Şimdi adım adım gidelim. Bilgisayardaki seri ekranın klavyesinden girdiğimiz 'n' harfi ilk önce ikili(binary) forma dönüştürülüyor.
n = 1101110
Sonra bilgisayardan Orange pi'ye gönderilecek veri hazırlanıyor. Programda eşlenik biti varsayılan değer "none" olduğu için veriye başlangıç ve bitiş bitleri eklenip bu veri paketi başlangıç bitinden sonra en düşük önemli bitten en önemli bite doğru iletilmeye başlıyor. Son olarak bitiş biti de gönderilip bu verinin gönderilme işlemi gerçekleşmiş oluyor.
Bilgisayardan gönderilen veri "data boyutu=7" olduğundan 7 bit(veri biti) + 2 bit(başlangıç-bitiş biti) olarak toplam 9 bitlik veri paketi şeklinde UART'a geliyor. Bu yüzden Orange pi'ye gönderilen veri paketi " 1'1101110'0 " dır.
Şimdi Orange pi tarafına bakalım. Bu veri paketi geldiğinde bunu nasıl değerlendirecek. Önceki yazıdan normalde UART sinyali '1' konumundaydı. Verinin gelmesi için bu çıkışın '0' olması gerekiyordu. Başlangıç bitinden sonra Orange pi programda belirttiğimiz üzere verinin 8 bit olduğunu biliyor ve bu yüzden 8 bit alıp bunu işleyecek. Peki başlangıç bitinden sonraki 8 bit ne? Bitiş bitininde içinde olduğu " 1'1101110" Peki program iletimin bittiğini nasıl anlatacak. Normalde iletim yokken UART çıkışı 1 olduğu için bir sonraki bit de '1' olur ve UART 8 bit aldıktan ve bitiş bitini de aldığı için iletimin gerçekleştiğini düşünür.

Sonuç olarak Orange pi verinin "11101110" olduğunu düşünür. Bu da ASCII kodu olarak 238' e denk geliyor. Bu ASCII kodu da aşağıdaki tabloda görebileceğiniz bir karaktere denk geliyor.
Buradaki karakterler belirsiz karakterler olduğu için ekranda bunlar okunamaz bir karakter olarak gözükecek.
Buraya kadar teorik olarak ne olabileceğini konuştuk. Şimdi bütün bu işlemleri, Orange pi'ye hangi karakterin geleceğini; bu karakterin, "ASCII", "Binary" ve "Hex" karşılıklarını görebileceğimiz bir python dili ile bir program yazalım ve bu adımları görelim.
Bu python ile yazılmış programda programda Orange pi'ye gelen "karakteri", "ASCII " karşılığını, "Hex" karşılığını ve "Binary" karşılığını; ardından normalde yedi bit gelen ama Orange pi' nin sekiz bit olarak aldığı ve bu sekizinci bitin de '1' olduğunu bildiğimiz için bu bitin sekizinci basamaktaki değeri olan '128' kullanarak gelen değerden '128' çıkarıp gelmesi gereken karakteri buluyoruz.
NOT: Hatta bu bilgilerle bir hata programı bile yazılabilir. Eğer alınan karakterin ASCII kodundan '128' çıkardığımızda mantıklı bir değer çıkıyorsa program hata versin ve sorunun muhtemelen veri uzunluğunun uyuşmadığı ile ilgili uyarı mesajı versin. Bu programı önümüzdeki yazıda paylaşacağım.
Normal konumuza dönecek olursak, örnek koda bazı eklemeler yapıp yukarıda bahsettiğim değerleri görüyoruz. Bu sayede veri uzunluğunun programda ne gibi bir sorun çıkarttığını daha iyi anlayabiliyoruz.
Burada programın "else" kısmı ile ilgileneceğiz. Zaten girdiğiniz doğru okunmadığından program "if" döngüsüne girmiyor.
Programın işleyişi şu şekilde; bilgisayardaki seri arayüz programından girilen her karakteri tek tek "ser.read()" ile alıyoruz. Sonra bu karakterleri belirttiğimiz karakterle karşılaştırıp bir döngüye sokuyoruz. Eğer karakterler birbirini tutmuyorsa Orange pi ekranına bu karakter, bu karakterin Ascii, Hex ve Binary karşılıkları yazılacak. Sonra bu karakterin Ascii kodundan '128' çıkarılıp "gelmesi gereken karakter" yazısının altında bu işlem sonucunda çıkan karakter yazılacak.
Burada görüldüğü üzere aslında gelen verinin hangi karaktere denk olduğu görülüyor. Bu karakterin neden böyle olduğunun açıklaması da yukarıda mevcut.
Peki "ser.write" ile Orange pi'den bilgisayara bir çok karakter hatta bu karakterlerden cümle gönderiyoruz. Burada niye sıkıntı çıkmıyor? Bu soruyu da aynı şekilde gönderilen karakterlere ve veri paketinin ne olduğuna bakıp yorum yapalım.
Bunun ilk nedeni Orange pi'den bilgisayara gönderdiğimiz karakterlerini hepsi "ASCII" karşılığı 128'den küçük olan karakterler. Bu ne demek peki? Yani bu karakterlerin "binary" karşılığı en fazla 7 bit oluyor. Tabi Orange pi' bunları başlarına '0' koyu yine 8 bit olarak gönderiyor ama bilgisayar aldığını verinin 7 bit olduğunu düşündüğü için sadece 7 bitini alıyor. Bu yüzden Orange pi'den gönderilen karakterler bir bozukluğa uğramıyor.
Fakat "ASCII" kodu 128'den fazla olan karakterler için durum değişiyor. Bu demek oluyor ki bu karakterlerini "binary" karşılığında 8 bit var ve sekizinci bit '1'. Yani bilgisayar 7 bit aldıktan sonra sekizinci biti '1' gördüğünden veri bitinin bittiğini sanıyor. Tabi bu herhangi bir '1' biti değil. yedinci bitten sonraki '1' biti. Eğer biz veri uzunluğu 8 olarak belirtmiş olsaydık sekizinci bitten sonraki '1' bitine dikkat edecektik. Bilgisayardan Orange pi'ye veri gönderirken yaşadığımız durumun sebebi de bu. Orange pi ilk önce 8 bitini alıyor. Sonra bitiş bitine bakıyor.
"ASCII" kodu olarak klavyeden gireceğim karakterler var. Örneğin "ü" harfi "ASCII" kodu olarak '129' a eşit fakat bundan 128 çıkınca ortaya çıkacak karakter bizim gözle görebileceğimiz bir şey ifade etmediğinden ne olduğunu anlamak güç oluyor. Daha büyük ASCII koduna denk gelen karakter de klavyede mevcut olmadığı için direk girdiğimiz sayıyı sanki ASCII koduymuş gibi karaktere dönüştürebiliriz. Örneğin "sayi3" değişkeni tanımlıyoruz. Bu değişkene '235' sayısını atayıp bunu "chr(sayi3)" ile bilgisayara gönderiyoruz ve ne yazıldığını gözlemliyoruz.
Yine düşünecek olursa '235' ASCII kodu binary olarak '11101011' a eşit. Biz bu veriyi gönderdiğimizde başlangıç ve bitiş bitlerini ekleyip gönderiyoruz ve veri paketi "1'11101011'0" oluyor. Bu veri paketi bilgisayara ulaştığında 7 biti alınıp veri '1101011' olarak tanımlanıyor. Bu da karakter olarak 'k' harfine denk geliyor. Yani biz Orange pi'den 235 ASCII kodunun karşılığını yazmak üzere bilgisayara gönderildiğinde bilgisayarda gönderdiğimiz veri 'k' olarak yazılıyor.

Parity biti tanımlamasını iki cihazda farklı olması
Değineceğimiz bir başka parametre ise “parity biti”. Biz kodda herhangi bir parity biti tanımlamadık (varsayılan - none) ama seri ekranda tanımlarsak ne olur?Burada örnekleri göstermeden önce bu durumu şöyle açıklayabiliriz. Seri haberleşmeden bahsederken “ bitiş bitinin” '1' olduğundan bahsetmiştim. Yani parity biti '1' olursa ve biz de parity biti tanımladığımız için program verinin bittiğini ve o '1' bitinin bitiş biti olduğunu algılayacak. Eğer” parity biti“ “0” olursa, biz de veri parity bitini belirtmediğimiz için program o “0” bitini de veri kabul edecek ve sanki iki tane veri girilmiş gibi davranacak.
Parity bitini “even“ diye belirtirsek burada "even parity
biti" , veri bitindeki '1' bitinin sayısını çift sayı yapmaya çalışır.
y= 121(ASCII)=01111001, burada even parity biti '1' olur.
n=110(ASCII)=01101110, burada da even parity biti '1' olur.
Bilgisayardaki seri ekranda parity bitini “even” ayarlayıp
Orange pi’ de parity biti ayarlamaz isek, bilgisayar veri gönderirken verinin
sonuna parity biti ekler ama Orange pi veri alırken parity bitini dikkate almaz
ve yukarıda anlattığım duruma göre onu “bitiş biti” sanabilir.
Even parity bitleri farklı olsun diye kodda "y" karakteri
yerine ''c'' karakterini kullandım.
c=99(ASCII)=01100011, burada even parity biti '0' olur.
Haberleşmeyi başlattığımız an programın başında çıkan yazılar parity biti farkında dolayı zaten karışık-anlaşılmaz çıkar.
Daha sonrasında “n”
karakterini girdiğimizde PC=>Orange pi giderken bu
veriye parity biti olarak “1” ekleniyor. Fakat sıra bu bite geldiğinde Orange
pi bu “1” bitini bitiş biti sanacak ve
ona gelen veri “n” karakterinin verisi olduğu için ekrana “ No denildi “
yazdıracak.
“c” karakterini girdiğimizde PC=>Orange pi’ ye veri giderken
sonuna parity biti olarak “0” ekleniyor. Orange pi 8 bit veriden sonra bitiş
biti de algılamadığı için veri akışının devam ettiğini sanıyor. Yani sondaki
“0” bitini Orange pi yeni bir veriymiş gibi görüyor. Bu yüzden orada ilk 8 bit
“c” karakterini veriyor sonraki “0” biti ise “c” veya “n” karakterlerinden biri
olmadığı için “belirlenemeyen karakter girişi” diye uyarı mesajı yazdırılıyor.
Eğer Orange pi’ de herhangi bir parity bit belirtmezsek ve
bilgisayarda “odd” parity girersek bu sefer tam tersi olur. Bunu da aşağıdaki fotoğrafta görebilirsiniz.
Sonuç olarak, haberleşmenin düzgün gerçekleşmesi için parametrelerin her iki cihazda da aynı olması gerekiyor.
Bu yazıda ASCII - BINARY - HEX dönüşümleri için kullandığım siteler:
- http://www.asciitable.com/
- https://www.rapidtables.com/convert/number/decimal-to-binary.html
- https://mothereff.in/binary-ascii
- https://sametcelikbicak.wordpress.com/2010/05/14/asciichr-ve-binary-karakter-set-tablosu/
Bu yazı biraz uzun ve bir bütün olduğu için bilgisayarlarda kullanılan seri haberleşme arayüz programlarına değinmedim. Bir sonraki yazıda bu programlardan bahsedeceğim.
Okuduğunuz için teşekkür ederim. Aklınıza takılan bir soru veya karşılaştığınız bir sorun olduğunda yorumlarda belirtebilirsiniz. Burada eksik olarak anlattığımı düşündüğünüz veya sizlerin gerekli olarak gördüğünüz bilgileri yine yorumlarda yazarsanız, bundan herkesin faydalanmasını sağlamış olursunuz. Herkese iyi çalışmalar.
Hiç yorum yok:
Yorum Gönder