Avr-Gsm Sms ile Röle Kontrol

Arduino ile tanışanların çoğunluğu ev otomasyonu adı altında sms ile röle kontrolü işleri yapmaktadır. Ben benzer bir devreyi kendi arazilerimizin sulanması için yaptım. Bu blog içerisinde paylaştım. İlk çalışmalarımı Arduino fonksiyonlarıyla ve hazır kütüphanelerle yaptım. Sistemin çalışması oldukça sorunlu bir haldeydi. Geç cevap veren ve mesajları kaçıran kararsız bir projeydi.

Arduino da kullandığımız Software serial’ in sorunlara neden olabileceğini öğrendim. İncelediğim hazır kütüphanelerin gereksiz kontroller ve beklemelerle dolu olduğunu fark ettiğimde de kütüphane kullanmayı bıraktım. Tüm hazır kütüphaneleri çöpe attım, donanım iyileştirmeleri yaptım. C diliyle baştan yaptığımda hızı hissedilir şeklide arttı. Bu yazıda size hazır kütüphane olmadan Sms alıp-verme ve bir röleyi kontrol etmeyi anlatmaya çalışacağım. İlk olarak Gsm modüllerden kabaca bahsetmek istiyorum.

Gsm Modül

SimCom Sim800 ve Sim900 serileriyle Quectel M66 ve M95 en çok karşılaşacağımız ve İmei kayıtlı olarak satın alabileceğimiz modüllerdir. Bu modülleri hazır kullanabileceğimiz halde bulmak mümkün. Bazı ürünlerin harici beslemeye ihtiyaçları olmaktadır. Bu nedenle ürünlerin bilgi sayfalarını incelemek gerekiyor. Sim800l modülü bunlardan birisidir. Bilgilerini incelediğimizde 3,4-4,4V aralığında çalıştığını ve en yüksek 2A akım ihtiyacı olabildiğini görebiliriz. Bilgi sayfasında beslemenin nasıl yapılacağı ilişkin bilgiler mevcut. Bir diğer önemli konu, modülün Rx bacağını denetleyicinin Tx bacağına doğrudan bağlamamak gerekiyor. 3V üstünde bir voltaj verilmesi durumunda modül bozulabilir. Bunun için voltaj bölücü kullanmak gerekir. Birçok modülde buna gerek yoktur kart üstünde bu işlemler yapılmıştır.

AT Komutları

Attention kısaltması AT ile başlayan komutlardır. Gsm ve Bluetooth gibi modüllerin iletişiminde kullanılır, modem iletişim komutlarıdır. İlk olarak “AT” komutu UART iletişimini kontrol için gönderilir. İletişim varsa “OK” cevabı gelir. Belli başlı komutları aşağıda paylaşıyorum. Buna geçmeden önce AT komutlarını gönderirken “AT<CR> “ (CR= satır başı )şeklinde göndeririz, modül cevap olarak “OK<CR><LF>” (LF= yeni satır) şeklinde dönüş yapar. “AT+CMGF=?<CR>” gönderdiğinizde cevap olarak seçenekleri gösterir. “AT+CMGF?<CR>” gönderdiğinizde cevap olarak ayarlı durumu gösterir. “AT+CMGF=1<CR>” gönderdiğinizde ayarı değiştirir ve geçerliyse “OK<CR><LF>” cevabını gönderir. Tüm komutlar için yazım kuralı böyledir.

CR: Satır başı ascii decimal (13)

LF: Yeni satır ascii decimal (10)

Ctrl+Z: Dosya sonu (EOF) ascii decimal (26)

 

AT: İletişim başlatma- kontrol komutu gönderilir. OK cevabı ile iletişimin durumu kontrol edilir.

AT&W: yapılan ayarları hafızaya alır.

AT+IPR: Baud rate ayarlanır. “0” otomatik ayarlanır.

ATE: Komutları tekrar eder ATE0 olursa tekrar kapatılır.

ATA: Gelen çağrıyı cevaplar.

ATH: Çağrıyı sonlandırır.

ATD: Girilen numaraya çağrı başlatır. “ATD05012345678; <CR>” şeklinde gönderilir.

AT+CMGF: Mesaj format ayarı AT+CMGF=1 yapılırsa metin mesajı alır-verir.

AT+CNMI: Mesaj alındığında modül bildirim gönderir. Bu bildirimin tipi doğrudan iletilmesi ya da hafızada tutulması, mesaj taşıyıcı tipi seçenekleri ayarlanır. AT+CNMI=2,1,0,0,0 ayarladığınızda mesaj hafızaya alınır ve bu bildirim +CMTI: “SM”,1<CR><LF> şeklinde olur. CMTI taşıyıcı, Sm kullanılan hafıza ve “1” sıra numarasıdır. “AT+CNMI=2,2,0,0,0” ayarladığımızda (M66)

