0% found this document useful (0 votes)
8 views36 pages

Arduino 401

Uploaded by

frmnyasi
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views36 pages

Arduino 401

Uploaded by

frmnyasi
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

ARDUİNO 301

(Başlangıç seviyesi
derslerde Arduino uygulama
geliştirme ortamını detaylı
olarak inceliyoruz )
.
Arduino ile Interrupt (Kesmeler)
Kesme anlamına gelen Interrupt, birden fazla işlemin yapıldığı projelerde sıklıkla kullanılan bir
özelliktir. Interrupt, Arduino'nun çalışması sırasında veya dışarıdan bir etkiyle meydana gelen
olaylara otomatik olarak tepki vermesidir. Interrupt sayesinde Arduino sürekli beklenen olayın
gerçekleşip gerçekleşmemesini beklemez. Arduino, başka görevleri yerine getirirken bu olay
gerçekleştiğinde, otomatik olarak bu olaydan haberdar olur.

Diyelim ki Arduino'nun Interrupt özelliği bulunan bir düğmesine basıldığında bilgisayara veri
yollamak istiyoruz. Bunu kolay bir şekilde loop fonksiyonunun içine yazacağımız kodlar ile
yapabiliriz. Fakat Arduino'nun bu projedeki tek görevi bu olmayabilir. Arduino başka işlemler
yaparken kullanıcı düğmeye basabilir. Böyle bir durumda Arduino düğmeye basıldığını
anlayamayacaktır.

Böyle bir hatanın önüne geçilmesi için Interrupt kullanılmalıdır. Düğmeye atanacak bir Interrupt,
Arduino başka bir işlem yapmakta olsa bile, düğmeye basıldığı gibi Arduino'ya haber verecektir.
Arduino düğmeye basıldığında yapılması gereken işlemleri yaptıktan sonra, kaldığı yerden diğer
işlemlere otomatik olarak geri dönecektir.

Arduino'da farklı görevlerde kullanılmak üzere çeşitli Interrupt'lar (kesmeler) bulunur. Zaman
kesmesi (timer interrupt) ve dış kesmeler (external İnterrupt) en yaygın olarak kullanılan Arduino
kesmeleridir.

Zaman Kesmesi (Timer Interrupt)


Zaman kesmesi (timer interrupt), belirli süre aralıklarında belirli görevlerin yapılabilmesi için
kullanılır. Örneğin bir LED'in saniyede bir yakıp söndürülmesi gerekmektedir. Bu işlem için loop
fonksiyonunun kullanılması yerine, zaman kesmesinin kullanılması Arduino programının
rahatlamasını sağlayacaktır. Kullanılan kesme her saniyede bir Arduino'ya haber vererek, LED'in
yakılıp söndürülmesini sağlayacaktır.

Zaman kesmelerinin ayarlanabilmesi için bazı program değişkenlerinin ayarlanması gerekir.


Bunlardan en önemlisi zaman sayıcısıdır. Bu değişkende tutulan değer, her saat darbesinde bir
artar. Taşma değerine ulaştığında sıfırlanır ve Arduino'ya sürenin dolduğunu, kesmenin yapılması
gerektiğini bildirir. Bu değişkenin başlangıç değeri ayarlanarak, kesmeler arasındaki geçecek
zaman ayarlanabilir.

Farz edelim ki, 8 bitlik zaman sayıcısının ilk değeri 50 olarak belirlendi. Her adımda bu değer bir
artırılacaktır. Zaman sayıcısının değeri 255 olduktan bir adım sonra sıfırlanacaktır. Bu noktada
zaman kesmesi gerçekleşecektir. Kesme gerçekleştiğinde Arduino otomatik olarak
"ISR(TIMERx_COMPA_vect)" fonksiyonunu çalıştıracaktır. Bu fonksiyonun içerisine her kesmede
yapılması istenilen görevler yazılır.
Zaman kesmesinin ne kadar sürede bir gerçekleşeceği, her adımın ne kadar sürede
gerçekleşeceğiyle de alakalıdır. Bu süre Arduino'nun kristalinin 1, 1/8, 1/64, 1/256 ve 1/1024
oranında olması sağlanabilir. Zaman kesmesinin oluşma süresi aşağıdaki formül ile
hesaplanabilir.

Zaman kesmesi kullanarak Kara Şimşek devresi


Zaman kesmesinin ne olduğunu ve nasıl ayarlandığını öğrendiğimize göre, bilgilerimizi
pekiştirmek için bir örnek yapalım. Bu örnekte, ilk uygulamalarımızda yaptığımız Kara Şimşek
devresini zaman kesmesi kullanarak yapacağız. Önceki uygulamada Kara Şimşek loop
fonksiyonu içerisinde yapılmıştı. Bu projede Arduino'nun tüm gücü LED'leri kontrol etmek için
kullanılmıştı. Eğer başka bir işlem yapılmak istenseydi, Arduino yetersiz kalabilirdi.

Bu projede ise LED'ler zaman kesmesi ile belirli sürelerde otomatik olarak yapılacağı için, Arduino
başka işlemleri de rahatça yapabilecek.

Bu uygulamayı yapmak için ihtiyacımız olan malzemeler:

 1 x Arduino
 8 x LED
 8 x 220 Ohm direnç
 1 x Breadboard
const int LEDdizisi[] = {2,3,4,5,6,7,8,9};
int j = 0;

void setup()
{
[Link](9600);

for(int i=0; i<8 ;i++)


{ /* For döngüsüyle LEDdizisi elemanlarına ulaşıyoruz */
pinMode(LEDdizisi[i], OUTPUT); /* LED pinleri çıkış olarak ayarlandı
*/
}
cli();
/* Ayarlamaların yapılabilmesi için öncelikle kesmeler durduruldu
*/

/* Timer1 kesmesi saniyede bir çalışacak şekilde ayarlanacaktır (1


Hz)*/
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 15624;
/* Bir saniye aralıklar için zaman sayıcısı ayarlandı */
TCCR1B |= (1 << WGM12);
/* Adımlar arasında geçen süre kristal hızının 1024'e bölümü olarak
ayarlandı */
TCCR1B |= (1 << CS12) | (1 << CS10);
TIMSK1 |= (1 << OCIE1A);
/* Timer1 kesmesi aktif hale getirildi */
sei();
/* Timer1 kesmesinin çalışabilmesi için tüm kesmeler aktif hale
getirildi */
}
/* Arduino otomatik olarak her saniye aşağıdaki fonksiyonu
çalıştıracaktır */
ISR(TIMER1_COMPA_vect){
for(int i=0; i<8; i++){
digitalWrite(LEDdizisi[i],LOW);
/* Tüm LED'ler söndürüldü */
}
digitalWrite(LEDdizisi[j],HIGH);
/* Sıradaki LED yakıldı */
j ++;
if(j > 7)
j = 0;
}
void loop()
{
[Link]("Arduino burada baska islemler yapabilir");
delay(100);
}
Yukarıdaki Arduino programında "LEDdizisi" değişkeninde Arduino'ya bağlanan LED'lerin pinleri
kaydedildi. Setup fonksiyonu içinde bu LED pinleri çıkış olarak ayarlandı. Programın başka işler
de yapabildiğini gösterebilmek için loop fonksiyonu içinde seri monitöre mesaj yazdırıldı. Bunun
için setup fonksiyonunda seri haberleşme başlatıldı. Zaman kesmesinin açılması ve saniyede bir
görev yapılabilmesi için setup fonksiyonu içerisinde Timer1 ayarlandı.

Zaman kesmesi saniyede bir "ISR(TIMER1_COMPA_vect)" fonksiyonunu çalıştırır. Bu


fonksiyonun içinde LED'lerin sırayla yanmasını sağlayacak kodlar yazıldı. Bu kodlarda öncelikle
tüm LED'ler sönük konuma getirilir, daha sonra sadece yanması gereken LED yakılır.

