I just finished a project exactly like yours, although I did my code in assembler. I did not use the interrupt since there are two data lines to check. I used polling of the two ports. A data pulse is about 40us, with a 2ms spacing. A read can be considered completed after 100ms. I built a trap to catch cards with more than 26 bits, in which case my code does not try to process the data (which makes no sense anyway since the format is unknown), but simply displays the number of bits read. Most reader outputs are open collector outputs capable of sinking about 16mA. If you use the interrupt on change feature, make sure you disable the interrupt as soon as one occurs, and reset only once the data line has returned to high before resetting the interrupt again (or it may result in an incorrect interrupt as the line returns back to its high state). Your method of waiting is risky. The timing of the reader is too "loose". > if( (RX_TEMP != 0x03) && RX_TEMP ) // Both bits can't > be 1 or 0 at the same time *ERROR CONDITION* I'm not a C guy, but both output bits of the reader WILL be 1 in the normal rest state. They can never be both 0 though. Testing for this condition is redundant IMHO though. Your attachment reads: The parity is calculated as follow: Even parity: using bits 1 to 12 Odd parity: using bits 12 to 25 That is not exactly correct, the leading parity bit (0), includes itself, 0 - 12. The trailing parity bit (26) includes bits 13 - 26 inclusive. Checking the parity is actually surprisingly simple. In the even parity, count all the 1's (of the proper bits), and check the LSB of the register containing the count to be 0. For the odd parity it should be 1. I run mine of the internal RC oscillator, no problem at all. I also decode and do parity check, and drive an LCD all off that one PIC (16F628A) I hope this helps, Bill van Dijk > -----Original Message----- > From: piclist-bounces@mit.edu [mailto:piclist-bounces@mit.edu] On Behalf > Of Mauricio Jancic > Sent: Wednesday, January 23, 2008 5:56 AM > To: 'Microcontroller discussion list - Public.' > Subject: [PIC] Wiegand decoding and reading > > Hello, > > This mail is longer than I expected. I'm sorry for that. The basic > issue is about the IOC feature, specifically trying to read a wiegand > package. > > I'm trying to read a card number using a wiegand output reader. > > I'm using a PIC16F88x so I'm using the full portb interrupt on > change. The IOC is properly set on by setting ICB<1:0> bits, since I'm > using > RB0 and RB1. > > On the interrupt, when IOC is detected I have the following code: > > if( RBIF && RBIE ) > { > RX_TEMP = PORTB; // Read PORTB > RX_TEMP &= 0x03; // Leave only the necesary bits > > if( (RX_TEMP != 0x03) && RX_TEMP ) // Both bits can't > be 1 or 0 at the same time *ERROR CONDITION* > { > if( RX_TEMP & 0x01 ) // If RB0 is 1 > { > getCardData( 1 ); > } > else > { > getCardData( 0 ); > } > wait = 2; // Wait for > 500 uS > RBIE = 0; // Disable > IOC for the above time > timeout = 200; // Timeout end of > card (50 ms) > } > > RBIF=0; //Clear IOC bit > } > > > Well, that's the basic code. It's working mostly, except that every > once in a while, an interrupt generates but the code reads a bit > incorrectly. > The "wait" is used to avoid the IOC to interrupt when the wiegand > signals return to high level. Since the wiegand LOW pulse is aprox. 40-50 > uS > and the space between bits is 2mS, the 500uS should be fine. > > Once the 500uS have finished the IOC interrupt is enabled: > > RX_TEMP = PORTB; > RBIF = 0; > RBIE = 1; > > This procedure is to ensure that any interrupt is clear before > re-enabling the IOC. > > > Problems: > Once a read is finished, the firmware outputs a stream of data > trough the serial port (see attached file). The correct number of the card > should be FC 081 and Card No. 00695. As you can see, the number is read ok > most of the time, but the parity is not. > > Page 2 here explains how the parity should be. > http://www.hidcorp.com/documents/understandCardDataFormats_wp_en.pdf > > In the beginning I was using the internal oscillator, but that lead to > aprox. 4 to 6 *ERROR CONDITIONS* detected, when I change the oscillator to > 20 MHz external, that count went down to 0 to 1. That makes me wonder if > there should be something I'm missing about the whole IOC feature. > > Regards, > > Mauricio -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist