Thanks. The problem was solved yesterday. It was quite stupid actually. There was some additional code on the interrupt that on a given condition took more than 50uS to execute. If, a pulse was received while on this particular condition, the pulse will be lost and I'll miss a bit of information. Regarding the IF that you mentioned. It's to provide additional security when reading the card. It's just some way to make sure you are not reading garbage. Regards, > -----Original Message----- > From: piclist-bounces@mit.edu [mailto:piclist-bounces@mit.edu] On > Behalf Of Bill van Dijk > Sent: Wednesday, January 23, 2008 20:42 > To: 'Microcontroller discussion list - Public.' > Subject: RE: [PIC] Wiegand decoding and reading > > 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 -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist