PBP İle RFid Readerden Gelen Kodu İşleme

Başlatan forgatten2, 20 Nisan 2011, 18:04:24

forgatten2

RFid readere kartı okuttuğumda 11111111100110011000000000000001100011010100011111100001111001101 şeklinde kod geliyor.
Bu kodu bir şekilde pic'e kaydetmem ve kart tekrar okutulduğunda karşılaştırma yapmam gerekiyor.

RFid reader manchester protokolünü kullandığı için usarta çevirmek için readerin sitesinden hazır program indirip onu kullandım. Manchester kodunu okuyup usart ile veriyor bana. Ama programdan anladığım kadarıyla kodu tek seferde değil tek tek gönderiyor. Daha iyi anlaşılması için aşağıya programın o bölümünü koyuyorum.

            for (i = 0; i <= 64; i++){                 // This part of the code
                                                       //  dislays the number of the specific RfID CARD
                if (data_valid[i] == 0) {
                  Uart1_Write('0');
                  }
                else {
                  Uart1_Write('1');                    // at the end of this for loop you will get a string of "0" and "1"
                  }
            }                                          // specific to a single RfID CARD
            UART1_Write(13);                           // Cariage return (view ASCII chart)
            UART1_Write(10);                           // Line Feed (view ASCII chart)


Bu programdan gelen kodu başka bir pic ile okutup karşılaştırmayı nasıl yapabilirim? (PBP ile)

Ruzgarbey

yazmış olduğunuz C kodu eksik. Sadece 8 bytelik bilgi alımını ve seri olarak gönderimi yazılmış. kodun tamamını yazarsanız size yapmanız gerekenleri yazmaya çalışırım PBP dili ile. saygılarımla..
Hayatta En Hakiki Mürşid İlimdir. M.K. ATATÜRK

forgatten2

İlginiz için teşekkür ederim, kodun tamamını ekliyorum.

