HC SR-04 Pic Kullanımı (CCS C) Bütün Detaylar

Başlatan dogukantuncr, 31 Aralık 2014, 04:41:46

dogukantuncr

Arkadaşlar öncelikle bütün forum arkadaşlarıma merhaba demek istiyorum. Bu yazımda sizinle arduino vb. ürünler arasında yok olmaya yüz tutmuş ancak bizim gibi duyarlı vatandaşlar tarafından ayakta tutulmaya çalışılan PIC Microcontroller ile HC SR-04 mesafe sensörünün kullanım detaylarını, sensörü denerken karşılaşılan sorunları ve bu sorunların çözümlerini ele alacağım. Öncelikle kullanılan malzemeleri yazayım;
1.PIC 18F4620 Microcontroller
2.HC SR-04 Mesafe sensörü
3.LM2575'li regülatör devresi
4.128x64 Winstar marka grafik LCD
5.PICKIT2 Programlayıcı kart
6.Breadboard

NOT:Yazılım CCS C dilinde yazılmıştır.

***Yazının sonunda LM2575 entegresinin datasheet'ini ve +5V Regülatör devresini bulabilirsiniz. Ayrıca HC SR-04 sensörünü yine yazının sonunda paylaştığım linklerden sorunsuz bir şekilde temin edebilirsiniz.

Öncelikle size sensör hakkında faydalı bigiler vereyim. Sensörümüz 2cm ile 400cm arası ölçme yeteneğine sahip. Çalışma akımı 6mA ve çalışma gerilimi 5V DC olan sensör 2 adet kontrol ucuna sahip. Bunlardan bir tanesi start ucu olan trigger, diğeri ise mesafeyi okuma ucu olan echo. Sensörün kullanımı kabaca trigger ucuna 10-20us tetikleme sinyali veriliyor ve echo ucunun 1 den 0 a düşme süresi ölçülüyor ölçülen süre 58 e bölünüyor ve mesafe bulunuyor. Bu iş için PIC'imizin en hassas ve neredeyse tek çaresi olan timer1 modülü kullanılıyor. Timer1 modülü 16bitlik sayıcı ve zamanlayıcı olarak kullanılabiliyor. Biz burda geçen süreyi sayacağımızdan timer1 modülünü sayıcı olarak kullanacağız ve formüllerle uğraşmamak için bölme oranını 1 yapacağız. Tabi ki timer'ın geri dönüş değerinide bir değişkene atacağız bu değişken 16bitlik olmalıdır. Lafı fazla uzatmadan devremize ve yazılımımıza geçelim;

İlk olarak ISIS te çizdiğim devreyi sizinle paylaşıyorum:



Devre gayet açık ama yinede anlamadığınız yer olursa mutlaka sorunuz.
ÖNEMLİ NOT:ISIS'teki LCD LGM kodlu olduğu için benim kullandığım LCD den biraz farklı yazının sonunda kullandığım LCD'nin datasheetini bulabilirsiniz.

İkinci olarak yazılımımızı aşağıda paylaşıyorum:

#include <18f4620.h>
#fuses NOWDT,NOPUT,NOCPD,NOPROTECT,NOMCLR,HS
#use delay (clock=4000000)
#define fast_glcd()
#include <HDM64GS12.c>
#include <GRAPHICS.c>

char yazi0[]="HC SR04 Deneme";   //İlk açılış yazısı değişkeni tanımlanıyor
char yazi1[]="Sure=";            //Ekrana yazılması için sure stringi
char yazi2[]="Mesafe=";          //Ekrana yazılması için mesafe stringi (cm olarak)
char yazi3[1],yazi4[1];          //Bu değişkenler ise değişkenlerimizi ekrana yazmak için
char d[]="PIC Proje";
unsigned long int c;             //16 bit lik işaretsiz süre değişkeni
float a;                         //Ondalıklı mesafe değişkeni

void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF|ADC_TAD_MUL_0);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);    //Timer1 ayarları yapılıyor dahili clock kaynağı ve bölme oranı 1
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   glcd_init(on);                   //İlk kullanım için LCD hazırlanıyor
   glcd_fillscreen(on);             //LCD full açık
   glcd_update();                   //Ekranda gösteriliyor
   delay_ms(200);
   glcd_fillscreen(off);            //LCD full kapalı (temizleme)
   glcd_rect(0,0,127,63,no,on);     //Ekran etrafına köşegen çiziliyor (opsiyonel)
   glcd_text57(22,28,yazi0,1,on);   //Ekrana ilk açılış yazısı yazılıyor
   glcd_text57(37,40,d,1,on);
   glcd_update();                   //Bütün işlemler ekrana yansıtılıyor
   delay_ms(2000);
   glcd_rect(22,28,105,35,yes,off);
   glcd_update();
   
   set_tris_a(0b00000000); //Giriş çıkış ayarlamaları
   set_tris_c(0b00000000);
   set_tris_e(0b00000010);
   
   output_low(pin_c0);     //Sensörün trigger ucu pasif yapılıyor
   a=0;                    //Değişkenler sıfırlanıyor
   c=0;
   
   while(1)                //Sonsuz döngü
   {
      output_high(pin_c0); //Trigger ucu aktif
      delay_us(15);        //15us bekleme
      output_low(pin_c0);  //Trigger ucu pasif
      //Sensör okumaya hazır
      while(!(input(pin_c1))) //Echo ucu 1 olana kadar hiçbir işlem yapma
      {
      }
      set_timer1(0);          //Echo ucu 1 olduğu zaman timer1'i sıfırla
      
      while((input(pin_c1)))  //Echo ucu 0 olana kadar hiçbir işlem yapma
      {
      }
      c=get_timer1();         //Echo ucu 0 olduğunda timer1 değerini c değişkenine at (bizim süre değişkenimiz)
      a=c/58;                 //Mesafeyi cm olarak ölçmek için süre değişkenini 58'e bölüyorum
      
      //Sonuçlar ekrana yazılıyor
      glcd_rect(41,10,71,17,yes,off);
      glcd_rect(60,19,126,26,yes,off);
      glcd_text57(10,10,yazi1,1,on);
      glcd_text57(10,19,yazi2,1,on);
      sprintf(yazi3,"%lu",c);
      glcd_text57(41,10,yazi3,1,on);
      sprintf(yazi4,"%.2f",a);
      glcd_text57(60,19,yazi4,1,on);
      glcd_update();
      delay_ms(1000);
   }
}


Yazılımda gerekli açıklamaları yaptım yinede kafanıza takılan bir şey olursa yardımcı olurum.

Şimdide karşılaştığım sorunları ve çözümleri yazacağım.
İlk karşılaştığım sorun timer1'in ayarlarıydı: Timer1'i ayarlarken mutlaka ve mutlaka dahili clock kaynağını seçin ve bölme oranını 1 yapın
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);


Karşılaştığım ikinci sorun ise sensör nereye bakarsa baksın yani cisimle arasında ne kadar mesafe olursa olsun sadece belli bir kaç süre değerini vermesiydi sensörün bozuk olabilme ihtimalide vardı ancak arada bir yani 50 tane okunan değerden 2-3 tanesinde doğru mesafeyi ölçmesi sensörün bozuk olmaihtimalini ortadan kaldırmasıydı. Madem sensör bozuk değil peki neden sürekli yanlış değer ölçüyordu? İşte bu sorunun cevabını 2 günlük araştırma ve hazırladığım düzenekler sayesinde bulabildim, ultrasonic'lerin açısı bozulmuştu. Ne demek istiyorum:



Ben bu iki sorun yüzünden günlerce uğraştım ancak çok şükürki karşıma başka sorun çıkmadı. Sizin karşınıza çıkan sorunları burada paylaşırsanız herkes bilgi sahibi olur ve güzel bir bilgi birikimi beyin jimanstiği olur.

Evet şimdi sırada projeye ait resimleri paylaşacağım:

















ve buda projenin çalışma videosu:
http://www.youtube.com/watch?v=wyiq0UnrVSM#ws


Bu arada "kendim HC SR-04 sensörü yapmak istiyorum" diyenler içinde bir yardımım dokunsun size HC SR-04'ün orjinal devre şemasını paylaşıyorum buyrun tepe tepe kullanın saygılar :)


LM2575 Entegresinin +5v regülatör devresi:



Her şey bana aittir alıntı değildir yararlı olması dileğiyle...
Doğukan Tuncer

Ekler:
HC SR-04 Datasheet: http://www.micropik.com/PDF/HCSR04.pdf

LM2575 Datasheet:https://www.google.com.tr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=12&cad=rja&uact=8&sqi=2&ved=0CF4QFjAL&url=http%3A%2F%2Fwww.astlab.hu%2Fpdfs%2FLM2575.pdf&ei=z2KjVKPFNKqAywPEwoCICw&usg=AFQjCNEpgWYPdL--_2rjLFsaNgOKE_HVyQ&sig2=TF9kS8DbjuyzKVSg4qiMjw&bvm=bv.82001339,d.bGQ

Winstar12864A Grafik LCD Datasheet: http://www.winstar.com.tw/UserFiles/ProductImages/13367138180895203871.jpg

MrDarK

Çok güzel bir çalışma olmuş tebrik ederim.

Devamının olması dileği ile :) Sanırım bitirme tezi falan bu ?
Picproje Eğitim Gönüllüleri ~ MrDarK

dogukantuncr

Öncelikle teşekkür ederim Ancak bitirme tezi değil sadee hobi olarak uğraşıyorum çok uğtaştım bu sensörle başkaları uğraşmasın sonuçta insanlara yardım etmek önemli

