Jump to content

Parallax RFID reader v2

Recommended Posts

I didn't want to take away from NatureTM's post on a similar title, so I'm just calling this v2.


This is my version of the parallax RFID Reader code. I'm using oPossum's software asyncserial code as the base for communications as it was extremely small and just worked right out of the box. The code currently compiles to Text: 608 bytes and Data 100 bytes. This is running on the 2231 chip but I'm sure would run fine on the 2211 as well.


Pins used, VCC for power to the RFID reader, GND for ground, P1.4 for serial in and P1.0 for enable/disable of the reader.


The brief on it:

1. read RFID

2. Disable RFID reader

3. Output matches and mismatches

4. Add small Delay(I did this as an experiment in learning ASM so not sure if this is the best way to do it. I could have used a simple delay function written in c which would have made control of the delay a little easier to set. )

5. turn on Reader


Now step 3 can be modified to just output if it matches or not....but I didn't do that with this code.

I've also added a couple of functions to the serial.asm file that turn on and off the Red LED P1.0 and another wait function....Seeing as I'm not quite sure if I did this correct or not...I'm sure someone may spot issues.


I tried my hand at a simple diff function....I'm sure it could be better as well...but heck, it worked for me so far...I'd love to hear recommendations on it.

EDIT: depending on your system this may not work on the linux side right away....I forgot that the code for the button press was important in that if you just plug this in it'll play havoc with some serial ports...so...you need a delay or set the first transmit of the device within the button interrupt....ooops...


Main body of code...

// RFidRead.c
#include "msp430g2231.h" //change as needed

#define keyCount 3
#define idc 11

static const unsigned char ID[][12] =
{0x0A, 0x30, 0x46, 0x30, 0x33, 0x30, 0x32, 0x38, 0x31, 0x33, 0x42, 0x0D} // 0F0302813B
,{0x0A, 0x30, 0x34, 0x31, 0x35, 0x42, 0x30, 0x43, 0x34, 0x34, 0x34, 0x0D} // 0415B0C444
,{0x0A, 0x30, 0x46, 0x30, 0x33, 0x30, 0x32, 0x38, 0x30, 0x35, 0x31, 0x0D} // 0F03028051
// oPossums function code
void serial_setup(unsigned out_mask, unsigned in_mask, unsigned duration);
void putc(unsigned);
void puts(char *);
unsigned getc(void);
//new functions to enable and disable the Red LED
void Red_Off(void);
void Red_On(void);
void Wait(void);

//my diff funciton. var 1 is the input key(read in from the rfid reader), var 2 is the diff key from the ID Array.
unsigned char diffAR(unsigned char a[],const unsigned char b[]);

void main(void)
unsigned char key[12]; //array to hold keys read in through reader

// Disable watchdog
//disabled as I now just put this code into a loop without initialization via button press
//P1IE = 0x04; // P1.3 interrupt enabled
//P1IES |= 0x04; // P1.3 Hi/lo edge
//P1IFG &= ~0x04; // P1.3 IFG cleared

// Use 1 MHz DCO factory calibration
//I'm wondering if it's possible to set up 3 pins for serial com....
// Setup the serial port
// Serial out: P1.1 (BIT1)
// Serial in:  P1.4 (BIT2)
// Bit rate:   2400 (CPU freq / bit rate) 
serial_setup(BIT1, BIT4, 1000000 / 2400);