/*

sbit OUT at RB0_bit;
sbit RDY_CLK at RB1_bit;
sbit SHD at RB2_bit;
sbit MOD at RB3_bit;

sbit OUT_Direction at TRISB0_bit;
sbit RDY_CLK_Direction at TRISB1_bit;
sbit SHD_Direction at TRISB2_bit;
sbit MOD_Direction at TRISB3_bit;

unsigned short sync_flag,     // in the sync routine if this flag is set
               one_seq,       // counts the number of 'logic one' in series
               data_in,       // gets data bit depending on data_in_1st and data_in_2nd
               cnt,           // interrupt counter
               cnt1, cnt2;    // auxiliary counters
unsigned short data_index;    // marks position in data arrey
char i;
char _data[256];
char data_valid[64];
char bad_synch;               // variable for detecting bad synchronization

void Interrupt() {

  // This is external INT1 interrupt (for sync and sample)
  //     it is enabled until we get 128 data bits
  if (INT1IF_bit && INT1IE_bit) {
      cnt++;                  // count interrupts on INT1 pin (RB1)
      INT1IF_bit = 0;
     }

  // This is external INT0 interrupt (for sync start)
  //   - once we get falling edge on RB0 we are disabling INT0 interrupt
  else if (INT0IF_bit && INT0IE_bit) {
     cnt = 0;
     sync_flag = 1;
     INT0IF_bit = 0;
     INT0IE_bit = 0;
     INT1IF_bit = 0;
     INT1IE_bit = 1;
   }
}


char CRC_Check(char *bit_array) {

char row_count, row_bit, column_count;
char row_sum, column_sum;
char row_check[5];
char column_check[11];

   // row parity check:
   row_count = 9;                      // count rows
   while (row_count < 59) {
     column_count = 0;                 // count columns
     while (column_count < 5) {
       row_check[column_count] = bit_array[row_count+column_count];
       column_count++;
     }
     row_bit = 0;                      // count row bits
     row_sum = 0;
     while (row_bit < 4) {
       row_sum = row_sum + row_check[row_bit];
       row_bit++;
     }

     if (row_sum.B0 != row_check[4].B0) {
       return 0;
     }
     row_count = row_count + 5;
   }
   // end row parity check

   // column parity check
   column_count = 9;            // count columns
   while (column_count < 13) {
     row_bit = 0;               // count column bits
     row_count = 0;             // count rows
     while (row_bit < 11) {
       column_check[row_bit] = bit_array[column_count+row_count];
       row_bit++;
       row_count = row_count + 5;
     }

     row_bit = 0;               // count column bits
     column_sum = 0;
     while (row_bit < 10) {
       column_sum = column_sum + column_check[row_bit];
       row_bit++;
     }

     if (column_sum.B0 != column_check[10].B0) {
       return 0;
     }
     column_count++;
   }
   // end column parity check
   if (bit_array[63] == 1) {
     return 0;
   }
   return  1;
}

// main program
void main() {

  ADCON1 = 0x0F;                // AD converter off
  CMCON = 7;
  
  OUT_Direction = 1;
  RDY_CLK_Direction = 1;
  SHD_Direction = 0;
  MOD_Direction = 0;

  SHD = 0;
  MOD = 0;

  UART1_Init(19200);            // Initialise USART communication
  Delay_ms(100);
  
  sync_flag = 0;                // sync_flag is set when falling edge on RB0 is detected
  one_seq = 0;                  // counts the number of 'logic one' in series
  data_in = 0;                  // gets data bit
  data_index = 0;               // marks position in data arrey
  cnt = 0;                      // interrupt counter
  cnt1 = 0;                     // auxiliary counter
  cnt2 = 0;                     // auxiliary counter

  // setup interrupts
  INTEDG0_bit = 0;              // Interrupt on falling edge on RB0
  INTEDG1_bit = 1;              // Interrupt on rising edge on RB1
  INT0IF_bit = 0;               // Clear INT0IF
  INT1IF_bit = 0;               // Clear INT1IF

  INT0IE_bit = 0;               // turn OFF interrupt on INT0
  INT1IE_bit = 0;               // turn OFF interrupt on INT1
  GIE_bit = 1;                  // enable GIE


  while (1) {
    bad_synch = 0;              // set bad synchronization variable to zero
    cnt = 0;                    // reseting interrupt counter
    sync_flag = 0;              // reseting sync flag
    INT1IF_bit = 0;
    INT1IE_bit = 0;             // disable external interrupt on RB1 (for sync and sample)
    INT0IF_bit = 0;
    INT0IE_bit = 1;             // enable external interrupt on RB0 (start sync procedure)

    while (sync_flag == 0) {    // waiting for falling edge on RB0
     asm nop
    }
 
    while (cnt != 16) {         // waiting 16 clocks on RB1 (positioning for sampling)
     asm nop
    }
 
    cnt = 0;
    _data[0] = OUT & 1;
 
    for (data_index = 1; data_index != 0; data_index++) {   // getting 128 bits of data from RB0
      while (cnt != 32) {                                   // getting bit from RB0 every 32 clocks on RB1
        asm nop
      }
      cnt = 0;                                              // reseting interrupt counter
      _data[data_index] = OUT & 1;                          // geting bit
      if(data_index & 1)
      if (!(_data[data_index] ^ _data[data_index-1]))
         {
            bad_synch = 1;
            break;                                          //bad synchronisation
         }
    }

    INT1IE_bit = 0;                         // disable external interrupt on RB1 (for sync and sample)
    if (bad_synch)
     continue;                              // try again
    cnt1 = 0;
    one_seq = 0;
    for(cnt1 = 0; cnt1 <= 127; cnt1++) {    // we are counting 'logic one' in the data array
      if (_data[cnt1 << 1] == 1) {
        one_seq++;
        }
      else {
        one_seq = 0;
        }

      if (one_seq == 9) {                  // if we get 9 'logic one' we break from the loop
          break;
    }
    }                                      //   (the position of the last  'logic one' is in the cnt1)
    if ((one_seq == 9) && (cnt1 < 73)) {   // if we got 9 'logic one' before cnt1 position 73
                                           //   we write that data into data_valid array
       data_valid[0] = 1;                  //   (it has to be before cnt1 position 73 in order
       data_valid[1] = 1;                  //    to have all 64 bits available in data array)
       data_valid[2] = 1;
       data_valid[3] = 1;
       data_valid[4] = 1;
       data_valid[5] = 1;
       data_valid[6] = 1;
       data_valid[7] = 1;
       data_valid[8] = 1;
       for(cnt2 = 9; cnt2 <= 63; cnt2++) {      // copying the rest of data from the data array into data_valid array
          cnt1++;
          data_valid[cnt2] = _data[cnt1 << 1];
        }
       if (CRC_Check(data_valid) == 1) {        // if data in data_valid array pass the CRC check

            UART1_Write_Text("CRC CHECK OK!");         // Writing of the CRC Check confirmation through USART communication
            UART1_Write(13);                           // Cariage return (view ASCII chart)
            UART1_Write(10);                           // Line Feed (view ASCII chart)
            
            
            
            for (i = 0; i <= 64; i++){                 // This part of the code
                                                       //  dislays the number of the specific RfID CARD
                if (data_valid[i] == 0) {
                  Uart1_Write('0');
                  }
                else {
                  Uart1_Write('1');                    // at the end of this for loop you will get a string of "0" and "1"
                  }
            }                                          // specific to a single RfID CARD
            UART1_Write(13);                           // Cariage return (view ASCII chart)
            UART1_Write(10);                           // Line Feed (view ASCII chart)
            Delay_ms(500);

        }
     }

   }
}

Ruzgarbey

yazmış olduğunuz c kodu portb kesmesi kullanılarak hazırlanmış ve dediğiniz gibi rfid karttan okuduğu bilgileri bit olarak usarttan göndermekte. sizin yapmanız gereken ikinci bir picin usartından bu bilgiyi almak.benim düşümceme göre önce bilgiyi alacak pice bir preamble bilgisi göndermek olur.
c koduna aşağıdaki kodu ekledim.bu şekilde preamble gönderelim.
       if (CRC_Check(data_valid) == 1) {        // if data in data_valid array pass the CRC check            
UART1_Write_Text("ROK");         // Usarttan RFID OK preamble verisi gönderiyoruz
Uart1_Write('A');                         // veri kontrol                                        
for (i = 0; i <= 64; i++){                 // This part of the code                                                      
                                                      //  dislays the number of the specific RfID CARD                
if (data_valid[i] == 0) {                  
Uart1_Write(0);                  
}                
else {                  
Uart1_Write(1);                    // at the end of this for loop you will get a string of "0"and "1"                  
}            
}                                          // specific to a single RfID CARD            
UART1_Write("B");                           //Veri Bitirme           
        
 Delay_ms(500);        
}


şimdi picbasic ile usarttan gelecek veriyi almamız gerekiyor.bu veriyi hafızaya yazma veya hafızadan okuma bölümünü küçük bir flag ile ayarlayabilirsiniz. basic kodları:
Symbol OkuYaz=PortA.0  'gelecek verinin kontrol amaçlımı yoksa yazma amaçlımı olduğunu kontrol eden pin.giriş olarak ayarlayıp bir swicth koyarak ayarlayabilirsiniz.

Kontrol   var bit
Gelen var byte
temp var byte
Adres var byte
HafizaTest  var byte
Hafiza  Var Byte
veriisle  var bit
clear

main:
Select Case OkuYaz  ' İlgili Pinin Durumuna Göre İşlem Yapılıyor
Case 0
veriisle=0
Case 1
if veriisle=1 and HafizaTest=0 Then  ' RFID KART okunmus ve hafizadaki kodla uyumlu ise
.....
.....
veriisle=0
endif

End Select

Goto Main


'USART Kesme Bölümü
Disable
Kesme:
Hserin 3,CIK,[Wait "ROK",Gelen]
if Gelen="A" then
Adres=0
Kontrol=1
endif
if kontrol=1 then
    if OkuYaz=0 Then  ' RFID Kartı Hafizaya Yazma 
         write Adres,Gelen
    else
         Read Adres,Hafiza
         if not Hafiza=Gelen  HafizaTest=1    'bellekte kayıtlı olan rfid no kontrol ediliyor
    endif
endif
if Gelen="A" then
Adres=0
Kontrol=1
HafizaTest=0
endif
if Gelen="B" Then   ' bitirme verisi alınıyor ve değişkenler ayarlanıyor
Kontrol=0
Adres=0
veriisle=1
endif
CIK:
Temp=RcReg
GIE=1
RESUME
ENABLE


Yukarıdaki kodda PortA.0 Pinini RFID Kartın Okunup Kontrol Edilmesi veya RFID Kartın Hafızaya Yazılmasını Sağlıyor. Diğer Programdan Gelen Veriyi Bit Bit Okuyup Toplamda 8 Byte olarakta alabilirdik. ama bu şekildede kontrol edebilirsin.umarım işinize yarar. saygılarımla.
Hayatta En Hakiki Mürşid İlimdir. M.K. ATATÜRK

forgatten2

PBP kodlarında anlamadığım bir konu var.  Hserin 3,CIK,[Wait "ROK",Gelen]  Bu satırda ROK'u bekledik A'yı aldık. Fakat rfid readerden gelen kodu almadık gibi duruyor. Zaten alsak bile 11111111100110011000000000000001100011010100011111100001111001101 şeklindeki kodu herhangi bir değişkene atayamayız diye biliyorum

Ruzgarbey

#5
Alıntı yapılan: forgatten2 - 21 Nisan 2011, 17:36:54
PBP kodlarında anlamadığım bir konu var.  Hserin 3,CIK,[Wait "ROK",Gelen]  Bu satırda ROK'u bekledik A'yı aldık. Fakat rfid readerden gelen kodu almadık gibi duruyor. Zaten alsak bile 11111111100110011000000000000001100011010100011111100001111001101 şeklindeki kodu herhangi bir değişkene atayamayız diye biliyorum
tekrar merhaba.
Usart kesmesinde ROK u alıp Ardındaki veriyi Gelen değişkenine aktarıyoruz. Gelen Degğişkenindeki veri A ise Kontrol isimli değişkeni set ediyoruz ve gerekli ayarlamaları yapıyoruz. Kodu dikkatli incelerseniz Porta.0 pini kart readerden gelen verinin hafızaya yazılma işlemi veya hafızadan okunma işlemi için belirtildiğini görebilirseniz.  kart readerdengelen bilgiyi yani 1 bit Gelen değişkenine alıyoruz. porta.0 pininin durumuna göre hafızaya yazma ve hafızadaki, veriyi kontrol ediyoruz.  Daha açıklayıcı olması için kodların yanına açıklamalarını yazayım.kodu biraz düzelteyim.
Kesme:
Hserin[Gelen]  'preamble verisini al 
if Gelen="A" then  'Gelen değişkeni A ise
Adres=0  'hafızadan okumak veya yazmak için Adres değişkenini sıfırla.
Kontrol=1  'Usarttan istediğimiz preamble geldiği için kontrol değişkenini set et
endif
if kontrol=1 then   ' kontrol değişkeni set edilmiş ise 
if OkuYaz=0 Then  ' porta.0 pini kontrol et. yazma ve okuma için. pin lowda ise        
write Adres,Gelen  'adres değişkenindeki adrese gelen değişkenindeki veriyi yaz.  
else         
Read Adres,Hafiza  'adres değişkenindeki adresteki veriyi okuyup       
if not Hafiza=Gelen  HafizaTest=1    'gelen değişkeni ile karşılaştır.eşit değilse Hafizatest set et
endif
endif
if Gelen="A" then ' ilk Preamble verisi geldiği için değişkenleri tekrar ayarla
Adres=0
Kontrol=1
HafizaTest=0
endif
if Gelen="B" Then   ' bitirme verisi alınıyor ve değişkenler ayarlanıyor
Kontrol=0
Adres=0
veriisle=1
endif
CIK:
Temp=RcReg
GIE=1
RESUME
ENABLE


umarım bu şekilde işini yarar. C kodundaki ROK gönderme satırını sil. C kodunda bilgiyi Byte olarak ayarlamak mümkün.bir dizi değişken tanımlanıp bit leri set veya clear yaparak yapılabilir.
Hayatta En Hakiki Mürşid İlimdir. M.K. ATATÜRK

Ruzgarbey

C koduna bu eklemeyi gerçekleştirdim. PBP ile Bilgiyi Byte olarak alıp istediğin değişkene aktarabilirsin. saygılarımla..
       if (CRC_Check(data_valid) == 1) {        // if data in data_valid array pass the CRC check            
byte Veri[8],say=0,gecici=0,dizisay=0;
Uart1_Write('A');                         // veri kontrol                                       
for (i = 0; i <= 64; i++){                 // This part of the code
                                                     //  dislays the number of the specific RfID CARD               
 if (data_valid[i] == 0) { 
bit_clear(gecici,say);  	// bit olarak alınan bilgiyi gecici değişkenine yazıyoruz bit olarak
say++;               
                
}                
else { 
bit_set(gecici,say);   
say++;              
        
     }  
if(say==8)	// 8 bit olan gecici değişkenini Veri isimli dizi değişkene aktarıyoruz.	
{
say=0;
Veri[dizisay]=gecici;
gecici=0;
dizisay++;
}
     
    }  

for(say=0;say<8;say++)	// readerden alınan 64 bit  veriyi 8 Byte olarak usarttan gönderiyoruz.
{
Uart1_Write(Veri[say]);
}
                                  
 UART1_Write("B");                           //Veri Bitirme                   
 Delay_ms(500);       
 }
Hayatta En Hakiki Mürşid İlimdir. M.K. ATATÜRK