mir_as82

#3
Güzel olmuş hocam eline sağlık.
Bu sistemin hassasiyeti nedir? 0.1mm ölçüm yapabiliyor mu?

dogukantuncr

#4
Eyvallah teşekkür ederim. Sistemin hassasiyeti 3mm dir süre değişkenini float olarak tanımlarsak süreyi 58'e böldüğümüzde 3mm hassasiyetle ölçüm yapabiliriz.

tornadooo

HC SR04 sensörü ile dc motor kontrol etmek istiyorum. İlk deneme de HC RS04 sensörü ile harekete göre led yakıp söndürmeye çalıştım olmadı. CCS C de yazdıgım kod da ki eksikleri söyleyebilirmisiniz. teşekkürler :)


#include "main.h"

#FUSES XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)

int16 uzaklik, zaman;
#define echo pin_B0
#define trig pin_B1
#define led pin_B5
#use fast_io(b)


void main()
{
  setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   set_tris_b(0b00000010);
   set_tris_b(0b00000000);


while(1)
{
output_high(trig);                   
delay_us(20);                       
output_low(trig);
while(!input(echo))                     
{}
set_timer1(0);                         
while(input(echo))                     
{}

zaman=get_timer1();
uzaklik=(zaman*10)/(58.0);


if(uzaklik)
{
  output_high(led);
}
  else 
 {
 output_low(led);
}  

delay_ms(500);
}
}

dogukantuncr

set_tris_b(0b00000010);
   set_tris_b(0b00000000);

sorun burda :)

tris_b'yi iki kere tanımlamışsın ve 2. sinde trig ucunuda çıkış yapmışsın

Recep METE

Arkadaşım emeğin için teşekkür ederim.Bu projeyi bir yere kaydediyorum.Belki ileride lazım olur.
printf(lcd_putc,"\f  Ne kadar okursan oku, bilgine, yakışır şekilde davranmıyorsan cahilsin demektir.  \n   semfero");d

dogukantuncr

Yardımcı olabildiysem ne mutlu bana eğer çözemediğîniz yer olursa yardımcı olmak isterim

Salih

Güzel bir çalışma olmuş. Eline sağlık.

Recep METE

Hocam bu projeyi isiste çalıştırdınız mı?  Çalıştırdıysanız isis dosyasını yükler misiniz?
printf(lcd_putc,"\f  Ne kadar okursan oku, bilgine, yakışır şekilde davranmıyorsan cahilsin demektir.  \n   semfero");d

tornadooo

Alıntı Yapset_tris_b(0b00000010);
   set_tris_b(0b00000000);


Denedim olmadı. Hc rs04 sensörü trig den ses dalgasını göndercek echo geri gelen dalgayı ölcecek yanlış anlamadıysam echo ya gelen her sinyali led de niye gösteremiyorum. Yanlış bir mantık mı kuruyorum? Yazdıgım kod derlerken  herhangi bir hatada vermiyor. uygulamada bir türlü çalışmadı kodu baştan aşagı incelerseniz sevinirim kod da bir problem var...  teşekkürler

ibralali


dogukantuncr

Alıntı yapılan: Recep METE - 03 Mart 2015, 23:18:48
Hocam bu projeyi isiste çalıştırdınız mı?  Çalıştırdıysanız isis dosyasını yükler misiniz?
Dostum HC SR04ün ısıs componenti olmadığı içinı isiste çalışmıyor

dogukantuncr

Alıntı yapılan: tornadooo - 04 Mart 2015, 00:07:23

Denedim olmadı. Hc rs04 sensörü trig den ses dalgasını göndercek echo geri gelen dalgayı ölcecek yanlış anlamadıysam echo ya gelen her sinyali led de niye gösteremiyorum. Yanlış bir mantık mı kuruyorum? Yazdıgım kod derlerken  herhangi bir hatada vermiyor. uygulamada bir türlü çalışmadı kodu baştan aşagı incelerseniz sevinirim kod da bir problem var...  teşekkürler
#include "main.h"

#FUSES XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)

int16 uzaklik, zaman;
#define echo pin_B0
#define trig pin_B1
#define led pin_B5
#use fast_io(b)


void main()
{
  setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   set_tris_b(0b00000010);
   set_tris_a(0b00000000);


while(1)
{
output_high(trig);                   
delay_us(20);                       
output_low(trig);
while(!input(echo))                     
{}
set_timer1(0);                         
while(input(echo))                     
{}

zaman=get_timer1();
uzaklik=(zaman*10)/(58.0);


if(uzaklik==10) //eğer uzaklık 10cm ise
{
  output_high(led);
}
  else
{
output_low(led);


delay_ms(100);
}
}



Birde böyle dene bakalım çalışması gerekiyor eğer sensörle cisim arası 10 cm iken led yanmıyosa ya sensörün bozuktur yada pic bozuktur