Skip to content

Libraries

steigeia edited this page May 10, 2017 · 3 revisions

Standard Arduino Libraries

My project uses 3 of the Standard Libraries from Arduino which can be found here. These libraries include the SPI, SD, and Wire libraries. The SPI library is used to allow the UNO to talk to other device using the SPI communication protocol. The Wire library is used to allow the UNO to talk to other device using the I2C communication protocol. You can learn more about the SPI and I2C communication protocol on the Communication Protocols page here. You can learn more about Arduino's SPI library here and Arduino's Wire library here. The SD library allows for the Arduino UNO to read from and write to SD cards utilizing SD slot like on the data logging shield. I mainly utilized the code from the Datalogger example which can be found here.

RTClib-master

The RTClib-master library can be found in the documentation for Adafruit data logger shield here or in my code repository here. This library communicates with a Real Time Clock through the I2C communications protocol by using the Wire library. In order to use the Real Time Clock, you need to set it to the correct time this can be done using the ds1307 example which can be found here. I also found this code to be a good over view of how to retrieve the current time from the Real Time Clock.

AddicoreRFID

The addicoreRfid library can be found with the documentation for the RC522 Module here or in my code repository here. This library lets the Arduino UNO communicate with RC522 Module through SPI communications. It can be a bit hard to understand how to do certain things using the library but the example in the library shows how to rea the UNIDs of RFID cards which is what is needed for this project. This example is the Addicore_RFID_Example and can be found here. There is one issue with the example code which can be seen below.

pinMode(chipSelectPin,OUTPUT);              // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin 
digitalWrite(chipSelectPin, LOW);           // Activate the RFID reader
pinMode(NRSTPD,OUTPUT);                     // Set digital pin 5, Not Reset and Power-down
digitalWrite(NRSTPD, HIGH);

The above code implies that in order to change which pins are used for SS and Reset can be changed just by setting their pin mode and value. The init function is what is supposed to do this and the library has a setup function for setting the SS and Reset pins. The correct way to use the library would be to use the setup function followed up by the init function which can be seen below.

//set the value for the Slave Select and the Reset pin then initialize
myRFID.Advanced_Setup_AddicoreRFID(chipSelectRFID, resetRFID);
myRFID.AddicoreRFID_Init();

Another 3 functions that are used are for finding, reading the UNID of, and selecting a RFID card. These function can be seen below.

myRFID.AddicoreRFID_Request(PICC_REQIDL , ret);
myRFID.AddicoreRFID_Anticoll(serNum);
myRFID.AddicoreRFID_SelectTag(serNum);

The PICC_REQUIDL searchs the antenna area and selects a card. In AddicoreRFID_Request(PICC_REQIDL , ret), ret is a unsigned char* that contains information about the type of RFID chip is in the card but this is not used in this project. In AddicoreRFID_Anticoll(serNum), serNum is an unsigned char* that contains the 4 byte UNID and a 1 byte checksum which should be the exclusive or of all 4 of the UNID bytes. This serNum is then used to select the card, if any were found by AddicoreRFID_Request(PICC_REQIDL , ret), by calling AddicoreRFID_SelectTag(serNum).

The next step is to see if the card uses the same security key which is done by the function call seen below.

stat = myRFID.AddicoreRFID_Auth(PICC_AUTHENT1A, key_addr, keyA, serNum);
if (stat == MI_OK) {//if it works read the id off of the card

In order to understand what this is doing you must first understand the internals of a MIFARE 1K Card which can be found here. The most basic knowledge that you need is that there are 16 sectors (0-15) of 4 block each going from block 0-63 with the 0 block be read only and containing the manufacturer data. Each block contains 16 individual bytes. The first 3 blocks of each sector (0-2) contain data while the 4 block (3) is a sector trailer which contains 2 6 byte access keys, Key A & Key B, as well as 3 bytes that determine the access level of those keys and 1 data byte. AddicoreRFID_Auth(PICC_AUTHENT1A, key_addr, keyA, serNum) makes it so that you can read and write data to certain parts of the RFID card as long as the correct information is entered. The key_addr needs to be the fourth block of a sector, in my code it is block 7 witch is the sector trailer for sector 1. It is important that key-addr is the sector trailer for the sector you want to read/write because the authorization only works for one sector at a time. In my case I am reading from and writing to block 4 and 7 which are both in sector 1 so I made sure that I choose the sector trailer of sector 1. keyA needs to be the correct Key A for that sector trailer. It also possible to use Key B depending an the access bit but you would need to change PICC_AUTHENT1A to PICC_AUTHENT1B. If everything has gone right after that function call, there was a card and the authorization worked, then stat should be MI_OK which is explained down below.

Once the sector has been authorize, that sector of the RFID card can now be read from or written to as seen the code below.

myRFID.AddicoreRFID_Write(ID_addr, cardID);
myRFID.AddicoreRFID_Read(ID_addr, ret);

for AddicoreRFID_Write(ID_addr, cardID), cardID is the 16 byte array that is written to block ID_addr. for AddicoreRFID_Read(ID_addr, ret), ret is the 16 byte array that is read from block ID_addr.

All of these functions except AddicoreRFID_SelectTag(serNum) return a status btye which can be one of the following values.

//AddicoreRFID error codes
#define MI_OK                   0
#define MI_NO_TAG_ERR           1
#define MI_ERR                  2

AddicoreRFID_SelectTag(serNum) returns the capacity of the card instead of one of the error codes listed above.

The final functions that are used are AddicoreRFID_Halt() and ClearBitMask(Status2Reg, 0x08) which effectively allow the card and reader to be used again. AddicoreRFID_Halt() end the communication protocol on the RFID chip side while ClearBitMask(Status2Reg, 0x08) resets the transmission status of the RC522 chip so that i can communcate with a new RFID chip.

AESLib

the AESLib can be download from here and can be found in the github code here. The only time that this library is used can be seen below.

aes128_enc_single(crypt_key, ret);

This function takes in a 16 byte array as a crypt_key which is used to encrypt ret which is also a 16 byte array