//Start of read code.
puts("\r\nRFID Read...\r\n");
//if data comes out garbled check the baud rate....try hitting reset as well.
//_BIS_SR(LPM0_bits + GIE); //disabling for now as I don't need this.
  int i;
  for(i = 0;i<11;i++) {           // Do forever
  //c = getc();     // Get a char
  //putc(c);        // Echo it back
  //Check for 0F or 04
  for(i = 0;i<11;i++) {           
  int x;
  for(x=0;x   if (diffAR(key, ID[x])==1)
  {puts("\r\nKey matches...\r\n");}
{puts("\r\nKey mismatch...\r\n");}
//Some test code...figured maybe it would be useful for someone.
  for(; {           // Do forever
  c = getc();     // Get a char
case 'a' :
case 'b' :
default :
Wait(); //wait for a little bit.
Red_Off(); //Re-enable RFID reader.

//not used atm, left in just in case though...
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)

char c;
c = getc();
P1IFG &= ~0x04; // P1.3 IFG cleared

unsigned char diffAR(unsigned char a[],const unsigned char b[]){
unsigned char diff = 0;
unsigned char t = 0;
unsigned char count = 0;
unsigned char i;
for(i = 0;i<11;i++) {
   //A do while loop...WOO...
   do {
   //compare arrays here	
   t=(b[count]==a[count])? 1:0;
   if (count == 11)
   {diff = 1;}
   while(t == 1);
   //a=(x==y)? 1:0;
return diff;


And the slightly modified code from oPossum

; serial.asm
           .cdecls C, LIST, "msp430g2231.h"
           .bss    in_bit_mask, 2      ; Serial in pin
           .bss    out_bit_mask, 2     ; Serial out pin
           .bss    bit_dur, 2          ; Bit duration in cycles
           .bss    half_dur, 2         ; Half bit duration in cycles
           .text                       ;
           .def    serial_setup        ; void serial_setup(unsigned out_mask, unsigned in_mask, unsigned bit_duration);
           .def    putc                ; void putc(unsigned c);
           .def    puts                ; void puts(char *s);
           .def    getc                ; unsigned getc(void);
           .def	Red_On				;
           .def	Red_Off				;
           .def	Wait                ;
serial_setup                            ; - Setup serial I/O bitmasks and bit duration (32 minimum)
           mov     R12, &out_bit_mask  ; Save serial output bitmask
           mov     R13, &in_bit_mask   ; Save serial input bitmask
           bis     R12, &P1DIR         ; Setup output pin
           bis     R12, &P1OUT         ;
           bic     R13, &P1DIR         ; Setup input pin
           or      R13, R12            ;
           bic     R12, &P1SEL         ; Setup peripheral select
           mov     R14, R12            ;
           sub     #16, R14            ; Adjust count for loop overhead
           rla     R14                 ; Multiply by 2 because NOP is two bytes
           mov     R14, &bit_dur       ; Save bit duration
           sub     #32, R12            ; Adjust count for loop overhead
           mov     R12, &half_dur      ; Save half bit duration
           							; Added by mark to allow for LED fun!
           bis.b   #01000001b,&P1DIR   ; make P1.0 and P1.6 output
           jmp		Red_Off             ; all others are inputs by default
           ret                         ; Return
                                       ; - Send a single char
putc                                    ; Char to tx in R12
                                      ; R12, R13, R14, R15 trashed
           mov     &out_bit_mask, R15  ; Serial output bitmask
           mov     &bit_dur, R14       ; Bit duration
           or      #0x0300, R12        ; Stop bit(s)
           jmp     bit_low             ; Send start bit...
tx_bit      mov     R14, R13            ; Get bit duration
tx_delay    nop                         ; 4 cycle loop
           sub     #8, R13             ;
           jc      tx_delay            ;
           subc    R13, PC             ; 0 to 3 cycle delay
           nop                         ; 3
           nop                         ; 2
           nop                         ; 1
           rra     R12                 ; Get bit to tx, test for zero
           jc      bit_high            ; If high...
bit_low     bic.b   R15, &P1OUT         ; Send zero bit
           jmp     tx_bit              ; Next bit...
bit_high    bis.b   R15, &P1OUT         ; Send one bit
           jnz     tx_bit              ; If tx data is not zero, then there are more bits to send...
           ret                         ; Return when all bits sent         
                                       ; - Send a NULL terminated string
puts                                    ; Tx string using putc
           push    R11                 ;
           mov     R12, R11            ; String pointer in R12, copy to R11
putsloop                                ;
           mov.b   @R11+, R12          ; Get a byte, inc pointer
           tst.b   R12                 ; Test if end of string
           jz      putsx               ; Yes, exit...
           call    #putc               ; Call putc
           jmp     putsloop            ;
putsx       pop     R11                 ;
           ret                         ;
getc                                    ; - Get a char
           mov     &bit_dur, R14       ; Bit duration
           mov     &in_bit_mask, R13   ; Input bitmask
           mov     #0x01FF, R12        ; 9 bits - 8 data + stop

rx_start                                ; Wait for start bit
           mov     &P1IN, R15          ; Get serial input         
           and     R13, R15            ; Mask and test bit
           jc      rx_start            ; Wait for low...
           mov     &half_dur, R13      ; Wait for 1/2 bit time
rx_delay    nop                         ; Bit delay
           sub     #8, R13             ;
           jc      rx_delay            ;
           subc    R13, PC             ; 0 to 3 cycle delay
           nop                         ; 3
           nop                         ; 2
           nop                         ; 1
           mov     &P1IN, R15          ; Get serial input         
           and     &in_bit_mask, R15   ;
           rrc     R12                 ; Shift in a bit
           mov     R14, R13            ; Setup bit timer
           jc      rx_delay            ; Next bit...
           rla     R12                 ; Move stop bit to carry
           swpb    R12                 ; Move rx byte to lower byte, start bit in msb
           ret                         ; Return with rx char and start bit in R12, stop bit in carry
                                       ; Added by Mark
Red_On      bis.b   #00000001b,&P1OUT   ; set P1.6 (green on)
		ret							;
Red_Off     bic.b   #00000001b,&P1OUT   ; set P1.0 (red on)
Wait        mov.w   #31834,R10               ; load R10 with value for delay
L1          dec.w   R10                     ; decrement R10
           jnz     L1                      ; if R10 is not zero jump to L1
           .end                        ;

Link to post
Share on other sites

Very nice VoodooFish. Please submit it to the POTM.


the photo u took is excellent. did u use an SLR to do that? does it require a special lens?

Looks like a prime/fast lens (F2.80), by looking at the depth of focus. That is a very sharp plane.

Camera from Exif is : Canon EOS 30D

Link to post
Share on other sites

@simpleAVR, As bluehash pointed out , yes, an (older)DSLR. You could use most any zoom lens for this shot though I used a 24-70 F2.8L. I love this lens.... I shot this using a tripod and forgot to set the aperture to something (f8) to give more focus to the subject.

@bluehash will consider submitting. :)

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...