Dış Kesmeler (External interrupt)


Arduino projelerinde sıkça kullanılan diğer bir kesme çeşidi de dış kesmelerdir. Dış kesmeler,
Arduino'nun özel pinlerinde gerçekleşen voltaj değişimlerini takip eden kesmelerdir. Örneğin
Arduino'nun dış kesme pinine bağlanmış bir düğmeye basıldığında, dış kesme Arduino'ya
otomatik olarak haber verir. Bu kesme sayesinde Arduino sürekli olarak düğmeye basılıp
basılmadığını kontrol etmek zorunda kalmaz, bu sırada başka işlemleri yerine getirebilir.

Dış kesmelere sahip pinler Arduino türüne göre değişiklik gösterir. Aşağıdaki tabloda Arduino
türlerine göre dış kesme özelliğine sahip pinler gösterilmiştir.

Arduino Türü Int.0 Int.1 Int.2 Int.3 Int.4 Int.5

Arduino Uno 2 3 - - - -

Arduino Mega 2 3 21 20 19 18

Arduino Leonardo 3 2 0 1 7 -

Kullanılacak dış kesme pini, setup fonksiyonu içerisinde "attachInterrupt" fonksiyonu ile
belirtilmeli. Bu fonksiyonun içinde kullanılacak olan pinin numarası değil, kesme numarası girilir.
Örneğin Arduino Uno kullanıcısı 2. pindeki kesmeler için 0, 3. pindeki kesmeler için 1 değerini
kullanmalıdır. "attachInterrupt" fonksiyonun ikinci değeri kesme durumunda çalışacak fonksiyonu
belirler, üçüncü değer hangi durumlarda kesmenin gerçekleşeceğini belirler.

Aşağıda "attachInterrupt" fonksiyonu için tanımlanabilecek dış kesmelerin türleri belirtilmiştir.

 LOW: Pindeki voltaj 0 ise kesme oluşur.


 CHANGE: Pinde oluşacak voltaj değişimlerinde kesme gerçekleşir.
 RISING: Yükselen kenarlarda kesme gerçekleşir. Yani pindeki voltaj değeri 0'dan 5 Volta
çıktığında kesme gerçekleşir.
 FALLING: Düşen kenarlarda kesme gerçekleşir. Yani pindeki voltaj değeri 5'ten 0'a
düştüğünde kesme gerçekleşir.
Örneğin Arduino Uno'nun 2. pinine düğme bağlamış olalım. Bu düğmeye basıldığında
"butonaBasildi" fonksiyonunun çalışmasını istemekteyiz. Bunun için setup fonksiyonunun içerisine
attachInterrupt (0, butonaBasildi, RISING) yazmamız gerekir. Böylece düğmeye her basıldığında
"butonaBasildi" fonksiyonu otomatik olarak çalışır.

Dış kesmeler ile düğme kontrollü LED


Bu uygulamada dış kesme özelliğinden faydalanarak düğme kontrolü yapılır. Düğmeye
basıldığında Arduino'nun 5. pinine bağlanmış olan LED yakılır. Kullanıcı düğmeden elini
çektiğinde yine dış kesme kullanılarak, LED otomatik olarak söndürülür. Dış kesme kullanılması
Arduino'nun sürekli düğme durumunu kontrol etmek zorunda kalmasını engeller. Düğmeye
basıldığında veya düğmeden el çekildiğinde, Arduino otomatik olarak anlar. Böylece Arduino
düğmeyi kontrol etmeden diğer işlemleri yerine getirebilir.

Bu uygulamayı yapmak için ihtiyacımız olan malzemeler;

 1 x Arduino
 1 x düğme
 1 x 10K ohm direnç
 1 x LED
 1 x 220 ohm direnç
 1 x Breadboard
int LED = 5;
/* LED'in bağlı olduğu pin 5 olarak belirlendi */

void setup()
{
pinMode(LED, OUTPUT);
/* LED çıkış olarak ayarlandı */

attachInterrupt(0, LEDiyak, RISING);

/* 0 dış kesmesi ayarlandı. Yani Arduino Uno için dugme 2. pine


bağlanmalıdır */

[Link](9600);
}

void loop()
{
[Link]("Arduino burada baska islemler yapabilir");
delay(100);
}

void LEDiyak()
{
/* Dugmeye basıldığında çalışacak fonksiyon */
digitalWrite(LED,HIGH);
attachInterrupt(0, LEDisondur, FALLING);
}

