NatureTM 100 Posted March 7, 2011 Share Posted March 7, 2011 I saw touch ported some rfid reader code to msp430, and so I thought I'd share what I've got for the Parallax RFID reader. The code is a bit bloated and inefficient, but it seems to work well. It compiles from about 1300B to 1500B program size in CCS, depending on if optimization is used, and uses 60B RAM. Most of the work is done in software, so TimerA and the USI are free. I couldn't get it to run at 1MHz, so you'll need an MSP430 with calibration constants or a clock source. It works fine at 8MHz or higher. I used a voltage divider to bring the reader's 5V data line down, and powered the reader with my launchpad's TP1 and TP4 test points. #include "msp430g2231.h" #include #define PIN_RFID_DATA BIT7 // normally high #define PIN_RFID_ENABLE BIT4 // active LOW #define PIN_LED BIT0 #define RFID_BAUD 2400 #define MCLK_FREQUENCY 8000000 #define WDT_DIVIDER 512 #define BYTES_PER_MESSAGE 12 #define BYTES_PER_TAG 10 #define N_ALLOWED_TAGS 1 #define RESULT_SUCCESS 0 #define RESULT_TIMEOUT 1 #define RESULT_ERROR 2 #define RESULT_NO_DATA 3 #define READER_WARMUP 800 #define MIDSCAN_TIMEOUT 200 const char tags[N_ALLOWED_TAGS][bYTES_PER_TAG] = {'3', '6', '0', '0', '6', '2', '2', 'B', 'A', 'E'}; const unsigned long WDT_FREQUENCY = MCLK_FREQUENCY / WDT_DIVIDER; volatile unsigned long wdtCounter = 0; unsigned int stateCount; char rfidData[bYTES_PER_MESSAGE] = {0}; char rfidByte; char bitIndex = 0; char newByte = 0; volatile char haveNewByte = false; volatile char busy = false; char wdtTicksPerBit; unsigned long millis(){ return wdtCounter / ((float)WDT_FREQUENCY / 1000); } void delayMillis(unsigned long milliseconds){ unsigned long wakeTime = wdtCounter + (milliseconds * WDT_FREQUENCY / 1000); while(wdtCounter < wakeTime); } void addBits(char n, char state){ int i; if(state) for(i = 0; i < n; i++){ rfidByte |= 0x01 << bitIndex; bitIndex++; } else for(i = 0; i < n; i++){ rfidByte &= ~(0x01 << bitIndex); bitIndex++; } } char scanTag(){ unsigned long timeout = millis() + READER_WARMUP; char byteIndex = 0; P1OUT &= ~PIN_RFID_ENABLE; while(!haveNewByte){ if(millis() > timeout){ P1OUT |= PIN_RFID_ENABLE; busy = false; return RESULT_NO_DATA; } } if(newByte == 0x0A){ while(byteIndex < BYTES_PER_MESSAGE){ timeout = millis() + MIDSCAN_TIMEOUT; rfidData[byteIndex] = newByte; byteIndex++; haveNewByte = false; while(!haveNewByte){ if(millis() > timeout){ P1OUT |= PIN_RFID_ENABLE; busy = false; return RESULT_TIMEOUT; } } } P1OUT |= PIN_RFID_ENABLE; return RESULT_SUCCESS; } else{ P1OUT |= PIN_RFID_ENABLE; haveNewByte = false; busy = false; return RESULT_ERROR; } } char isValidTag(){ char iTag; char iByte; char valid = true; for(iTag = 0; iTag < N_ALLOWED_TAGS; iTag++){ for(iByte = 0; iByte < BYTES_PER_TAG & valid; iByte++){ if(rfidData[iByte + 1] != tags[iTag][iByte]) valid = false; } } return valid; } void handleMessage(){ if(isValidTag()) P1OUT ^= PIN_LED; } void main(void){ DCOCTL = CALDCO_8MHZ; BCSCTL1 = CALBC1_8MHZ; WDTCTL = WDTPW + WDTTMSEL + WDTIS1;// + WDTIS0; IE1 |= WDTIE; // Enable WDT interrupt wdtTicksPerBit = ((float)WDT_FREQUENCY / RFID_BAUD); P1IE |= PIN_RFID_DATA; P1IES |= PIN_RFID_DATA; P1DIR |= PIN_RFID_ENABLE + PIN_LED; P1OUT |= PIN_RFID_ENABLE + PIN_LED; _BIS_SR(GIE); // enable interrupts while(1){ switch(scanTag()){ case RESULT_SUCCESS: handleMessage(); delayMillis(1000); break; case RESULT_NO_DATA: delayMillis(1000); break; // nothing here for RESULT_ERROR // just scan the tag again right away } } } #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void){ stateCount++; wdtCounter++; } #pragma vector=PORT1_VECTOR __interrupt void Port1(void){ static char state; unsigned int nBits; P1IES ^= PIN_RFID_DATA; // capture both edges P1IFG &= ~PIN_RFID_DATA; if(!busy){ bitIndex = 0; busy = true; state = 0; stateCount = wdtTicksPerBit * -1; // ignore start bit } else{ nBits = (stateCount / wdtTicksPerBit); // trim off the stop bit if the last data bit is also a "1" // maybe catch some other unexpected behavior too if(nBits + bitIndex > 8) nBits = 8 - bitIndex; addBits(nBits, state); state ^= BIT0; stateCount = 0; } if(bitIndex == 8){ busy = false; newByte = rfidByte; haveNewByte = true; } } This was part of a project I was working on to tweet when my cats poop. I was using some RF Link boards from eBay so I wouldn't need a data connection to the litter box. It turns out RF Links are very noisy, and the code for wireless was just too big for my 2K flash MSP430's. I've got some 8K's on order, but for now my cats' bowel movements will continue to remain a mystery. gatesphere and GeekDoc 2 Quote Link to post Share on other sites
bluehash 1,581 Posted March 7, 2011 Share Posted March 7, 2011 This was part of a project I was working on to tweet when my cats poop. I was using some RF Link boards from eBay so I wouldn't need a data connection to the litter box. It turns out RF Links are very noisy, and the code for wireless was just too big for my 2K flash MSP430's. I've got some 8K's on order, but for now my cats' bowel movements will continue to remain a mystery. Thanks for sharing NTM. How do you know if your cats poop? weight? Quote Link to post Share on other sites
NatureTM 100 Posted March 7, 2011 Author Share Posted March 7, 2011 Nah, I was just going to see when they came and left the litter box and send it to twitter. Maybe have some special messages if they're in there for awhile. It's just a goofy project to give myself a little entertainment. Quote Link to post Share on other sites
zeke 693 Posted March 8, 2011 Share Posted March 8, 2011 Tweeting a Cat poop event. Now I've heard everything. You need a hobby Man! Or a girlfriend. That'll distract you. Quote Link to post Share on other sites
bluehash 1,581 Posted March 8, 2011 Share Posted March 8, 2011 Or a girlfriend. That'll distract you. He already does. Quote Link to post Share on other sites
NatureTM 100 Posted March 8, 2011 Author Share Posted March 8, 2011 You need a hobby Man! Or a girlfriend. That'll distract you. This is my hobby! What I need is exercise. :-) I've been telling my girlfriend to distract me more! Quote Link to post Share on other sites
GeekDoc 226 Posted March 10, 2011 Share Posted March 10, 2011 I ordered some sample RFID "keychains" from TI that should work with the Parrallax reader (that's what I got them for). They are small, black cylinders, maybe 4mm diameter, about 25-30mm long, with a hole through one end (comes on a "spiral-ring" key ring). I mention this because they might fit well on a cat's collar. http://focus.ti.com/docs/prod/folders/print/ri-trp-rfob.html Quote Link to post Share on other sites
NatureTM 100 Posted March 10, 2011 Author Share Posted March 10, 2011 I mention this because they might fit well on a cat's collar. Hey thanks doc, but I already bought the RFID keychanins from Parallax's site. Quote Link to post Share on other sites
GeekDoc 226 Posted March 11, 2011 Share Posted March 11, 2011 Hey thanks doc, but I already bought the RFID keychanins from Parallax's site. Even though you had to pay for them, you have the big advantage of knowing they will work! Quote Link to post Share on other sites
cde 334 Posted March 17, 2011 Share Posted March 17, 2011 I ordered some sample RFID "keychains" from TI that should work with the Parrallax reader (that's what I got them for). They are small, black cylinders, maybe 4mm diameter, about 25-30mm long, with a hole through one end (comes on a "spiral-ring" key ring). I mention this because they might fit well on a cat's collar. http://focus.ti.com/docs/prod/folders/print/ri-trp-rfob.html The TI tags say that they are 134khz tags. The Parrallax RFID reader uses 125khz tags. Quote Link to post Share on other sites
GeekDoc 226 Posted March 17, 2011 Share Posted March 17, 2011 The TI tags say that they are 134khz tags. The Parrallax RFID reader uses 125khz tags. Darn! I just saw they were in "Low Frequency" range, I hadn't looked up the specifics on either part. :oops: Just rolling the dice, I guess. These fobs are nice, though; I may eventually have to work on a reader for them. :? Quote Link to post Share on other sites
TheDirty 33 Posted March 18, 2011 Share Posted March 18, 2011 Anybody work with some reader IC's? Looking on digikey there seems to be some low parts count chips for RFID reading that are around $7. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.