1000 kişiden bir kişi için ! devam.... 320volt blog

Elektronik Devreler Projeler » Microchip PIC devreleri bilgiler, Yazar Projeleri Makaleler Elektronik Genel »

RF-ID uygulaması (PIC16F88 SN75176 CCS)

RF-ID uygulaması PIC16F88 SN75176 CCS

Selam arkadaşlar sizinle yapmış olduğum rfi-id uygulamasını paylaşıyorum. Uygulama eğitim amaçlı ve örnek niteliğinde olup geliştirilmeye müsaittir. Uygulamadan bahsedecek olursak denetleyici olarak PIC16F88 kullanılmıştır. PIC16F88 piyasada rahat bulunan PIC16F628A ile pek fiyat farkı bulunmayan 16f628`den daha marifetli bir denetleyicidir.

RF-ID Devre şeması

rf id isis devre semasi

Devre EM4100 diye tabir edilen 125khz rf-id kartlarını okuyup okuduğu bilgileri seri olarak gönderir. haberleşme için baskı devre üzerinde rs485 devresi vardır isteyen iptal edip RS232 olarak kullanabilir. Devre okuduğu kart bilgisini gönderdikten sonra 5 saniye boyunca cevap bilgisi bekler gelen cevap ‘E‘ ise yeşil led yanar buzzer ve röle 1 saniye çalışır. Farklı bir cevap veya 5 saniye boyunca hiç bir cevap gelmez ise kırmızı led ve buzzer kesik olarak iki kere uyarı verir.Devre üzerinde iki led buzzer ve röle vardır.

Ayrıca pc üzerinde alınan kodları okumak ve cevap göndermek için delphi 7 ile küçük bir arayüz hazırladım onunla devreyi test edebilirsiniz.16F88 için kodlar CCS C ile yazılmıştır.

rf id pcb ust

rf ir reader devre alt

rf id pcb modul ust

RF-ID reader PIC16F88

Son olarak devre üzerindeki rf-id okuyucu modül mikro elektronikanın modülüdür. Yurt içi veya yurt dışından temin edilebilir. Modül üzerindeki çip EM4095 tir. Faydalı olması dileğiyle.

Projenin kaynak kod, isis ve program dosyaları ( Dosya şifresi-pass: tekniker_erhan ) RF-ID-reader-PIC16F88.rar

CCS C rfid reader.c yazılım içeriği

///////////////////////////////////////////////////////////////////////////////
//// Proje:PIC16F88 ile RF-ID okuyucu uygulaması                           ////
//// Projeyi yapan:Erhan Yılmaz(tekniker_erhan)                            ////
//// E-mail:erhan_yilmazz@hotmail.com                                      ////
//// Tarih:22-06-2009 Pazartesi                                            ////
//// Version 1.0                                                           ////
//// Not:Proje eğitim amaçlı ve RF-ID uygulamaları ile örnek niteliğinde   ////
//// olup geliştirilmeye müsaittir.                                        ////
///////////////////////////////////////////////////////////////////////////////
#include  <16F88.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,PUT,CCPB3,NOMCLR
#use delay(clock=4000000)
#include 
#include 
#use rs232 (baud=9600, xmit=pin_B5, rcv=pin_B2, parity=N, stop=1)
#define RF_RDY_CLK   PIN_B6
#define RF_SHD       PIN_B1
#define RF_MOD       PIN_B4
#define RF_DEMOD_OUT PIN_B3
#define k_led PIN_A2
#define y_led PIN_A3
#define buzzer PIN_B7
#define role PIN_A1

unsigned int8 code[5];
unsigned int8 cevap;
void yanlis(void){
        output_high(k_led);
        output_high(buzzer);
        delay_ms(200);
        output_low(k_led);
        output_low(buzzer);
        delay_ms(200);
        output_high(k_led);
        output_high(buzzer);
        delay_ms(200);
        output_low(k_led);
        output_low(buzzer);
        }

void dogru (void){
        output_high(y_led);
        output_high(role);
        output_high(buzzer);
        delay_ms(1000);
        output_low(y_led);
        output_low(role);
        output_low(buzzer);
        }

void kontrol(int8){
   if(cevap=='E'){dogru();}
   else{yanlis();}}

void main(void) {
int16 i;
   setup_adc_ports(NO_ANALOGS);
   setup_comparator(NC_NC_NC_NC);
   rf_init(); 

   while(1) {

        if(read_4102(code)){
        disable_interrupts(global);
        output_high(y_led);
        output_high(buzzer);
        delay_ms(200);
        output_low(y_led);
        output_low(buzzer);
        printf("%X-%X-%X-%X-%X"code[0],code[1],code[2],code[3],code[4]);
        cevap='H';
        for(i=0;i<=5000;i++){
        if (kbhit()){
        cevap=getch();
        break;}
        delay_ms(1);}
        kontrol(cevap);
        enable_interrupts(global);
        }
     }
}

CCS C em4095_read.c yazılım içeriği

/////////////////////////////////////////////////////////////////////////
////                             em4095_read.c                       ////
//// This file contains drivers for a EM4095 RFID basestation.       ////
////                                                                 ////
/////////////////////////////////////////////////////////////////////////
////                                                                 ////
////                          Pin Layout                             ////
////   ------------------------------------------------------------  ////
////   |                                                          |  ////
////   | 1: VSS       GND         | 16: DC2                       |  ////
////   |                          |                               |  ////
////   | 2: RDY/CLK   RF_RDY_CLK  | 15: FCAP                      |  ////
////   |                          |                               |  ////
////   | 3: ANT1                  | 14: SHD         RF_SHD        |  ////
////   |                          |                               |  ////
////   | 4: DVDD                  | 13: DEMOD_OUT   RF_DEMOD_OUT  |  ////
////   |                          |                               |  ////
////   | 5: DVDS                  | 12: MOD         RF_MOD        |  ////
////   |                          |                               |  ////
////   | 6: ANT2                  | 11: AGND                      |  ////
////   |                          |                               |  ////
////   | 7: VDD       +5V         | 10: CDEC_IN                   |  ////
////   |                          |                               |  ////
////   | 8: DMOD_IN               |  9: CDEC_OUT                  |  ////
////   ------------------------------------------------------------  ////
////                                                                 ////
/////////////////////////////////////////////////////////////////////////

#ifndef EM4095
#define EM4095

#ifndef RF_SHD
#define RF_RDY_CLK   PIN_B6         // External interrupt used to read clock
#define RF_SHD       PIN_B1         // High disables the antenna signal
#define RF_MOD       PIN_B4         // High does 100% modulation
#define RF_DEMOD_OUT PIN_B3         // Data read in interrupt service routine
#endif

// Provide a buffer for storing recieved data and data to be sent
#define RFBUFFER_SIZE 20
int8 RFbuffer[RFBUFFER_SIZE];
int8 RFbuffer_index = 0;
int8 RFbuffer_bitIndex = 0;
#define END_OF_RFBUFFER (RFbuffer_index == sizeof(RFbuffer))

/////////////////////////////////////////////////////////////////////////
//// Read modes available for reading data from a transponder
/////////////////////////////////////////////////////////////////////////
int8 RF_readMode;
#define RF_MANCHESTER_DATA    0     // Reads Manchester encoded data
#define RF_MEASURE_WIDTHS     1     // Measure a series of widths
#define RF_FIND_WIDTH         2     // Find a specific width
#define RF_FIND_PATTERN       3     // Find a pattern of widths
/////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////
//// Global Variables
/////////////////////////////////////////////////////////////////////////
int1  bitValue              = 1;
int1  storeData             = TRUE;
int1  RE_FE_TOGGLE          = 1;
int1  RF_widthFound         = FALSE;
int1  RF_patternFound       = FALSE;
int8  RF_widthToFind        = 0;
int8* RF_findWidths         = 0;
int8  RF_uncertainty        = 0;
int8  timer0_overflows      = 0;
int8  dataTransferred       = 0;
int16 old_clock             = 0;
/////////////////////////////////////////////////////////////////////////

// Purpose:       Initializes the 4095 into sleep mode
//                Sets up the timers and interrupts
void rf_init()
{
   output_low(RF_SHD);
   output_low(RF_MOD);

   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);
   setup_ccp1(CCP_CAPTURE_RE);
   //setup_ccp2(CCP_COMPARE_INT);

   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
}

// Purpose:       Powers down the RF antenna
//#define rf_powerDown()  output_high(RF_SHD);

// Purpose:       Powers up the RF antenna
//#define rf_powerUp()    output_low(RF_SHD);

// Purpose:       Select which edge to begin reading data
void RF_readEdge(int1 edge)
{
   if(edge)
   {
      setup_ccp1(CCP_CAPTURE_RE);
      RE_FE_TOGGLE = 1;
   }
   else
   {
      setup_ccp1(CCP_CAPTURE_FE);
      RE_FE_TOGGLE = 0;
   }
}

// Purpose:       Interrupt service routine to handle compare 1 interrupts.
//                Reads incoming data from a transponder and stores it in
//                the global buffer.
#INT_CCP1
void isr_ccp1()
{
   int8  width;

   // Toggle between capturing rising and falling edges to meausure width
   if(RE_FE_TOGGLE)
   {
      setup_ccp1(CCP_CAPTURE_FE);
      RE_FE_TOGGLE = 0;
   }
   else
   {
      setup_ccp1(CCP_CAPTURE_RE);
      RE_FE_TOGGLE = 1;
   }

   // Calculate the width
   width = CCP_1 - old_clock;
   old_clock = CCP_1;

   switch(RF_readMode)
   {
      // Use to receive manchester formatted data from a transponder
      case RF_MANCHESTER_DATA:
      {
         if(width > 54)           // Check for a phase change
         {
            bitValue = ~bitValue; // Invert the save bit value
            storeData = TRUE;     // Force a bit store
         }

         if(storeData)
         {
            shift_right(RFbuffer+RFbuffer_index, 1, bitValue);
            ++dataTransferred;

            if(++RFbuffer_bitIndex == 8 )
            {
               RFbuffer_bitIndex = 0;
               ++RFbuffer_index;
            }
         }

         storeData = ~storeData;
         break;
      }

      // Use to read high and low widths
      case RF_MEASURE_WIDTHS:
      {
         RFbuffer[RFbuffer_index++] = width;
         ++dataTransferred;

         break;
      }

      // Use to search for a certain pulse width
      case RF_FIND_WIDTH:
      {
         if(width > (RF_widthToFind - RF_uncertainty)
         && width < (RF_widthToFind + RF_uncertainty))
         {
            RF_widthFound = TRUE;
         }
         break;
      }

      case RF_FIND_PATTERN:
      {
         if(width > RF_findWidths[RFbuffer_index] - RF_uncertainty
         && width < RF_findWidths[RFbuffer_index] + RF_uncertainty)
         {
            if(++RFbuffer_index == dataTransferred)
            {
               RF_patternFound = TRUE;
            }
         }
         else
         {
            if(RFbuffer_index > 0)
            {
               int8 pos, i, j;
               pos = RFbuffer_index-1;   // Save the initial position

               // Try to match partial pattern
               while(--RFbuffer_index != 0)
               {
                  if(width > RF_findWidths[RFbuffer_index] - RF_uncertainty
                  && width < RF_findWidths[RFbuffer_index] + RF_uncertainty)
                  {
                     for(i=pos, j=RFbuffer_index-1; j!=255; --i, --j)
                     {
                        if(RF_findWidths[j] != RF_findWidths[i])
                        {
                           break;
                        }
                     }
                     if(j == 255)
                     {
                        break;
                     }
                  }
               }
            }
         }
         break;
      }
   }
}

// Purpose:       This interrupt service routine is used
//                to send data to a transponder
// Inputs:        None
// Outputs:       None

// Purpose:       Interrupt for timer 0. Keeps track of the number of
//                overflows for timeouts.
// Inputs:        None
// Outputs:       None
#INT_RTCC
void isr_rtcc()
{
   ++timer0_overflows;
}

// Purpose:       Fill the buffer with data read from the basestation
// Inputs:        1) The number of bits to read
//                2) TRUE start on rising edge
//                   FALSE start on falling edge
// Outputs:       The number of bits read. Could be used to check for timeout
int8 RF_get(int8 numBits, int1 edge)
{
   RF_readEdge(edge);
   RF_readMode = RF_MANCHESTER_DATA;

   storeData         = TRUE;
   bitValue          = 0;
   RFbuffer_index    = 0;
   RFbuffer_bitIndex = 0;
   dataTransferred   = 0;
   timer0_overflows  = 0;
   old_clock         = 0;
   set_timer1(0);

   clear_interrupt(INT_CCP1);
   enable_interrupts(INT_CCP1);
   while(dataTransferred < numBits && timer0_overflows < 15);
   disable_interrupts(INT_CCP1);

   RFbuffer_index = 0;
   RFbuffer_bitIndex = 0;

   return dataTransferred;
}

// Purpose:       Send data from the buffer to the transponder
// Inputs:        1) Send numBits of data to the transponder
//                2) The index in the buffer to start at
//                3) The bit position at the index to start at
// Outputs:       None

// Purpose:       Search for a certain pulse width
// Inputs:        1) The width length in clocks
//                2) Uncertainty to search over a range
//                3) TRUE start on rising edge
//                   FALSE start on falling edge
//                ex) numClocks = 128; uncertainty = 6; range = 122 to 134
// Outputs:       TRUE if width was found, FALSE if not found
int1 RF_findWidth(int8 numClocks, int8 uncertainty, int1 edge)
{
   RF_readEdge(edge);

   RF_readMode          = RF_FIND_WIDTH;
   RF_widthToFind       = numClocks;
   RF_widthFound        = FALSE;
   RF_uncertainty       = uncertainty;
   timer0_overflows     = 0;
   old_clock            = 0;
   set_timer1(0);

   clear_interrupt(INT_CCP1);
   enable_interrupts(INT_CCP1);
   while(RF_widthFound == FALSE && timer0_overflows < 50);
   disable_interrupts(INT_CCP1);

   return RF_widthFound;
}

// Purpose:    Measure a number of pulse widths, both high and low
// Inputs:     1) The number of widths to measure
//             2) TRUE start on rising edge
//                FALSE start on falling edge
// Outputs:    The number of widths that were measured. If there is
//             no transponder in range, the timeout could occur.
int8 RF_measureWidths(int8 numWidths, int1 edge)
{
   RF_readEdge(edge);

   RF_readMode       = RF_MEASURE_WIDTHS;
   dataTransferred   = 0;
   RFbuffer_index    = 0;
   timer0_overflows  = 0;
   old_clock         = 0;
   set_timer1(0);

   clear_interrupt(INT_CCP1);
   enable_interrupts(INT_CCP1);
   while(dataTransferred < numWidths && timer0_overflows < 50);
   disable_interrupts(INT_CCP1);

   return dataTransferred;
}

// Purpose:    Measure a number of pulse widths, both high and low
// Inputs:     1) A pointer to an array of widths. It is safe to use RFbuffer.
//             2) The number of widths in the pattern
//             3) Uncertainty to search over a range
//             4) TRUE start on rising edge
//                FALSE start on falling edge
// Outputs:    The number of widths that were measured. If there is
//             no transponder in range, the timeout could occur.
int8 RF_findPattern(int8* widths, int8 numWidths, int8 uncertainty, int1 edge)
{
   RF_readEdge(edge);

   RF_readMode       = RF_FIND_PATTERN;
   RF_patternFound   = FALSE;
   RFbuffer_index    = 0;
   RF_findWidths     = widths;
   dataTransferred   = numWidths;
   RF_uncertainty    = uncertainty;
   timer0_overflows  = 0;
   old_clock         = 0;
   set_timer1(0);

   clear_interrupt(INT_CCP1);
   enable_interrupts(INT_CCP1);
   while(RF_patternFound == FALSE && timer0_overflows < 40);
   disable_interrupts(INT_CCP1);

   return RF_patternFound;
}

// Purpose:       Set every byte in the buffer to data
// Inputs:        None
// Outputs:       None
void RFbuffer_fill(int8 data)
{
   int i;

   for(i=0; i= 8 )
      {
         ++RFbuffer_index;
         RFbuffer_bitIndex = 0;
      }
   }
}

// Purpose:       Set the value of the next byte in the buffer
// Inputs:        None
// Outputs:       None
void RFbuffer_setByte(int8 data)
{
   if(!END_OF_RFBUFFER)
   {
      int8 i;
      for(i=0; i<8; ++i)
      {
         RFbuffer_setBit(bit_test(data, 7));
         rotate_left(&data, 1);
      }
   }
}

#endif

Yazar: Erhan

Yazarımızın 320volt.com Blog üzerinde şu an okuduğunuz yazı dahil 21 yazısı bulunmaktadır. Yazarımız hakkında bilgileri ve diğer yazılarını görmek için bakınız;

Elektronik

 
  1. aykut54 (picproje.org) says:

    erhan hocam tebrikler size yetişemiyoruz allah yolunuz açık etsin

  2. Erhan says:

    Sağol dostum inşallah vakit buldukça böyle projeler yapıp yayınlarım

  3. can efendi says:

    erhan hocam; süpersiniz :P

  4. serkan says:

    Erhan Bey devreyi yapıp güzel çalıştırmışsınız ama yayınladığınız kodlarda eksiklik var iki tane include demişsiniz ama yanına birşey yazmamışsınız. Ayrıca rf okuyucu kartı okuduktan sonra veri göndermeden önce birkaç bit (artık rf okuyucu nasıl tasarlanmışsa) kontrol için göndermiyor mu? Ben bitirme aldım ve bitirmemde ID kodlarını bilgisayara göndereceğim. Ama daha rf okuyucudan pici haberleştiremiyorum. Bu konuda birşeyler yazarsanız çok öğretici olur. Teşekkürler

  5. gevv says:

    Kodlarda bir eksik yok eklenirken bir sorun olmuş düzenlendi kaynak dosyadaki kodlar ile denemenizi yapın iyi çalışmalar

  6. Erhan says:

    Arkdaşım mesajını yeni gördüm include problemini siteye eklerken problem olmuş sorun düzeltilmiş zaten devre sadece okuduğu 5 bytelık rfid datasını hex formatta seriporttan iletiyor her byte için 2 karkter toplamda 10 byte gödneriyor onun dışında hehangi bir kontrol işareti göndermiyor kodları örnek olması için yazdığım için gerek duymadım önemli olan if(read_4102(code))komutunun değeri true(1) ise rfid kart okunmuş ve code isimli 5 bytelık değişkene kart datası aktarılmış demektir sonrasında sen bu datayı istediğin şekilde kullanabilirsin ben devrenin çalışmasını görmek için datayı hex karakterler şeklinde 10 byte olarak seriporttan direk gönderdim pc kısmında ise küçük bir arayüz programı ile kodları görüntüledim

  7. bünyaz says:

    Devre için teşekkürler.
    Ancak devreyi kurduk okuyucuyu taktık kartıda bulduk buraya kadar hallederiz.
    1.Pc bağlantısını nasıl gerçekleştireceği (bilmiyorum) ve arayüzün çalışmasını anlayamadım :)
    2.Elimde 4 kart var 2si kapıyı açsın 2si açamasın istiyorum mevcut halle bunları gerçekleştirmek mümkün müdür? Yoksa geliştirmek mi gerekiyor.
    Teşekkürler.

  8. Erhan says:

    Merhabalar devrenin pc bağlantısı biraz kafa karıştırıyor buda devrenin esas kullanım amacından dolayı devrenin asıl amacı slave üye olarak ağa bağlanmak yani kart bilgisini ana denetleyiciye veya pcye gönderir bilgi orada değerlendirilir ona göre evet veya hayır anlamında geri dönüş alınır böylece büyük bir firmanın v.s sitenin giriş çıkış kontrolü sağlanır devreyi bu amaçla tasarladım haberleşme içinde en uygun rs485 olduğu için rs485 çipi kullandım ama kartı direk pcye bağlamak için rs485 kısmını kullanmayıp picin rx tx çıkışlarını pc ile haberleştirmek için rs232 çip ile devre kurup haberleştirmek yeterli 2. sorunda ise devre donanım olarak uygun fakat yazılımda değişiklik yapman gerek 16f88i bu yüzden kullandım 16f88in 4 kword hafızası olduğu için bir çok fonksiyon ekleyebilirsin

  9. Selamlar hocam. ben bu devreyi yapmak istiyorum. Bina giriş sistemi. için, baskı devre cizimi varmı, malzemeleri nereden temin edebilirim?

  10. Erhan says:

    Bina giriş sistemi için pc bağlantısı kullanmayıp ilgili yazılımını yazıp kullanabilirsin pcb müsait rfid okuyucuyu www.elektrovadi.com adresinden temin edebilirsin diğer malzemelerde piyasada rahatça bulunabilir.

  11. Otomasyocu says:

    Öncelikle elinize sağlık güzel bir çalışma olmuş. Benim farklı bir sorum olacaktı da; biz bu rf-id kartı(okutulan kartı) kendimiz programlayabilirmiyiz yoksa fabrika çıkışı orjinal halimi, yada bunların pilli olanlarından mı almak lazım

  12. Erhan says:

    Benim devre ile sadece okuma yapılır okuma yazma için 16f88 yerine en düşük 16f876 yani enaz 2 ccp modülü olan pic bağlanması lazım sonrada ccsnin kütüphanesinde bulunan em4095.c dosyasını projene dahil ederek okuma yazma fonksiyonlarını kullanabilirsin benim em4095_read.c dosyası sadece okumak içindir.Kartlarda em4100 diye geçen sadece okunabilir kartlardır okuma yazma için em4150 diye geçen 1 kbit kapasiteli kartlar var onlarla işini görebilirsin ama onlarında pek bulunacağını sanmıyorum çünkü benim yaptığım devre 125 khz bunlar genellikle kartlı geçiş sistemlerinde kullanılır. Hafızalı kayıt işlemleri gerektiren ugulamalarda 13.59 mhzlik okuyucular kullanılır kart olarakta mifare diye geçen kartlar kullanılır. Bunların okuyuclarını yapmayada gerek yok çünkü 30-50 liraya 13.59 mhz rfid okuyucu yazıcı modüller satılıyor seriporttan direk bilgisayarla haberleşiyor.

Yorum Sayfaları

Yorum yapın

Doğrulama: (kutuyu işaretleyiniz)

  • Lütfen Türkçe imla kurallarına dikkat etmeye özen gösteriniz.
  • Yorumunuz yönetici tarafından kontrol edilmeden yayımlanmaz.
  • Paylaşılan devrelerin malzeme listesini istemeyiniz. Olsa zaten paylaşılırdı şema üzerinden listeyi çıkartabilirsiniz
  • Gavatar sitesine avatarınızı yükleyebilirsiniz.