void LEDisondur()
{
/* Dugmeden el çekildiğinde çalışacak fonksiyon */
digitalWrite(LED,LOW);
attachInterrupt(0, LEDiyak, RISING);

Arduino kodunda öncelikle LED'in bağlanacağı pin, 5 olarak belirlenmiş ve bu pin çıkış olarak
ayarlanmıştır. Devrede düğme, 2. pine bağlanmıştır. Bu pin 0. dış kesmeye karşılık gelmektedir
(Arduino Uno için). Düğmeye basıldığında ve düğmeden el çekildiğinde, Arduino farklı kesmelere
girmekte ve LED'in konumunu değiştirir.

Setup fonksiyonu içinde düğmeye basıldığında yapılacak olan görev tanımlandı. Bu alanda
düğmeden çekilince yapılacak görevin tanımlanmama nedeni, Arduino'nun aynı anda sadece bir
adet dış kesme görevi atayabilmesidir. Bu yüzden 'LEDiyak' ve 'LEDisondur' fonksiyonlarında dış
kesme fonksiyonları tekrar tanımlandı.

Zaman ve dış kesmelerin nasıl kullanıldığını öğrendik. Kapsamlı projelerde bu kesmeler


kullanılarak Arduino üzerindeki yük azaltılabilir ve projenin daha sağlıklı çalışması sağlanabilir.
I2C Protokolü
Arduino, diğer Arduino veya sensörlerle haberleşmek için bazı haberleşme protokolleri kullanır. Bu protokollerden
birisi de I2C'dir. I2C (Inter-Integrated Circuit), seri haberleşme türlerinden senkron haberleşmeye bir örnektir.
Haberleşme için toprak hattı dışında SDA ve SCL olmak üzere iki hatta ihtiyaç duyulmaktadır. Hat sayısının fazla
olması nedeniyle, uzun mesafeli haberleşmelerde tercih edilmez. Genellikle kısa mesafeli ve düşük veri aktarım
hızının yeterli olduğu yerlerde kullanılır.

I2C haberleşmesinde, haberleşmeyi kontrol eden master cihazı bulunur. Her haberleşmede bir tane master
bulunmalıdır. Haberleşmenin sağlanabilmesi için haberleşme hattına en az bir adet slave (köle) cihaz
bağlanmalıdır. Hatta bağlanan birden fazla slave cihazlardan hangisinin veri aktaracağına, master cihaz karar
verir. Böylece hat sayısında bir değişiklik olmadan birden fazla cihazla haberleşme sağlanır.

Master ve slave cihazların aynı besleme hattına bağlanmasına gerek yoktur. Fakat iletişimin sağlanması için
toprak hatlarının aynı olması gerekir. Bunun yanında veri aktarımı için SDA (Serial Data Line) ve SCL (Serial
Clock) olmak üzere iki adet haberleşme hattı bulunur. Bu hatlardan SDA, cihazlar arasındaki veri aktarımının
sağlandığı hattır. Bu hatta çift yönlü veri aktarımı olur. Hatta aktarılan verilerin senkronizasyonu, SCL hattı
tarafından gerçekleştirilir. SCL hattında master cihaz tarafından üretilen saat sinyali bulunur. SDA hattındaki
haberleşme, bu sinyale göre düzenlenir.

Haberleşmenin tüm hat boyunca hatasız bir şekilde sağlanabilmesi için SDA ve SCL hatları, pull-up
dirençlerle VCC hattına bağlanmalıdır. SDA ve SCL pinleri, kullanılan Arduino türüne göre değişiklik
göstermektedir. Arduino türlerine göre SDA ve SCL pinleri aşağıdaki tabloda gösterilmiştir .

Arduino türü SDA pini SCL pini

Arduino Uno A4 A5

Arduino Mega 20 21

Arduino Leonardo 2 3

Arduino Due 20 21

Arduino Nano A4 A5
I2C Fonksiyonları
I2C haberleşme protokolünün çalışma şeklini ve bağlantı hatlarını öğrendiğimize göre,
Arduino'nun I2C haberleşmesini yapabilmesi için kullanmamız gereken fonksiyonları
tanıyalım. Bu fonksiyonlar Arduino'nun "Wire.h" kütüphanesi içerisinde bulunmaktadır. Bu
yüzden öncelikle bu kütüphaneyi projemize dâhil etmeliyiz.

 [Link](): I2C haberleşmesini başlatan fonksiyondur. Bu fonksiyon parametre


olarak slave cihazın adresini alır. Eğer cihaz master olarak tanımlanacak ise bu
fonksiyona herhangi bir parametre atanmaz. Örneğin haberleşme hattında '1'
adresine sahip slave bir Arduino tanımlanmak isteniyorsa, [Link](1); yazılır. Eğer
bu Arduino haberleşme hattının master cihazı olarak tanımlanmak istenseydi
fonksiyon, [Link](); olarak çağırılmalıydı.
 [Link](): Fonksiyon hat üzerinden Arduino'ya ulaşmış veri paketlerinin
sayısını döndürür. Eğer fonksiyonun değeri 0'dan büyükse Arduino'ya gelen yeni veri
paketi vardır.
 [Link](SlaveAdresi): Master cihazın hat üzerinde bulunan slave
cihazlardan hangisiyle haberleşmek istediğini belirler. Fonksiyon, parametre olarak
haberleşmeye başlayacağı cihazın adresini alır.
 [Link](): Hat üzerindeki veri aktarımının sonlandığını belirtir.
 [Link](): Veri hattından gelen verinin okunmasını sağlar.
 [Link](): Fonksiyona yazılan parametreyi veri hattına aktarır. Kısaca veri
yollamak için kullanılır.
 [Link](GorevFonksiyonu): Slave olarak tanımlanmış cihaza veri
geldiğinde, cihazın yapacağı işlemi belirleyen fonksiyondur. Fonksiyon parametre
olarak veri geldiğinde, çağırılacak fonksiyonun ismini alır.
 [Link](): Master tarafında kullanılan bu fonksiyon ile slave cihazdan veri
istenir. Fonksiyonun ilk parametresi, slave cihazın adresini belirler. İkinci parametre
ise slave cihazdan kaç byte'lık veri beklendiğini belirler. Üçüncü ve son parametre ise
hattın istekten sonraki durumunu belirler.
 [Link](): Slave tarafında kullanılan bu fonksiyon, master cihazdan veri
isteği geldiğinde çalıştırılacak fonksiyonu belirler. Bu fonksiyon parametre olarak
çalıştırılacak fonksiyonun ismini alır.

I2C ile iki Arduino Arasında Veri Aktarımı


I2C bağlantı şemasını ve kullanılacak fonksiyonları öğrendiğimize göre, artık küçük bir örnek ile
I2C'yi daha iyi anlayabiliriz. Bu örnekte iki adet Arduino Uno kullanılacaktır. Arduino Uno'lardan
birisi master birisi de slave görevinde bulunacaktır.

Master görevindeki Arduino, slave görevindeki Arduino'ya bağlı LED'leri kontrol edecek ve slave
görevindeki Arduino'dan veri alacak. Slave görevindeki Arduino, master görevindeki Arduino'dan
gelen veriyi yorumlayacak. Gelen veriye göre de LED'leri kontrol edecek ve diğer Arduino'ya veri
yollayacak.
Bu uygulamayı yapmak için ihtiyacımız olan malzemeler:

 2 x Arduino
 2 x 4.7K ohm direnç
 1 x LED
 1 x 220 ohm direnç
 1 x Breadboard

Not: Devredeki iki Arduino'da ayrı ayrı veya aynı besleme kaynağından beslenmelidir. Eğer
Arduino'lar ayrı kaynaklardan besleniyorsa, toprak hatlarının birleştirilmesi gerektiğini unutmayın.
Slave üzerinden gelen mesajları okumak için Master görevindeki Arduino'yu bilgisayara
bağlayarak Seri Monitörü açın.

Master görevindeki Arduino kodu:


/* I2C haberleşmesinde Master olarak görev yapan Arduino kodu */

#include <Wire.h>
/*
* I2C fonksiyonlarını kullanabilmek için
* Wire.h kütüphanesini projemize ekledik
*/
void setup()
{
[Link]();
/* I2C haberleşmesi master olarak başlatıldı */

[Link](9600);
/* Bilgisayara veri yazdırabilmek için seri haberleşme başlatıldı
*/
}

void loop()
{
[Link](1);
/* 1 adresine sahip Slave (köle) cihazına veri yollanacağı
bildiriliyor */
[Link]("a");
/* a karakteri slave cihaza yollanıyor */
[Link]();
/* Yollanacak verilerin bittiği bildiriliyor */
/* a karakteri slave cihazda LED'i yak anlamına gelecektir */

delay(1000);

[Link](1);
/* 1 adresine sahip Slave (köle) cihazına veri yollanacağı
bildiriliyor */
[Link]("b");
/* b karakteri slave cihaza yollanıyor */
[Link]();
/* Yollanacak verilerin bittiği bildiriliyor */
/* b karakteri slave cihazda LED'i sondur anlamına gelecektir */

delay(1000);

[Link](1,
7);
/* 1 adresine sahip slave (köle) cihazından 7 BYTE'lık veri
bekleniyor */
char gelenKarakter;
/* I2C hattından gelen veriler gelenKarakter değişkenine
yazdırılacak */
while([Link]()){
/* I2C hattında yeni veri olduğu sürece döngü devam edecek */
gelenKarakter = [Link]();
/* I2C hattından gelen veriler okunuyor */
[Link](gelenKarakter);
/* Gelen veriler ekrana yazdırılıyor */
}
[Link]();

delay(1000);
}
Master görevindeki Arduino kodunda öncelikle I2C fonksiyonlarının kullanılabilmesi için Wire.h
kütüphanesi çalışmaya dahil edilmiştir. Daha sonra haberleşme [Link]() komutuyla master
olarak başlatıldı. Slave cihazdan gelecek verilerin ekrana yazdırılabilmesi için [Link](9600)
komutu ile Arduino ve bilgisayar arasındaki iletişim başlatıldı.

Loop fonksiyonu içinde, bir saniye aralıklarla slave cihaza 'a' ve 'b' karakterleri yollandı. Bu
karakterler slave cihazda işlenerek LED'in konumu değiştirilecek. Bu karakterlerin yollanabilmesi
için öncelikle [Link](1) fonksiyonuyla hangi slave cihaza veri aktarılacağı
seçildi. Tüm veriler cihaza yollandıktan sonra [Link](); komutuyla cihaza veri
aktarımının bittiği bildirildi.

Slave cihazdan veri alınmak istendiği için [Link](1, 7); komutu kullanıldı. Bu komutla
slave cihaz 7 byte'lık veriyi master cihaza aktaracağını anladı. Yeni veri geldiği sürece işlemin
devam edebilmesi için, while döngüsünün koşulu [Link]() yapılır. I2C data hattından
gelen veriler [Link]() fonksiyonuyla okunarak seri porta yollandı.

Slave görevindeki Arduino kodu


/* Slave (köle) görevindeki Arduino'nun kodu */
#include <Wire.h>
/*
* I2C fonksiyonlarını kullanabilmek için
* Wire.h kütüphanesini projemize ekledik
*/

const int LED = 13;


/* LED 13. pinde bulunmaktadır */

void setup()
{
[Link](1);
/* I2C haberleşmesi, haberleşme adresi 1 olan bir slave cihaz
olarak başlatıldı */
[Link](istekGeldiginde);
/*
Master olan cihaz bu Arduino'dan veri istediğinde gerçekleşecek
işlem seçildi
*/
[Link](veriGeldiginde);
/*
Master olan cihazdan bu Arduino'ya veri geldiğinde yapılacak işlem
seçildi
*/
pinMode(LED,OUTPUT);
/* LED pini çıkış olarak ayarlandı */
}
void loop()
{
/*
* Tüm işlemler veri isteği geldiğinde veya yeni veri geldiğinde
* yapılacağı için loop fonksiyonunun içi boş bırakılmıştır
*/
delay(1);
}
void veriGeldiginde(int veri)
{
/* I2C hattında bu cihaz için yeni veri olduğunda bu fonksiyon
çalışır */
char gelenKarakter;
/* Hattaki veri okunarak gelenKarakter değişkenine kaydedilir */
while([Link]()){
gelenKarakter = [Link]();
}
/* Eğer gelen veri 'a' ise LED yakılır, 'b' ise LED söndürülür */
if(gelenKarakter == 'a')
digitalWrite(LED,HIGH);
else if(gelenKarakter == 'b')
digitalWrite(LED,LOW);
}
void istekGeldiginde()
{
/*
* Eğer master bu cihazdan veri istiyor ise master cihaza "Merhaba"
verisi yollanılır
* Eğer bu bir sensör olsaydı "merhaba" yerine sıcaklık veya ivme
verisi yollanıyor olacaktı
*/
[Link]("Merhaba");
}
Slave görevindeki Arduino kodunda öncelikle I2C fonksiyonlarının kullanılabilmesi için Wire.h
kütüphanesi çalışmaya dâhil edildi. Daha sonra haberleşme [Link](1) komutuyla 1 adresine
sahip slave cihaz olarak başlatıldı. Master cihazından veri geldiğinde "veriGeldiginde()"
fonksiyonu, istek geldiğinde "istekGeldiginde()" fonksiyonunun çalışması için
"[Link](veriGeldiginde)" ve "[Link](istekGeldiginde)" fonksiyonları kullanıldı.

Programın ana yapısı bu iki fonksiyon ile çalışır. Arduino'ya master cihazdan yeni veri geldiğinde
bu veri okunarak 'gelenKarakter' değişkenine yazdırılır. Gelen karakter eğer 'a' harfine eşitse LED
yakılır, 'b' harfine eşitse LED söndürülür. Eğer master cihazdan veri isteği geldiyse, master cihaza
"Merhaba" yazısı geri döndürülür. Eğer bu Arduino bir sensör olsaydı, burada "Merhaba" yazısı
yerine ortam sıcaklığını veya ivme verisini döndürecekti.

İki Arduino arasında I2C ile nasıl haberleşme ağı kurulacağını öğrendik. I2C sadece mikro
denetleyiciler arasında haberleşmeyi sağlamaz, aynı zamanda sensörlerle de haberleşmeyi
sağlar. Bir hat üzerine bağlanmış birden fazla sensör, Arduino tarafından kolaylıkla okunabilir.
Böylece sensör sayısı artmasına rağmen devredeki karmaşıklık ve kablo sayısı artmamış olur.
Arduino ile IMU Kullanımı
Bu uygulamada I2C haberleşme protokolünü destekleyen MPU-6050 IMU kartının üzerinde
bulunan sensörlerle sıcaklık ivme ve cayro değerlerini ölçeceğiz. Bu sensörler yerine aynı görevi
yapan farklı sensörler de kullanabilirsiniz. Öncelikle kullanacağınız sensörün datasheet'ini yani
belirtimini okuyarak sensörün I2C adresini ve veri isteme şeklini öğrenmelisiniz.

Bu projede kullanacağımız kart, çeşitli görevler için özelleştirilmiş bir IMU kartıdır. IMU ivme,
basınç, cayro gibi sensörleri üzerinde bulunduran sensör kartıdır. MPU-6050 elektronik ve robot
malzemeleri satan yerlerde kolayca bulunabilir. Ucuz olması ve kolay kullanımından dolayı bu
kart seçilmiştir.

MPU-6050'nin belirtimi (datasheet) incelendiğinde görüldüğü gibi, cihazın I2C haberleşme adresi
0x68'dir. Buradan sensörler hakkında daha fazla bilgi de edilinebilir.

Bu uygulamayı yapmak için ihtiyacımız olan malzemeler:

 1 x Arduino
 2 x 4.7K ohm direnç
 1 x MPU-6050
Slave görevindeki Arduino kodu
/* MPU-6050 ile I2C haberleşme örneği */
#include<Wire.h>
/*
* I2C fonksiyonlarını kullanabilmek için
* Wire.h kütüphanesini projemize ekledik
*/

const int MPU=0x68;


/* MPU-6050'nin I2C haberleşme adresi */

int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
/* IMU'dan alınacak değerlerin kaydedileceği değişkenler */

void setup(){
[Link]();
[Link](MPU);
[Link](0x6B);
[Link](0); /* MPU-6050 çalıştırıldı */
[Link](true);
/* I2C haberleşmesi başlatıldı ve MPU-6050'nin ilk ayarları yapıldı
*/
[Link](9600);
}
void loop(){
verileriOku();
/* IMU'dan değerler okundu */

/* Okunan değerler serial monitör'e yazdırılıyor */


[Link]("ivmeX = "); [Link](AcX);
[Link](" | ivmeY = "); [Link](AcY);
[Link](" | ivmeZ = "); [Link](AcZ);
[Link](" | Sicaklik = "); [Link](Tmp/340.00+36.53);
/* Datasheetten alınan sıcaklık hesaplama formülü kullanıldı */
[Link](" | GyroX = "); [Link](GyX);
[Link](" | GyroY = "); [Link](GyY);
[Link](" | GyroZ = "); [Link](GyZ);
delay(333);
}

void verileriOku(){
[Link](MPU);
/* I2C haberleşmesi yapılacak kart seçildi */
[Link](0x3B);
/* 0x3B adresindeki register'a ulaşıldı */
[Link](false);
[Link](MPU,14,true);
/* 14 BYTE'lık veri istendi */
AcX=[Link]()<<8|[Link]();
AcY=[Link]()<<8|[Link]();
AcZ=[Link]()<<8|[Link]();
Tmp=[Link]()<<8|[Link]();
GyX=[Link]()<<8|[Link]();
GyY=[Link]()<<8|[Link]();
GyZ=[Link]()<<8|[Link]();
/*
* Sırası ile okunan her iki byte birleştirilerek sırası ile
değişkenlere yazdırıldı
* Böylece IMU'dan tüm değerler okunmuş oldu
* 0X3B adresi imu değerlerinden ilk sensörün değerine denk
gelmektedir.
* IMU'dan tüm değerlerin okunabilmesi için bu adresten başlandı
*/
}
Böylece I2C ile sensörlerden nasıl veri alacağımızı, iki Arduino'yu nasıl konuşturacağımızı
öğrendik. I2C, birden fazla sensörün kullanıldığı devrelerde, sensörlerin ve Arduino'nun
birbirinden fazla uzakta bulunmadığı projelerde sıklıkla kullanılır.

SPI Protokolü
SPI (Serial Peripheral Interface), Arduino'nun desteklediği senkron seri haberleşme türlerinden
biridir. Özellik ve kullanım olarak I2C'ye benzer. Bir Arduino'nun diğer Arduino veya sensörlerle
kısa mesafede haberleşmesini sağlar. SPI protokolünde de I2C'de olduğu gibi bir adet Master
cihaz bulunur. Bu cihaz hatta bağlı çevresel cihazları kontrol eder.

Master ve çevresel cihazlara bağlanan MISO (Master In Slave Out), MOSI (Master Out Slave In)
ve SCK (Serial Clock) olmak üzere üç adet SPI hattı bulunur.

 MISO: Çevresel cihazlardan (slave) yollanan verilerin master cihaza aktarıldığı hattır.
 MOSI: Master cihazdan yollanan verilerin çevresel cihazlara aktrıldığı hattır.
 SCK: SPI haberleşmesinde senkronu sağlayan saat sinyalinin bulunduğu hattır. Saat
sinyali master cihaz tarafından üretilir.

MISO ve MOSI hatlarından da anlaşıldığı gibi SPI protokolünde I2C'den farklı olarak veri hatları
tek yönlüdür. Ayrıca çevresel cihazların (slave) adreslerinin olmasına gerek yoktur. Her çevresel
cihazın seçim ayağı bulunur. Bu ayağa, SS (Slave Select) denir. Bu hattın sayısı kullanılan
çevresel cihazların sayısı kadardır. Her cihaz için master cihazından ayrı SS hattı çıkar. SS hattı
LOW (0 volt) düzeyinde olan çevresel cihaz, master cihaz ile iletişime başlar.

Örnek bir SPI haberleşme hattı aşağıdaki resimde gösterilmiştir. Resimde de görüleceği üzere,
Master cihazdan çevresel cihaz sayısı kadar SS çıkışı bulunur. Master cihaz iletişime geçmek
istediği çevresel cihazın SS pinini LOW (0 Volt) düzeyine çeker.
SPI pinleri Arduino türüne göre değişiklik gösterir. Arduino türlerine göre bu pinleri aşağıdaki
tabloda gösterilmiştir.

SS (master)
Arduino türü MOSI MISO SCK SS (slave)

-
Arduino UNO 11 veya ICSP4 12 veya ICSP1 13 veya ICSP3 10

-
Arduino Mega 51 veya ICSP4 50 veya ICSP1 52 veya ICSP3 53

-
Arduino Leonardo ICSP-4 ICSP-1 ICSP-3 -

Arduino Due ICSP-4 ICSP-1 ICSP-3 - -


SPI fonksiyonları
SPI protokolünü öğrendiğimize göre şimdi haberleşmenin Arduino kısmına bakalım. Arduino'da
SPI fonksiyonlarını kullanabilmemiz için öncelikle "SPI.h" kütüphanesini projemize eklememiz
gerekir. Kütüphane projeye eklendiğinde aşağıdaki fonksiyonlar kullanılabilir.

 [Link](): SPI haberleşmesini başlatır ve SPI pinlerini başlangıç konumlarına alır.


 [Link](): Bu fonksiyon ile SPI haberleşmesinin saati ayarlanabilir.
Fonksiyon değer olarak saat değişkenlerini almaktadır. Eğer hiçbir değişiklik yapılmazsa
SPI saati "SPI_CLOCK_DIV4" olarak çalışır. Fonksiyonun alabileceği değişkenler;
SPI_CLOCK_DIV4, SPI_CLOCK_DIV8, SPI_CLOCK_DIV16, SPI_CLOCK_DIV32,
SPI_CLOCK_DIV64, SPI_CLOCK_DIV128'dir.
 [Link](): SPI hattına veri yollamak veya veri almak için bu fonksiyon kullanılır.

SPI ile İki Arduino Arasında Haberleşme


SPI kütüphanesi, Arduino'nun her zaman master konumunda olacağı düşünülerek hazırlanmış
fakat bu uygulamamızda kullanacağımız Arduino'lardan birisi master, diğeri ise slave (köle)
durumunda çalışacak. Master olan Arduino için SPI kütüphanesi yeterli olacak fakat diğer Arduino
için kütüphane dışında kendi komutlarımızı yazmamız gerekir.

Uygulamada master görevindeki Arduino, diğer Arduino'ya bağlı LED'lerin konumunu yollayacağı
veriler ile değiştirecek. Slave görevindeki Arduino LED'in konumunu değiştirdikten sonra, SPI
üzerinden kaç kere veri geldiğini master olan Arduino'ya geri bildirecek.

Bu uygulamayı yapmak için ihtiyacımız olan malzemeler;

 2 x Arduino
 1 x LED
 1 x 220 ohm direnç
 1 x Breadboard
Master Arduino'nun 11, 12 ve 13. pinleri, köle görevindeki Arduino'nun sırası ile 11, 12 ve 13.
pinlerine takıldı. Master görevindeki Arduino'nun 8. pini, SS pini olarak belirlendi ve köle
görevindeki Arduino'nun 10. pinine bağlandı.

Dikkat: Devredeki iki Arduino da ayrı ayrı veya aynı besleme kaynağından beslenmelidir. Eğer
Arduino'lar ayrı kaynaklardan besleniyorsa toprak hatlarının birleştirilmesi gerektiğini unutmayın.
Köle üzerinden gelen mesajları okumak için master görevindeki Arduino'yu bilgisayara
bağlayarak Seri Monitörü açınız.

/* SPI haberleşmesinde Master olarak görev yapan Arduino kodu */


#include <SPI.h>
/*
* SPI fonksiyonlarını kullanabilmek için
* SPI.h kütüphanesini projemize ekledik
*/

const int SSpini = 8;


/* Slave görevindeki Arduino'nun seçilmesi için 8 bumaralı pin SS
olarak belirlendi */

void setup()
{
pinMode(SSpini, OUTPUT);
/* SS pini çıkış olarak ayarlandı */
digitalWrite(SSpini, HIGH);
/* Slave olan Arduino başlangıçta haberleşmeye geçmemesi için SS
pini HIGH yapıldı */
[Link]();
/* SPI haberleşmesi başlatıldı */
}

void loop()
{
veriGonder('a', SSpini);
/* Diğer arduinoya LED'i yakması için 'a' komutu yollandı */
delay(1000);

veriGonder('b', SSpini);
/* Diğer arduinoya LED'i söndürmesi için 'b' komutu yollandı */
delay(1000);
}

/* SPI üzerinden veri göndermek için yazılmış fonksiyondur */


void veriGonder(char veri, int SSpini)
{
digitalWrite(SSpini, LOW);
/* Diğer Arduino'nun veri dinlemeye başlaması için SS hattını LOW
düzeyine çekmeliyiz */
delay(1);
/* Kısa bir süre bekleyelim */
char LEDDurumu;
LEDDurumu = [Link](veri);
[Link](LEDDurumu);
/* veri karakteri diğer Arduino'ya yollandı
* Fonksiyon diğer arduino'dan gelen veriyi vermektedir
* Geri gelen veri LEDDurumu değişkeninde tutulmuştur
* Bu değişken Seri port üzerinden bilgisayardaki Serial monitöre
yollanmıştır
*/
digitalWrite(SSpini, HIGH);
/* Haberleşmeyi bitirmek için pin LOW konumuna çekilmiştir */
}
Öncelikle projeye SPI fonksiyonlarının kullanılabilmesi için "SPI.h" kütüphanesi eklendi. „SSpini'
değişkeniyle, seçilecek olan köle konumlu Arduino belirlendi. Bu değişken çoğaltılarak sisteme
daha fazla köle görevli Arduino eklenebilir. Setup fonksiyonu içinde SS pinleri çıkış olarak
ayarlandı ve „HIGH' konumuna getirildi. Daha sonra [Link]() fonksiyonuyla SPI protokolü
başlatıldı. Projenin loop fonksiyonu içinde 1 saniye aralıklarla köle olan Arduino'ya „a' ve „b'
karakterleri yollandı

char i = 0;
const int LED = 7;
/* LED Arduino'nun 7. pinine bağlanmıştır */
void setup()
{
pinMode(MISO, OUTPUT);
pinMode(SS , INPUT);
/* MISO pini OUTPUT, SS pini INPUT olarak ayarlandı */
pinMode(LED,OUTPUT);
/* LED pini çıkış olarak ayarlandı */

SPCR 0b11000000;
|=
SPSR 0b00000000;
|=
/* Slave mod ve interrupt için ayarlamalar yapıldı */
sei();
/* Interruptlar çalıştırıldı */
}

void loop()
{
delay(100);
}

/* SPI kesmesi olduğunda çalışacak fonksiyon */


ISR(SPI_STC_vect)
{
cli();
/* Interruptlar durdurulmuştur */
while(!digitalRead(SS))
{
SPDR = i;
i ++;
if ( i > 255)
i = 0;
while(!(SPSR & (1 << SPIF)));
/* SPI hattında veri aktarımı bitene kadar bekle */
char gelenVeri;
gelenVeri = SPDR;
if(gelenVeri == 'a'){
digitalWrite(LED,HIGH);
}else if(gelenVeri == 'b'){
digitalWrite(LED,LOW);
}
/* SPI üzerinden gelen verinin değerine göre LED'in konumu
değiştirildi */
}
sei();
/* Interruptlar başlatılmıştır */
}
Bu uygulamayla SPI protokolünün nasıl çalıştığını ve Arduino tarafında hem master hem de köle
konumunda hangi fonksiyonların kullanıldığını öğrendik. İlerleyen konularda SPI ile çalışan
cihazları inceleyeceğiz.

Arduino ile Kablosuz Haberleşme


Arduino projelerinin çoğunda kablosuz olarak bir yerden, başka bir yere veri aktarmak isteriz. Bu
veriler kimi zaman diğer Arduino'ya bağlı parçaları kontrol etmek için, kimi zaman da karşı
taraftaki Arduino'dan sensör verilerini almak için kullanılır. Arduino, tek başına kablosuz veri
aktarımı için yeterli değildir. Arduino, kablosuz veri aktarımı için kablosuz haberleşme modüllerine
ihtiyaç duymaktadır.

Arduino ile çalışan çeşitli kablosuz haberleşme modülleri vardır. Eğitimimizde bu modüllerden
kullanımı kolay ve fiyatı düşük olan, nRF24L01 modülünü kullanacağız. nRF24L01 modülü
Arduino ile daha önce öğrendiğimiz SPI protokolünü kullanarak haberleşmektedir. Modülün PCB
ve harici antenli modelleri bulunmaktadır. İki model de 2.4 GHz‟de haberleşmektedir, fakat harici
antene sahip modülün haberleşme mesafesi PCB antene sahip modülden daha fazladır.
PCB Antenli nRF24L01
Harici Antenli nRF24L01

Pin bağlantıları
Modül 3.3 Volt ile çalıştığı için, modülün VCC pini Arduino'nun 3.3 Volt çıkışına takılmalıdır.
Yanlışlıkla modülün 5 Volt hattına takılması, modüle zarar verebilir. Bu uygulamada Arduino Uno
kullandığımız için, modülün SPI pinlerini Arduino'nun SPI pinlerine bağlamalıyız. Bazı
nRF24L01'lerde modül üzerinde pin isimleri yazmamaktadır. Aşağıdaki görselde nRF24L01
modülünün pin bağlantıları gösterilmiştir.
Aşağıdaki tabloda nRF24L01 modülü ile Arduino arasında kurulacak bağlantılar gösterilmiştir.

nRF24L01 Haberleşme Modülü Arduino UNO

VCC 3.3 V

GND GND

CS 7

CE 8

MOSI 11

MISO 12

SCK 13

Projelerimizde nRF24L01 modüllerinden birisi alıcı (receiver) diğeri ise verici (transmitter)
görevinde kullanılacaktır. Modülün alıcı veya verici olması, kablo bağlantılarını
değiştirmemektedir. Hangi modülün alıcı, hangi modülün verici olacağına, Arduino içerisindeki
kod karar vermektedir. Projenin ihtiyacına göre haberleşme modülü çift yönlü haberleşme
yapmak için, hem alıcı hem de verici (transceiver) olarak kullanılabilir.

Not: Tüm kablo bağlantılarının hatasız bir şekilde yapılmasına rağmen, bazen modüller birbiri
arasındaki haberleşmeyi sağlayamamaktadır. Böyle bir durumda modüllerin VCC (3.3V) ve GND
pinleri arasına 3.3 uF ile 10 uF arasında bir kapasite koyarak tekrar deneyin.

Arduino yazılımı
nRF24L01 kablosuz haberleşme modülü, Arduino için "nRF24L01p.h" isimli kütüphaneye sahiptir.
Arduino kodunu yazmadan önce bu kütüphaneyi indirip, Arduino projemize dâhil etmeliyiz.
Kütüphaneyi indirmek için tıklayın.

Not: Arduino kütüphaneleri dosya klasörü ile birlikte Arduino'nun yüklü olduğu dizindeki "libraries"
klasörü içerisine kopyalanmalıdır.

Kütüphane projeye eklendikten sonra ilk olarak CS ve CE pinlerinin programa tanımlanmalıdır.


Modül, SPI ile haberleştiği için [Link]() fonksiyonu ile SPI protokolü başlatılmalıdır. İki
haberleşme modülünün birbiri arasında iletişime geçebilmesi için, modüllerin aynı kanal
üzerinden haberleşmesi gerekir. “[Link](KanalID)” fonksiyonu ile haberleşme kanalı seçilir.
Protokol ayarlamaları yapıldıktan sonra iki modül aralarında haberleşmeye hazır hale gelir.
Uzaktan Kontrollü Sıcaklık Sensörü
Bu projede kullanılacak olan iki Arduino Uno'dan birinde LM35 sıcaklık sensörü bulunmaktadır.
Bu, Arduino ortam sıcaklığını ölçerek, sıcaklık bilgisini nRF24L01 kablosuz haberleşme modülünü
kullanarak, diğer Arduino'ya aktaracaktır. Sıcaklık bilgisini alan Arduino ,seri port üzerinden Serial
Monitör'e yazdıracaktır. Bu uygulamada nRF24L01 modülünün devreye nasıl bağlandığını ve
Arduino kodunun nasıl yazıldığını öğrenmiş olacağız.

Not: Bu uygulamada kullanılacak olan LM35 sıcaklık sensörünün besleme (5 V), toprak ve çıkış
olmak üzere 3 adet pini bulunmaktadır. Çıkış pinindeki değer, ortamın sıcaklığına göre lineer
olarak değişmektedir.

Bu uygulamayı yapmak için ihtiyacınız olan malzemeler:

 2 x Arduino UNO
 2 x nRF24L01 kablosuz haberleşme modülü
 2 x 10 uF kapasite
 1 x LM35 (sıcaklık sensörü)
 1 x Breadboard

Alıcı görevindeki
nRF24L01
Arduino Uno

3.3 Volt -> VCC

GND -> GND

7 -> CS
8 -> CE

11 -> MOSI

12 -> MISO

13 -> SCK

Verici görevindeki
nRF24L01
Arduino Uno

3.3 Volt -> VCC

GND -> GND

7 -> CS

8 -> CE

11 -> MOSI

12 -> MISO

13 -> SCK

Verici görevindeki
LM35
Arduino Uno

5 Volt -> 1 (VCC)

A0 -> 2 (Analog)

GND -> 3 (GND)


Verici kodu
#include <SPI.h>
#include <nRF24L01p.h>
#include <String.h>

nRF24L01p verici(7,8);
/* CSN - > 7, CE -> 8 olarak belirlendi */
float sicaklik;
static char veri[10];
void setup() {
[Link](9600);
[Link]();
[Link](MSBFIRST);
/* SPI başlatıldı */
[Link](90);
[Link]("Hasbi");
[Link]();
/* Verici ayarları yapıldı */
}
void loop() {
sicaklik = analogRead(A0);
/* A0daki gerilim ölçüldü */
sicaklik = sicaklik * 0.48828125;
/* Ölçülen gerilim sıcaklığa çevrildi */
[Link]("SICAKLIK = ");
[Link](sicaklik);
[Link](" C");
/* Sıcaklık bilgileri ekrana yazdırıldı */

dtostrf(sicaklik,5,
2, veri);
/* float değerindeki sıcaklık stringe çevrildi */
[Link](veri);
boolean gonderimDurumu = [Link](FAST);
/* Sıcaklık bilgisi nRF24L01'e aktarıldı */
/* Eğer gönderim başarısız olursa gonderimDurumu'nun değeri false
olacaktır */
if(gonderimDurumu==true){
[Link]("mesaji gonderildi");
}else{
[Link]("mesaji gonderilemedi");
}

delay(1000);
}
nRF24L01 modülünün CSN ve CE pinleri 7 ve 8 olarak belirlenmiştir. Okunan sıcaklık verisinin
ekrana yazdırılabilmesi için, seri haberleşme başlatılmıştır. Modül SPI protokolünü kullandığı için
SPI başlatılmıştır. Haberleşmenin sağlanabilmesi için, modüller arasındaki kanal 90 olarak
belirlenmiştir. Loop fonksiyonu içerisinde bir saniye aralıklarla LM35'ten sıcaklık verisi
okunmuştur. Okunan veri, kablosuz haberleşme modülüne yollanmıştır. Gönderimin başarı
durumu 'gonderimDurumu' değişkeni yardımıyla ekrana yazdırılmıştır.
Alıcı kodu
#include <SPI.h>
#include <nRF24L01p.h>

nRF24L01p alici(7,8);
/* CSN - > 7, CE -> 8 olarak belirlendi */

void setup(){
[Link](9600);
[Link]();
[Link](MSBFIRST);
/* SPI başlatıldı */
[Link](90);
[Link]("Hasbi");
[Link]();
/* Alıcı ayarları yapıldı */
}

String sicaklik;

void loop(){
while([Link]()){
/* Modülden veri geldiği sürece while devam edecek */
[Link]();
[Link](sicaklik);
/* Modülden gelen veri okundu */
if([Link]()>0)
{
[Link](sicaklik);
/* modülden gelen veri ekrana yazdırıldı */
sicaklik="";
/* eski veri temizlendi */
}
}
}
nRF24L01 modülünün CSN ile CE pinleri 7 ve 8 olarak belirlenmiştir. Vericiden alınan sıcaklık
verisinin ekrana yazdırılabilmesi için seri haberleşme başlatılmıştır. Modül SPI protokolünü
kullandığı için SPI başlatılmıştır. Haberleşmenin sağlanabilmesi için modüller arasındaki kanal 90
olarak belirlenmiştir. Loop fonksiyonu içerisinde haberleşme modülünden veri geldiği sürece,
while döngüsünün devam etmesi sağlanmıştır. Gelen veriler 'sicaklik' değişkeninde tutulmuş ve
ekrana yazdırılmıştır.

Bu uygulamamızda iki Arduino modülü arasında kablosuz haberleşmenin nasıl sağlandığını


öğrenmiş olduk. Bu ve daha önceki bölümlerde öğrenilen bilgiler ile gelişmiş Arduino projeleri
yapılabilir. Bölümde incelenen nRF24L01 modülü yerine farklı modüller de aynı şekilde
kullanılabilir fakat her modülün haberleşmesi farklı olacağı için, öncelikle kullanılacak modülün
belirtimleri (datasheet) incelenmelidir.
Arduino ile Ethernet Kullanımı
Ethernet modülü, Arduino'yu kablolu internet ağına bağlamak için kullanılan bir karttır. Ethernet
modülüyle Arduino, web tarayıcısı gibi web sitelerine girebilir, web sitelerine veri kaydedebilir
hatta sizin için tweet atabilir.

Kart üzerinde Wiznet W5100 entegresi bulunmaktadır. Ethernet modülü hem TCP hem de UDP
ile uyumludur. Yeni üretilen ethernet modüllerinde, internete bağlanma özelliğinin yanında SD
kart kullanabilme özelliği de bulunur.

Arduino, Wiznet W5100 entegresi ve SD kart SPI üzerinden haberleşir. İnternete bağlanmayı
sağlayan Wiznet entegresi ile Arduino'nun haberleşmeye geçmesi için Arduino'nun 10. pininin 0
Volt (LOW) düzeyine getirilmesi gerekir. Eğer SD kart ile işlem yapılmak isteniyorsa Arduino'nun
4. pini 0 Volt (LOW) düzeyine getirilir.

W5100 ile SD kart aynı SPI hattını kullandıkları için beraber çalışamazlar. Bu yüzden aynı anda
4. ve 10. pinler 0 Volt (LOW) düzeyine getirilmemeli. Kullanılmayacak olan özelliğin SPI kontrol
pinin 5 Volt (HIGH) konumuna getirilmesi gerekir.
Arduino'yu internete bağlamak için shield'e göre daha ucuz olan ethernet modülleri kullanılabilir.
Bu modüller ile Arduino arasındaki kablo bağlantıları elle yapılmalıdır. Aşağıdaki resimde
shield'lere göre daha ucuz olan Enc28j60 ethernet modülü gösterilmiştir.

Enc28j60 ethernet modülünü kullanacak Arduino geliştiricilerinin, kablo bağlantılarını aşağıdaki


tablo veya devre şemasına göre yapmaları gerekir.

Enc28j60 Ethernet modülü Arduino

CS 10

SI 11

SO 12

SCK 13

VCC 3.3V

GND GND
Kablo bağlantılarını yaptığımıza göre artık programlama kısmına geçebiliriz. Ethernet
modüllerinin Arduino ile kullanılması için birçok hazır kütüphane bulunur. Biz bu kütüphanelerden
"ethercard-master" isimli olanını kullanacağız. Bu kütüphaneyi seçme nedenimiz, diğer
kütüphanelere göre daha kolay kullanıma sahip olması ve daha kararlı çalışmasıdır.
Kütüphaneyi buradan indirebilirsiniz.

Not: Kütüphanede tanımlanan CS pininin 10 olarak değiştirilmemesi Arduino'nun ethernet modülü


ile bağlantı kuramamasına neden olacaktır. "EtherCard.h" dosyasındaki "csPin" değişkenini 10
olarak ayarlamayı unutmayınız.

Arduino ile Web Tarayıcı Yapımı


Ethernet modülünün internete başarıyla bağlanıp bağlanmadığını anlamak için bu uygulamada
Arduino ile internet sitelerine bağlanmaya çalışacağız. Bağlandığımız sitenin HTML kodlarını seri
monitöre yazdıracağız. Böylece Arduino ile basit bir web tarayıcı yapmış olacağız.

Uygulamada daha önceden yüklediğimiz "ethercard-master" kütüphanesini kullanacağız. Ethernet


Shield kullanacak Arduino geliştiricileri, Shield'i doğrudan Arduino üzerine takarak, devre
kurulumunu tamamlayabilir. Enc28j60 ethernet modülünü kullanacaklar için kurulması gereken
devre, aşağıdaki devre şamasında gösterilmiştir.
Devre kurulumunu gerçekleştirdiğimize göre aşağıdaki Arduino kodunu yükleyelim ve serial
monitörü açalım.

#include <EtherCard.h>

static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };


/* Ethernet ağında tek olması gereke MAC adresi */

byte Ethernet::buffer[700];
static uint32_t timer;

const char website[] PROGMEM = "[Link]";


/* bağlantı kurulacak internet sitesi */

// called when the client request is complete


static void my_callback (byte status, word off, word len) {
[Link](">>>");
Ethernet::buffer[off+300] = 0;
[Link]((const char*) Ethernet::buffer + off);
[Link]("...");
}
void setup () {
[Link](57600);
[Link](F("\n[web browser]"));

if ([Link](sizeof Ethernet::buffer, mymac) == 0)


[Link](F("Ethernet baglanti hatasi"));
if (![Link]())
[Link](F("DHCP hatasi"));

[Link]("IP: ", [Link]);


[Link]("GW: ", [Link]);
[Link]("DNS: ", [Link]);

if (![Link](website))
[Link]("DNS failed");

[Link]("SRV: ", [Link]);


}

void loop () {
[Link]([Link]());

if (millis() > timer) {


timer = millis() + 5000;
[Link]();
[Link]("Baglanti kuruluyor");
[Link](PSTR(""), "", website, my_callback);
}
}
Yukarıdaki kod çalıştırıldığında, eğer tüm ayarlar ve devre kurulumu doğruysa, Arduino‟nun belirtilen
internet sitesine bağlanması ve bu site ile ilgili bilgileri ekrana yazdırması gerekmektedir. Bağlantı
başarılı bir şekilde kurulduktan sonra sitenin HTML kodları da serial monitörde görünecektir.

Seri haberleşmenin daha hızlı gerçekleşmesi için Baud Rate 57600 olarak belirlenmiştir. Serial
monitörde mesajların doğru görülmesi için serial monitor penceresinin sağ altından baud rate ayarını
yapmayı unutmayınız.

"mymac" değişkenine yazılacak MAC adresi, orijinal ethernet modülleri üzerinde yapıştırma şeklinde
yazmaktadır. Eğer böyle bir yapıştırma bulunmuyorsa, kodda belirtilen MAC adresi denenebilir. Setup
fonksiyonu içinde, modülün belirtilen MAC adresi ile ağa bağlanıp bağlanamadığı kontrol edilmiştir.
Eğer bağlantı hatasız gerçekleştirildiyse, Arduino'nun ağdan aldığı IP adresi ekrana yazdırılmıştır.

Loop fonksiyonu içinde belirtilen internet sitesine bağlanma komutları bulunmaktadır. Arduino beş
saniyede bir belirtilen internet sitesine tekrar bağlanmaktadır. Bunu sağlamak için daha önceden
öğrendiğimiz millis fonksiyonu kullanılmıştır.

Eğer Arduino'nuz hatasız bir şekilde internete bağlandıysa, artık Nesnelerin İnterneti (Internet of
Things) projelerini gerçekleştirebilirsiniz.
Ortam Sıcaklığını Arduino ile Tweet Atmak
Ethernet modülümüzü başarılı bir şekilde internete bağladığımıza göre, bu modül ile yapılabilecek
projelere bakalım. "ethercard-master" kütüphanesi içerisinde tweet atmak için yazılmış örnek
program bulunmaktadır. Bu program üzerinde ufak değişiklikler yaparak ortam sıcaklığını tweet
atan bir devre kurabiliriz. Öncelikle Twitter'a mesaj yollayabilmemiz için kişisel jetonunuzun
(token) olması gerekir. Bunun için burada linki verilen Twiter uygulamasını kullanabilirsiniz.