+CMT: “+905012345678“,,”2019/06/01 12:30:00+12″<CR><LF>Gelen Mesaj<CR><LF> şeklinde bildirim gelir. (Bu sıralama ya da biçim modüller arası farklı olabilir. Ayrıca farklı ayarlar ile farklı bilgiler içeren bildirimler alınabilir.) CMT taşıyıcı, gönderen numara, tarih, saat ve mesaj içeriği doğrudan iletilir. Bu taşıyıcılar kontrol edilerek mesaj ayrıştırılıp işlem yapılır.

AT+CMGL: Hafızadaki mesaj listesini verir. AT+CMGL=”REC UNREAD” okunmamış mesajları gösterir.

AT+CMGR: Sıra numarası girilen mesajı okunmasını sağlar. “AT+CMGR=1” sıra numarası 1 olan mesajı gösterir.

AT+CMGS: Mesaj gönderme komutudur. AT+CMGS=”05012345678” <CR><LF> komutu ile mesaj gönderilecek numara girilir. Sonrasında “>” işareti cevap olarak gelir. Gönderilmek istenen mesaj girilir. “TEST MESAJ (ctrl+Z)” ile işlem tamamlanır.

AT+CMGD: Hafızadaki mesajları silen komut. “AT+CMGD=1,4” 1 numaralı hafıza bölümündeki tüm mesajları siler.

Bu komutlar birçok işlemi yapmamıza yeterli olacaktır. Komut setini inceleyerek farklı ihtiyaçlar için gerekli komutları bulabilirsiniz. İletişim için gerekli komutlardan sonra artık programa geçebiliriz.

Röle Kontrol

Atmega328p de tek UARTbirimi olduğundan mesajları LCD ekran üstünde gösterdim. Buradan ekran kullanımıyla ilgili bilgileri paylaştım bakabilirsiniz. Ben kodları test ederken Atmega2560 kullandım, bu denetleyicide birden fazla USART birimi bulunmakta. Buradan UART kullanımıyla ilgili bilgilere ulaşabilirsiniz. Tek yapmanız gereken register isimlerini değiştirmek ve her UART birimi için farklı fonksiyonlar oluşturmak. Örn: uart0_basla() ve uart1_basla gibi ve UCSR0B ve UCSR1B gibi registerlere dikkat etmek gerekiyor. Bu şekilde seri ekran ile işlem yapabilirsiniz.

Sms kontrolün çalışma mantığını açıklayayım. Gsm modülü başlatıp gerekli ayarlamaları yaptıktan sonra UART iletişimini kesmeler ile yürütüyoruz. Mesaj geldiğinde kesme devreye giriyor ve ring buffer kullanarak gelen veriyi kaydediyoruz. Veri geldiğinde bir bayrak tanımlıyoruz. Bayrak aktif olduğunda gelen veriyi kontrol ediyoruz. Bu bayrak alınan veride (LF) yeni satır varsa aktif olacak şekilde ayarlıyoruz. Sms taşıyıcı olarak CMT kullandım. Eğer verinin içinde CMT varsa sms geldiğini gösteren bir bayrak daha tanımlıyoruz. Bu bayrakta aktifse mesajı çözüyor gönderen numarayı ve mesaj içeriğini ayrıştırıyoruz. Yukarıda paylaştığım örnekte CMT sonrası numara ve tarih gibi bilgilerin sonunda yeni satır (LF) geliyor ardından mesaj içeriği yer alıyor. Ayrıştırma işlemini bu bilgilere göre yapıyoruz. Tüm bu numara ve mesaj içeriğini dizi olarak alıyoruz. Çalışma mantığı bu şekilde artık fonksiyonlara geçip fonksiyonlarla birlikte açıklamaya devam edebilirim.

UART Fonksiyonları

Gsm modülü için gerekli olan ve daha önce UART kullanımı bölümünde kullanmadığım ya da değişiklik yaptığım fonksiyonları açıklamaya çalışacağım. Öncelikle UART ile ilgili fonksiyonlardan başlayacağım.

 

Modül ile iletişimi UART Rx ve Udre kesmelerini kullanarak gerçekleştiriyoruz. Rx rutininde gelen veriyi diziye alıyoruz farklı olarak ” \n” (LF) yeni satır geldiğinde “uaflag” isimli bayrak değişkenini “1” yapıyoruz. Modül veri gönderirken son olarak LF gönderecektir. Böylece iletişimi sonlandırdığını anlamış oluyoruz. Kod içinde bu bayrak kontrol edilerek devamında diğer işlemleri gerçekleştireceğiz.

 

Yeni bir fonksiyon olan uart_dizi_al fonksiyonu ring buffer’ a kayıtlı veriyi işlem yapabilmemiz için oluşturacağımız bir diziye almayı sağlıyor. Baş ve son sıra eşit olana kadar tüm bilgiyi diziye alıyoruz. Uart_oku ile veri karakter karakter okunuyor her seferinde pozisyon artırılarak kayıt işlemi tamamlanıyor.

Gsm Fonksiyonları

 

Enerji verildiğinde modül kapalı olacağından iletişim kurulamayacaktır. Ayrıca modülün otomatik baud rate ve diğer ayarlarının yapılması için gsm_basla() fonksiyonuna ihtiyaç vardır. İlk olarak “AT” komutunu gönderiyoruz ve “OK” cevabını bekliyoruz. Bilgi sayfalarında bu komutlar için en fazla 300ms bir gecikme olabileceği belirtilmiş. Ben 500ms bekleme yapıyorum. İlk başlangıç aşamasında çalışacağından bekleme konusunda takıntılı davranmadım. “OK” cevabı gelmediğinde modülü sıfırlayan (gsm_reset) ve tekrar komut gönderip “OK” cevabını yoklayan Do-While döngüsüne giriyoruz. İletişim başladığında mesajın metin formatı (CMGF) ve mesaj bildirim (CNMI) ayarlarını yapıyoruz. Kullanılan profile bu ayarları kaydedip varsa tüm mesajları siliyoruz (CMGD). Böylelikle modül ile iletişim başlamış gerekli ayarlar yapılmış oluyor.

 

Modül ile iletişim tamamlandığında “uaflag”  “1” oluyordu, bu durumda mesaj_kontrol() fonksiyonunu çağırıyoruz. Bu çağırma işlemini yapmadan önce küçük bir bekleme yapıyorum. Modül mesaj bildirimini yaptıktan sonra mesajı denetleyiciye gönderiyor. Bu çok hızlı olsa da denetleyici daha hızlı olduğundan mesajı alamadan taşıyıcı metnini alıyor. Bunun başka yöntemleri varsa da ben bilmiyorum ve bu yöntemi kullanıyorum. Mesaj_kontrol fonksiyonu öncelikle veri isimli diziye gelen veriyi alıyor.

Strstr fonksiyonuyla  veri dizisinde CMT taşıyıcısını sorguluyoruz. Eğer dizi içinde CMT varsa bir mesaj  alınmış demektir ve “smsflag” isimli mesaj geldiğini gösteren bayrak değişkeni “1” yapılıyor. AT komutları kısmında verdiğim örnekten gördüğünüz gibi bu bildirim içinde mesaj gönderen numara da vardır. Bilgi sayfasındaki şablona göre 9. karakterden itibaren numara bilgisi yer almakta. C de dizi sonuna “\0” NULL karakteri koyuluyor. Diziye alırken ring bufferda ilk karakter bir önceki mesajın Null karakteri olduğundan biz bir artırarak 10. karakterden numarayı başlatıyoruz. “gonderenno[i]=veri[i+10];” Burada yapılan gönderen no dizisinin i=0 olduğundan “0” yani ilk karakterini Veri dizisinin 10. karakterine eşitlemektir. “i” her döngüde bir artarak devam edecek ve numara kayıt tamamlanacaktır. Sms metnini de aynı mantıkla diziye alıyoruz.

 

İstenen numaraya mesaj gönderme ya da arama için fonksiyonlar bu şekildedir. Gördüğünüz gibi belli karakterleri belli sıralarda göndermek gerekiyor. Bu modüle göre değişiklik gösterebilir bilgi sayfasını kontrol etmek gerekiyor. Modüle gönderim yaparken bir konuyu açıklık getireyim. uart_dizi_gonder(\”\r); satırında “ kırmızı” tırnak işareti dizi olduğunu belirtmek için var. Biz tırnak işareti göndermek istediğimizde \ ters bölme işareti sonra tırnak işareti koymalıyız.

Main Fonksiyonu

Main fonksiyonu port ayarlamalarıyla başlıyor ardından LCD, UART ve Gsm modülü başlatarak döngü içine giriyoruz. Yukarıda bahsettiğim bayrakları kontrol ediyoruz. Uaflag bir olduğunda gsm modülden veri geldiğini anlıyor ve mesaj kontrol fonksiyonu ile bu verinin durumunu kontrol ediyoruz. Sms mesajı gelmişse mesaj ve gönderen numarayı ekrana yazıyoruz. Eğer mesaj içeriğinde ROLE ON/ROLE OFF varsa duruma göre röleyi açıyor-kapatıyoruz. Mesaj gönderen kişiye röle durumunu mesaj olarak gönderiyoruz.

Umarım faydalı olmuştur…

 

 

Bu yazı Haluk ŞİMŞEK tarafından yazılmıştır. 

You may also like...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.