/** * @brief Converted RFID Tag Arduino code * @author Michael Burmeister * @date February 10, 2018 * @version 1.0 * */ #include "simpletools.h" #include "fdserial.h" //Forward Functions defines void setup(void); void loop(void); char rfidRead(uint8_t *, uint8_t); char rfidWrite(uint8_t , uint8_t *); char rfidLogin(uint8_t *); char rfidSetPass(uint8_t *, uint8_t *); char rfidProtect(uint8_t enable); char rfidReset(void); char rfidReadLegacy(uint8_t *); void rfidFlush(void); void PrintHex(uint8_t *, uint8_t); #define rxPin 11 // Serial input (connects to the RFID's SOUT pin) #define txPin 10 // Serial output (connects to the RFID's SIN pin) #define BUFSIZE 12 // Size of receive buffer (in bytes) for incoming data from the RFID R/W Module (this should be adjusted to be larger than the expected response) // RFID R/W Module Commands // Number of bytes returned in () #define RFID_Read 0x01 // Read data from specified address, valid locations 1 to 33 (5) #define RFID_Write 0x02 // Write data to specified address, valid locations 3 to 31 (1) #define RFID_Login 0x03 // Login to tag with password (1) #define RFID_SetPass 0x04 // Change tag's password from old to new (1) #define RFID_Protect 0x05 // Enable/disable password protection (1) #define RFID_Reset 0x06 // Reset tag (1) #define RFID_ReadLegacy 0x0F // Read unique ID from EM4102 read-only tag (for backwards compatibility with Parallax RFID Card Reader #28140) (12) // Memory map/address locations for EM4x50 tag // Each address holds/returns a 32-bit (4 byte) value #define ADDR_Password 0 // Password (not readable) #define ADDR_Protect 1 // Protection Word #define ADDR_Control 2 // Control Word // ADDR 3-31 are User EEPROM area #define ADDR_Serial 32 // Device Serial Number #define ADDR_DeviceID 33 // Device Identification // Status/error return codes #define ERR_OK 0x01 // No errors #define ERR_LIW 0x02 // Did not find a listen window #define ERR_NAK 0x03 // Received a NAK, could be invalid command #define ERR_NAK_OLDPW 0x04 // Received a NAK sending old password (RFID_SetPass), could be incorrect password #define ERR_NAK_NEWPW 0x05 // Received a NAK sending new password (RFID_SetPass) #define ERR_LIW_NEWPW 0x06 // Did not find a listen window after setting new password (RFID_SetPass) #define ERR_PARITY 0x07 // Parity error when reading data // For use with RFID_ReadLegacy command #define LEGACY_StartByte 0x0A #define LEGACY_StopByte 0x0D #define IN 1 #define OUT 0 //set_direction(11, IN); Not needed //set_direction(10, OUT); Not needed fdserial *rfidSerial; int main() { // set up a new serial port //SoftwareSerial rfidSerial = SoftwareSerial(rxPin, txPin); rfidSerial = fdserial_open(rxPin, txPin, FDSERIAL_MODE_NONE, 9600); setup(); loop(); while(1) { // Add main loop code here. } } void setup() // Set up code called once on start-up { // define pin modes //while (!serial); // wait until ready print("\n\nParallax RFID Read/Write Module\n"); // set the baud rate for the SoftwareSerial port //rfidSerial.begin(9600); //flush(); // wait for all bytes to be transmitted to the Serial Monitor } void loop() // Main code, to run repeatedly { char idx; uint8_t rfidData[BUFSIZE]; // Buffer for incoming data /* Code blocks can be commented/uncommented/rearranged to experiment with the available features and operations of the Parallax RFID Read/Write Module */ print("Reading tag's unique serial number..."); while (rfidRead(rfidData, ADDR_Serial) != 0); PrintHex(rfidData, 4); // The rfidData string should now contain the tag's serial number, so display it on the Serial Monitor // println(); print("\n"); // flush(); print("Writing and verifying data to tag..."); while (rfidWrite(3, (uint8_t*)"\xFE\xED\xFA\xCE") != 0); // Write specified bytes into address 3 (user EEPROM area) // println("Done!"); print("Done!\n"); // flush(); print("Reading tag's entire memory contents:\n"); for (idx = 1; idx <= 33; idx++) // For each valid address location { while (rfidRead(rfidData, idx) != 0); // Read the data // print(idx, DEC); print("%d", idx); print(": "); PrintHex(rfidData, 4); // The rfidData string should now contain the data from the specific address, so display it on the Serial Monitor // println(); print("\n"); // flush(); } // Login is only required to take advantage of the password protection features // For example, to set the tag's password, lock/unlock the tag, or read/write the tag (if the tag is locked) print("Logging into the tag..."); while (rfidLogin((uint8_t*)"\x00\x00\x00\x00") != 0); // Login to tag with default password of 0x00000000 // println("Done!"); print("Done!\n"); // flush(); /* Serial.print("Changing the tag's password..."); while (rfidSetPass((uint8_t*)"\x00\x00\x00\x00", (uint8_t*)"\x00\x00\x00\x00") != 0); // Change password from current (0x00000000) to new (0x00000000) serial.println("Done!"); serial.flush(); print("Locking tag..."); while (rfidProtect(true) != 0); // Enable read/write password protection of the entire tag println("Done!"); flush(); print("Unlocking tag..."); while (rfidProtect(false) != 0); // Enable read/write password protection of the entire tag println("Done!"); flush(); print("Resetting the tag..."); while (rfidReset() != 0); // Log out and reset the tag (will require a re-login if trying to access a locked tag after this point) println("Done!"); flush(); */ /*print("Reading legacy tag's unique serial number..."); // Read unique ID from EM4102 read-only tag (used with the Parallax RFID Card Reader #28140) while (rfidReadLegacy(rfidData) != 0); println((char*)rfidData); // The rfidData string should now contain the tag's unique ID with a null termination, so display it on the Serial Monitor flush();*/ while(1); // Stay here when the demonstration is over } /*** SUPPORTING FUNCTIONS ***/ char rfidRead(uint8_t *data, uint8_t address) { char offset; // offset into buffer rfidFlush(); // empties any buffered incoming serial data // rfidSerial.print("!RW"); // header // rfidSerial.write(RFID_Read); // command // rfidSerial.write(address); // address dprint(rfidSerial, "!RW"); fdserial_txChar(rfidSerial, RFID_Read); fdserial_txChar(rfidSerial, address); // while (rfidSerial.available() != 5); // wait until data is received from RFID module while (fdserial_rxCount(rfidSerial) != 5); // if (rfidSerial.read() == ERR_OK) // if our status byte is OK if (fdserial_rxChar(rfidSerial) == ERR_OK) { for (offset = 0; offset < 4; offset++) // data[offset] = rfidSerial.read(); // get the remaining data data[offset] = fdserial_rxChar(rfidSerial); return 0; // return good } return -1; // return error } char rfidWrite(uint8_t address, uint8_t *data) { char offset; // offset into buffer rfidFlush(); // empties any buffered incoming serial data // rfidSerial.print("!RW"); // header // rfidSerial.write(RFID_Write); // command // rfidSerial.write(address); // address dprint(rfidSerial, "!RW"); fdserial_txChar(rfidSerial, RFID_Write); fdserial_txChar(rfidSerial, address); for (offset = 0; offset < 4; offset++) //rfidSerial.write(data[offset]); // data (4 bytes) fdserial_txChar(rfidSerial, data[offset]); // while (rfidSerial.available() == 0); // wait until data is received from RFID module while (fdserial_rxCount(rfidSerial) == 0); // if (rfidSerial.read() == ERR_OK) // if our status byte is OK if (fdserial_rxChar(rfidSerial) == ERR_OK) return 0; // return good return -1; // return error } char rfidLogin(uint8_t *password) { char offset; // offset into buffer rfidFlush(); // empties any buffered incoming serial data // rfidSerial.print("!RW"); // header // rfidSerial.write(RFID_Login); // command dprint(rfidSerial, "!RW"); fdserial_txChar(rfidSerial, RFID_Login); for (offset = 0; offset < 4; offset++) // rfidSerial.write(password[offset]); // password (4 bytes) fdserial_txChar(rfidSerial, password[offset]); // while (rfidSerial.available() == 0); // wait until data is received from RFID module while (fdserial_rxCount(rfidSerial) == 0); // if (rfidSerial.read() == ERR_OK) // if our status byte is OK if (fdserial_rxChar(rfidSerial) == ERR_OK) return 0; // return good return -1; // return error } char rfidSetPass(uint8_t *currentpass, uint8_t *newpass) { char offset; // offset into buffer rfidFlush(); // empties any buffered incoming serial data // rfidSerial.print("!RW"); // header // rfidSerial.write(RFID_SetPass); // command dprint(rfidSerial, "!RW"); fdserial_txChar(rfidSerial, RFID_SetPass); for (offset = 0; offset < 4; offset++) // rfidSerial.write(currentpass[offset]); // current password (4 bytes) fdserial_txChar(rfidSerial, currentpass[offset]); for (offset = 0; offset < 4; offset++) // rfidSerial.write(newpass[offset]); // new password (4 bytes) fdserial_txChar(rfidSerial, newpass[offset]); // while (rfidSerial.available() == 0); // wait until data is received from RFID module while (fdserial_rxCount(rfidSerial) == 0); // if (rfidSerial.read() == ERR_OK) // if our status byte is OK if (fdserial_rxChar(rfidSerial) == ERR_OK) return 0; // return good return -1; // return error } char rfidProtect(uint8_t enable) { rfidFlush(); // empties any buffered incoming serial data // rfidSerial.print("!RW"); // header // rfidSerial.write(RFID_Protect); // command dprint(rfidSerial, "!RW"); fdserial_txChar(rfidSerial, RFID_Protect); if (enable == 0) // flag // rfidSerial.write((byte)0); fdserial_txChar(rfidSerial, 0); else // rfidSerial.write((byte)1); fdserial_txChar(rfidSerial, 1); // while (rfidSerial.available() == 0); // wait until data is received from RFID module while (fdserial_rxCount(rfidSerial) == 0); // if (rfidSerial.read() == ERR_OK) // if our status byte is OK if (fdserial_rxChar(rfidSerial) == ERR_OK) return 0; // return good return -1; // return error } char rfidReset() { rfidFlush(); // empties any buffered incoming serial data // rfidSerial.print("!RW"); // header // rfidSerial.write(RFID_Reset); // command dprint(rfidSerial, "!RW"); fdserial_txChar(rfidSerial, RFID_Reset); // while (rfidSerial.available() == 0); // wait until data is received from RFID module while (fdserial_rxCount(rfidSerial) == 0); // if (rfidSerial.read() == ERR_OK) // if our status byte is OK if (fdserial_rxChar(rfidSerial) == ERR_OK) return 0; // return good return -1; // return error } char rfidReadLegacy(uint8_t *data) { char offset; // offset into buffer rfidFlush(); // empties any buffered incoming serial data // rfidSerial.print("!RW"); // header // rfidSerial.write(RFID_ReadLegacy); // command dprint(rfidSerial, "!RW"); fdserial_txChar(rfidSerial, RFID_ReadLegacy); // while (rfidSerial.available() != 12); // wait until data is received from RFID module while (fdserial_rxCount(rfidSerial) != 12); // if (rfidSerial.read() == LEGACY_StartByte) // if our start byte is OK if (fdserial_rxChar(rfidSerial) == LEGACY_StartByte) { for (offset = 0; offset < 10; offset++) // data[offset] = rfidSerial.read(); // get the remaining data data[offset] = fdserial_rxChar(rfidSerial); data[offset] = 0; // null terminate the string of bytes we just received return 0; // return good } return -1; // return error } void rfidFlush() // Empties any buffered incoming serial data { // while (rfidSerial.available() > 0) // rfidSerial.read(); fdserial_rxFlush(rfidSerial); } // from http://forum.arduino.cc/index.php?topic=38107#msg282343 void PrintHex(uint8_t *data, uint8_t length) // prints 8-bit data in hex { char tmp[length*2+1]; uint8_t first ; int j=0; for (uint8_t i=0; i> 4) | 48; if (first > 57) tmp[j] = first + 39; else tmp[j] = first ; j++; first = (data[i] & 0x0F) | 48; if (first > 57) tmp[j] = first + 39; else tmp[j] = first; j++; } tmp[length*2] = 0; print(tmp); }