lewtwo wrote:This is an API to read RFID cards using a standard Wiegand Protocol HID reader. Only two wires are needed and no additional hardware.
I did a quick code review and I found some places that could be improved. It is up to you if you want to take these changes but I thought I would pass them on as they are also instructive for other people.
Here are the first three things that hit me:
1. The multitasking and sharing of variable seems very dependent on the hardware protocol. You may want to look at writing more robust code that uses a semaphore to access the shared memory.
2. There are a number of hard-coded constants and dependent constants that could be stored in a lookup table.
3. The line
Code: Select all
J=Shl(J,1) 'same as multiplying by 2
looks a bit incongruous. This shift left is hardly going to save any time. Then looking at the problem further I realized that you could eliminate the calculate loop and save memory as well.
The basic problem is that you are using an array of bytes rather than bits and not using the
Alias feature of ZBasic. This is a very powerful feature that allows the memory for variables to be overlaid, within some constraints. Here is the declarations reusing some of your variable names. Note the 4 aliases of UnsignedLongs with byte alignment.
Code: Select all
Private RfidIdx as Byte
Private Const RFID_MAX_BITS as Byte = 64
Private ByteAlign RFIDQue(1 To RFID_MAX_BITS) As Bit
Private RFIDValues(1 to RFID_MAX_BITS\8) As Byte Alias RFIDQue(1) ' only used for initialization
Private RFCODE26 as UnsignedLong Alias RFIDQue(1)
Private RFCODE34 as UnsignedLong Alias RFIDQue(1)
Private RFID26 as UnsignedLong Alias RFIDQue(9)
Private RFID34 as UnsignedLong Alias RFIDQue(17)
I initialized the array of 64 bits as follows to provide a test case:
Code: Select all
' initialize bit values
RFIDValues(1) = FlipBits(&H07)
RFIDValues(2) = FlipBits(&H08)
RFIDValues(3) = FlipBits(&H40)
RFIDValues(4) = FlipBits(&HA6)
RFIDValues(5) = FlipBits(&H80)
RFIDValues(6) = FlipBits(&H00)
RFIDValues(7) = FlipBits(&H00)
RFIDValues(8) = FlipBits(&H00)
Here is the rewrite of the function to retrieve the ID without a loop. Note the shifts to get the correct 15/16 bits and the method to convert the big-endian bit format to a little-endian number. There is a small bug in this code for 26-bit devices - I will leave it to you resolve it.
Code: Select all
Public Function RfIDDec2() as UnsignedLong
Dim Val As UnsignedInteger
Select Case RfidIdx
Case 26
RfIDDec2 = RFID26
Val = CUInt(Shr(RfIDDec2,1))
RfIDDec2 = CULng(MakeWord(FlipBits(HiByte(Val)), FlipBits(LoByte(Val))))
Case 34
RfIDDec2 = RFID34
Val = CUInt(Shr(RfIDDec2,1))
RfIDDec2 = CULng(MakeWord(FlipBits(HiByte(Val)), FlipBits(LoByte(Val))))
Case Else
RfIDDec2=0
End Select
End Function
Here is the simplified code to retrieve the facility code that uses a similar mechanism of bit shifts and endian flipping to retrieve the correct code as an unsigned long:
Code: Select all
Public Function RfIDFacility2() as UnsignedLong
Dim Val As UnsignedInteger
Select Case RfidIdx
Case 26
RfIDFacility2 = RFCODE26
Val = CUInt(Shl(Shr(RfIDFacility2,1),7))
RfIDFacility2 = CULng(MakeWord(FlipBits(HiByte(Val)), FlipBits(LoByte(Val))))
Case 34
RfIDFacility2 = RFCODE34
Val = CUInt(Shr(RfIDFacility2,1))
RfIDFacility2 = CULng(MakeWord(FlipBits(HiByte(Val)), FlipBits(LoByte(Val))))
Case Else
RfIDFacility2=0
End Select
End Function
There is a more cleanup that could be applied to this code but I wanted to give you an initial idea of the 9x speedup that can be achieved and leave the rest to you. Here are some performance results in microseconds for the old and new code:
[table]
[row][mcol]Card Type[mcol]Old Code[mcol]Improved Code
[row]Facility Code[col]26[col]373[col]59
[row]ID[col]26[col]531[col]57
[row]Facility Code[col]34[col]623[col]63
[row]ID[col]34[col]580[col]63
[/table]
Mike Perks
Check out the new ZX-128e and ZX-1281e ZBasic devices at
OakMicros.com