Arduino 401
Arduino 401
(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.
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.
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.
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);
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 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.
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ı */
[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ı.
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 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.
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.
#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ı.
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.
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
*/
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 */
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 -
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.
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.
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);
}
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);
}
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.
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.
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.
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
7 -> CS
8 -> CE
11 -> MOSI
12 -> MISO
13 -> SCK
Verici görevindeki
nRF24L01
Arduino Uno
7 -> CS
8 -> CE
11 -> MOSI
12 -> MISO
13 -> SCK
Verici görevindeki
LM35
Arduino Uno
A0 -> 2 (Analog)
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.
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.
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.
#include <EtherCard.h>
byte Ethernet::buffer[700];
static uint32_t timer;
if ()
[Link]("DNS failed");
void loop () {
[Link]([Link]());
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.
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>
0x74,0x69,0x69,0x2D,0x30,0x31 };
byte mymac[] = {
/* tekil MAC adresi */
byte Ethernet::buffer[700];
Stash stash;
[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"));
if ()
[Link](F("DNS hatasi"));
void loop () {
[Link]([Link]());
}
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ı.
Önceki Sayfa
Önceki Sayfa