Twitter üye girişinizi yaptıktan ve uygulamaya izin verdikten sonra, site üzerinde jetonunuz (token)
görünür. Bu sayı ve karakterleri yazacağımız Arduino koduna ekleyeceğiz.

Bu uygulamayı yapmak için ihtiyacınız olan malzemeler:

 Arduino UNO
 Ethernet modülü
 1 x LM35 (sıcaklık sensörü)
 1 x Breadboard

Devremizi yukarıdaki devre şemasında gösterildiği gibi kuralım. Ethernet kablosunu, ethernet
modülümüze bağladıktan sonra devre kurulumumuz tamamlanmış olacaktır. Artık Arduino
kodunu hazırlayabiliriz.

Öncelikle Arduino, Ethernet modülü yardımıyla internet ağına bağlanması gerekir. LM35 ile ortam
sıcaklığı ölçülerek tweet mesajına eklenecektir. Oluşturulan mesaj, Twitter üzerinden aldığımız
jeton (token) ve Twitter uygulaması yardımıyla tweetlenecektir.
#include <EtherCard.h>

#define TOKEN "BURAYA TOKEN KODUNUZU YAZINIZ"

static uint32_t timer;

0x74,0x69,0x69,0x2D,0x30,0x31 };
byte mymac[] = {
/* tekil MAC adresi */

const char website[] PROGMEM = "[Link]";


/* Tweet atabilmemiz için kullandığımız uygulama adresi */

static byte session;

byte Ethernet::buffer[700];
Stash stash;

static void TweetAt () {


[Link]("Tweet hazirlaniyor");
float sicaklik = analogRead(A0);
/* A0daki gerilim ölçüldü */
sicaklik = sicaklik * 0.48828125;
/* Ölçülen gerilim sicaklığa çevrildi */
byte sd = [Link]();
[Link]("token=");
[Link](TOKEN);
[Link]("&status=");
[Link]("Odamin sicakligi su anda ");
[Link](sicaklik);
[Link](" derecedir.");

[Link]("Tweet hazirlandi");
[Link]();
int stash_size = [Link]();
Stash::prepare(PSTR("POST [Link] HTTP/1.0" "\r\n"
"Host: $F" "\r\n"
"Content-Length: $D" "\r\n"
"\r\n"
"$H"),
website, website, stash_size, sd);
session = [Link]();
[Link]("Tweet yollandi");
}
void setup () {
[Link](57600);
if ([Link](sizeof Ethernet::buffer, mymac) == 0)
[Link](F("Ethernet baglanti hatasi"));
if (![Link]())
[Link](F("DHCP hatasi"));

[Link]("IP: ", [Link]);


[Link]("GW: ", [Link]);
[Link]("DNS: ", [Link]);

if (![Link](website))
[Link](F("DNS hatasi"));

[Link]("SRV: ", [Link]);


}

void loop () {
[Link]([Link]());

const char* reply = [Link](session);


if (reply != 0) {
[Link](reply);
}

if (millis() > timer) {


timer = millis() + 60000;
[Link]("Baglanti kuruluyor");
TweetAt();
}

}
Not: Seri haberleşmenin daha hızlı gerçekleşmesi için Baud Rate 57600 olarak belirlenmiştir.
Serial monitörde mesajların doğru görülmesi için serial monitor penceresinin sağ altından baud
rate ayarını yapmayı unutmayınız.

Setup fonksiyonu içinde ethernet modülünün ağa katılabilmesi için ayarlamalar yapıldı.
Arduino'nun ağ üzerindeki IP adresi de bu bölümde ekrana yazdırıldı. Loop fonksiyonu
içinde ethernet modülünden gelecek mesajlar gösterildi ve 60 saniyede bir "TweetAt" fonksiyonu
çağrıldı.

"TweetAt" fonksiyonu, sıcaklığın ölçülerek Twitter mesajının oluşturulduğu fonksiyondur. Burada


oluşturulan mesaj daha önceden izin verdiğimiz uygulama aracılığıyla Twitter'a yollanır. Bu
fonksiyon, loop fonksiyonu içerisinde 60 saniyede bir çağrılır. Kısa sürelerde aynı tweetlerin
atılması, Twitter'ın yollanan mesajları engellemesine neden olabilir.
Ethernet modülü bazen tweet atarken başarısız olabilir. Bu durumlarda tekrar tweet atmayı
deneyebilirsiniz.

Bu uygulama değiştirilerek yeni Nesnelerin İnterneti (Internet of Things) projeleri


gerçekleştirilebilir. Örneğin burada kullanılan sıcaklık sensörü yerine, toprak-nem sensörü
kullanarak çiçeğinizin durumunu çevrimiçi olarak takip edebilir, istediğiniz zaman çiçeğinizi
sulayabilirsiniz.

Önceki Sayfa

Önceki Sayfa

You might also like