The attached message has been automatically discarded by the list server as the sender is coming via a nabble post and (presumably) not a list member. Posted as a service - please CC him directly if answering. I've advised him re needing to be a member. This is an olllllllllld thread so I have left all old message intact. Russell ---------- Forwarded message ---------- From: uxi To: piclist@mit.edu Date: Mon, 8 Mar 2010 10:23:10 -0800 (PST) Subject: [PIC] RE: Wiegand decoding and reading Hi Bill, I am also doing a project just like yours and would really appreciate if you can help me with the assembly code you wrote. Please do share the code here or give me alink so i can have a look on it. Basically i was trying to use Interrupts for reading data 0 and data 1 line from the reader but after reading ur reply i would like to see how u implemented it by POLLINg. Please Help and do share the code! Regards, Uzair Bill van Dijk wrote: > > 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