NFC
HAL Example
Device Compatibility
Overview
The NFC abstraction supports:
- Reading Info (All tags)
- Reading Page (MIFARE Ultralight & NTAG)
- Writing Page (MIFARE Ultralight & NTAG)
- Reading NDEF (MIFARE Ultralight & NTAG)
- Writing NDEF (MIFARE Ultralight & NTAG)
Code Examples
Below are examples of how to use NFC in MATRIX HAL.
NFC function references can be found here.
The command below will compile each example. Be sure to pass in your C++ file and desired output file.
g++ -o YOUR_OUTPUT_FILE YOUR_CPP_FILE -std=c++11 -DNXPBUILD__PH_RASPBERRY_PI -I/usr/local/include/matrix_nfc/nxp_nfc/NxpNfcRdLib/types -I/usr/local/include/matrix_nfc/nxp_nfc/NxpNfcRdLib/intfs -lmatrix_hal_nfc -lmatrix_creator_hal
NFC Detect & ReadInfo
The following example shows how to perform basic NFC tag detection and read information such as the UID from an NFC tag. You can download this example here.
///////////////////////// // INCLUDE STATEMENTS // /////////////////////// // For console output #include <iostream> // For sleep #include <chrono> #include <thread> // For using the Everloop #include "matrix_hal/everloop.h" #include "matrix_hal/everloop_image.h" #include "matrix_hal/matrixio_bus.h" // For using NFC #include "matrix_nfc/nfc.h" #include "matrix_nfc/nfc_data.h" int main() { //////////////////// // INITIAL SETUP // ////////////////// // Setting up HAL bus matrix_hal::MatrixIOBus bus; if (!bus.Init()) return false; // Setting up Everloop matrix_hal::EverloopImage everloop_image(bus.MatrixLeds()); matrix_hal::Everloop everloop; everloop.Setup(&bus); // Setting up NFC matrix_hal::NFC nfc; matrix_hal::NFCData nfc_data; ///////////////// // MAIN CODE // /////////////// std::cout << "Scan a tag, any tag!" << std::endl; do { // Scan NFC tag and read info into nfc_data.info nfc.Activate(); nfc.ReadInfo(&nfc_data.info); nfc.Deactivate(); // Output tag info and set everloop to green only if tag was detected, // else set everloop to off. if (nfc_data.info.recently_updated) { std::cout << nfc_data.info.ToString() << std::endl << std::endl; for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 0; led.green = 20; led.blue = 0; led.white = 0; } } else { for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 0; led.green = 0; led.blue = 0; led.white = 0; } } // Update the Everloop everloop.Write(&everloop_image); // Sleep for a reasonable amount of time std::this_thread::sleep_for(std::chrono::microseconds(10000)); } while (true); return 0; }
NFC Rainbow Toggle
The following example shows how to use an NFC tag to toggle the movement of the rainbow on Everloop. You can download this example here.
///////////////////////// // INCLUDE STATEMENTS // /////////////////////// // For console output #include <iostream> // For sleep #include <chrono> #include <thread> // For sine #include <cmath> // For string #include <string> // For using the Everloop #include "matrix_hal/everloop.h" #include "matrix_hal/everloop_image.h" #include "matrix_hal/matrixio_bus.h" // For using NFC #include "matrix_nfc/nfc.h" #include "matrix_nfc/nfc_data.h" int main() { //////////////////// // INITIAL SETUP // ////////////////// // Setting up HAL bus matrix_hal::MatrixIOBus bus; if (!bus.Init()) return false; // Setting up Everloop matrix_hal::EverloopImage everloop_image(bus.MatrixLeds()); matrix_hal::Everloop everloop; everloop.Setup(&bus); // Setting up NFC matrix_hal::NFC nfc; matrix_hal::NFCData nfc_data; ///////////////// // MAIN CODE // /////////////// std::cout << "Scan ON/OFF Tag" << std::endl; // Loop until a tag is detected and the info from it is read while (true) { if (nfc_data.info.recently_updated) break; nfc.Activate(); nfc.ReadInfo(&nfc_data.info); nfc.Deactivate(); } // Get the UID from the tag std::string switchUID = nfc_data.info.UIDToHex(); std::cout << "ON/OFF Tag Scanned!" << std::endl; float counter = 0; const float freq = 0.375; std::cout << "Scan the same tag to update rainbow." << std::endl; do { // Scan NFC tag and read info into nfc_data.info nfc.Activate(); nfc.ReadInfo(&nfc_data.info); nfc.Deactivate(); // Update the rainbow on everloop only if a a tag was detected and the // UID of the detected tag matches the initial scanned tag. if (nfc_data.info.recently_updated) { std::string currUID = nfc_data.info.UIDToHex(); if (switchUID == currUID) { for (matrix_hal::LedValue &led : everloop_image.leds) { // Sine waves 120 degrees out of phase for rainbow led.red = (std::sin(freq * counter + (M_PI / 180 * 240)) * 155 + 100) / 10; led.green = (std::sin(freq * counter + (M_PI / 180 * 120)) * 155 + 100) / 10; led.blue = (std::sin(freq * counter + 0) * 155 + 100) / 10; counter += 0.51; } } } // Update the Everloop everloop.Write(&everloop_image); // Sleep for a reasonable amount of time std::this_thread::sleep_for(std::chrono::microseconds(5000)); } while (true); return 0; }
NFC Unique Color Toggle
The following example shows how to use the UID of NFC tags to conditionally perform action depending on which tag is scanned. You can download this example here.
///////////////////////// // INCLUDE STATEMENTS // /////////////////////// // For console output #include <iostream> // For sleep #include <chrono> #include <thread> // For string #include <string> // For set #include <set> // For using the Everloop #include "matrix_hal/everloop.h" #include "matrix_hal/everloop_image.h" #include "matrix_hal/matrixio_bus.h" // For using NFC #include "matrix_nfc/nfc.h" #include "matrix_nfc/nfc_data.h" int main() { //////////////////// // INITIAL SETUP // ////////////////// // Setting up HAL bus matrix_hal::MatrixIOBus bus; if (!bus.Init()) return false; // Setting up Everloop matrix_hal::EverloopImage everloop_image(bus.MatrixLeds()); matrix_hal::Everloop everloop; everloop.Setup(&bus); // Setting up NFC matrix_hal::NFC nfc; matrix_hal::NFCData nfc_data; ///////////////// // MAIN CODE // /////////////// // Set used to check for uniqueness std::set<std::string> UID_set; // Strings to store the unique UID for three tags. std::string green_UID = ""; std::string blue_UID = ""; std::string red_UID = ""; // Scan red tag, using a set to ensure that the UID has not been scanned // before. Loop until a unique UID has been scanned. std::cout << "Scan Red Tag" << std::endl; while (true) { nfc.Activate(); nfc.ReadInfo(&nfc_data.info); nfc.Deactivate(); red_UID = nfc_data.info.UIDToHex(); // If the find function returns UID_set.end() then the UID was not // previously read. if (nfc_data.info.recently_updated && UID_set.find(red_UID) == UID_set.end()) break; } UID_set.insert(red_UID); // Scan green tag, using a set to ensure that the UID has not been scanned // before. Loop until a unique UID has been scanned. std::cout << "Scan Green Tag" << std::endl; while (true) { nfc.Activate(); nfc.ReadInfo(&nfc_data.info); nfc.Deactivate(); green_UID = nfc_data.info.UIDToHex(); // If the find function returns UID_set.end() then the UID was not // previously read. if (nfc_data.info.recently_updated && UID_set.find(green_UID) == UID_set.end()) break; } UID_set.insert(green_UID); // Scan blue tag, using a set to ensure that the UID has not been scanned // before. Loop until a unique UID has been scanned. std::cout << "Scan Blue Tag" << std::endl; while (true) { nfc.Activate(); nfc.ReadInfo(&nfc_data.info); nfc.Deactivate(); blue_UID = nfc_data.info.UIDToHex(); // If the find function returns UID_set.end() then the UID was not // previously read. if (nfc_data.info.recently_updated && UID_set.find(blue_UID) == UID_set.end()) break; } UID_set.insert(blue_UID); std::cout << "\nScan specified tags to activate Everloop" << std::endl; do { // Scan NFC tag and read info into nfc_data.info nfc.Activate(); nfc.ReadInfo(&nfc_data.info); nfc.Deactivate(); // If tag was detected set everloop to the color that matches the // scanned tag's UID, else set everloop to off. if (nfc_data.info.recently_updated) { std::string curr_UID = nfc_data.info.UIDToHex(); if (curr_UID == red_UID) { for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 50; led.green = 0; led.blue = 0; led.white = 0; } } else if (curr_UID == green_UID) { for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 0; led.green = 50; led.blue = 0; led.white = 0; } } else if (curr_UID == blue_UID) { for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 0; led.green = 0; led.blue = 50; led.white = 0; } } else { for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 0; led.green = 0; led.blue = 0; led.white = 0; } } } // Update the Everloop everloop.Write(&everloop_image); // Sleep for a reasonable amount of time std::this_thread::sleep_for(std::chrono::microseconds(10000)); } while (true); return 0; }
NFC Read Pages
The following example shows how to read all pages from an NFC tag. The tag must be either a NTAG or a MIFARE Ultralight. You can download this example here.
///////////////////////// // INCLUDE STATEMENTS // /////////////////////// // For console output #include <iostream> // For sleep #include <chrono> #include <thread> // For using the Everloop #include "matrix_hal/everloop.h" #include "matrix_hal/everloop_image.h" #include "matrix_hal/matrixio_bus.h" // For using NFC #include "matrix_nfc/nfc.h" #include "matrix_nfc/nfc_data.h" int main() { //////////////////// // INITIAL SETUP // ////////////////// // Setting up HAL bus matrix_hal::MatrixIOBus bus; if (!bus.Init()) return false; // Setting up Everloop matrix_hal::EverloopImage everloop_image(bus.MatrixLeds()); matrix_hal::Everloop everloop; everloop.Setup(&bus); // Setting up NFC matrix_hal::NFC nfc; matrix_hal::NFCData nfc_data; ///////////////// // MAIN CODE // /////////////// std::cout << "Scan a Mifare Ultralight or NTAG." << std::endl; do { // Scan NFC tag and read pages into nfc_data.pages nfc.Activate(); nfc.mful.ReadPages(&nfc_data.pages); nfc.Deactivate(); // Output pages from tag and set everloop to green only if tag was // detected and all pages were read, else set everloop to off. if (nfc_data.pages.recently_updated && nfc_data.pages.read_complete) { std::cout << std::endl; std::cout << "String:\n" << nfc_data.pages.ToString() << std::endl; std::cout << "Hex:\n" << nfc_data.pages.ToHex() << std::endl; for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 0; led.green = 20; led.blue = 0; led.white = 0; } } else { for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 0; led.green = 0; led.blue = 0; led.white = 0; } } // Update the Everloop everloop.Write(&everloop_image); // Sleep for a reasonable amount of time std::this_thread::sleep_for(std::chrono::microseconds(10000)); } while (true); return 0; }
NFC Write Page
The following example shows how to write a page to an NFC tag. The tag must be either a NTAG or a MIFARE Ultralight. You can download this example here.
///////////////////////// // INCLUDE STATEMENTS // /////////////////////// // For console output #include <iostream> // For sleep #include <chrono> #include <thread> // For string #include <string> // For vector #include <vector> // For using the Everloop #include "matrix_hal/everloop.h" #include "matrix_hal/everloop_image.h" #include "matrix_hal/matrixio_bus.h" // For using NFC #include "matrix_nfc/nfc.h" #include "matrix_nfc/nfc_data.h" int main() { //////////////////// // INITIAL SETUP // ////////////////// // Setting up HAL bus matrix_hal::MatrixIOBus bus; if (!bus.Init()) return false; // Setting up Everloop matrix_hal::EverloopImage everloop_image(bus.MatrixLeds()); matrix_hal::Everloop everloop; everloop.Setup(&bus); // Setting up NFC matrix_hal::NFC nfc; matrix_hal::NFCData nfc_data; ///////////////// // MAIN CODE // /////////////// int status; bool prompt_user = true; int page_number = 0; std::string write_str = ""; std::vector<uint8_t> write_data; do { // Ask user for new data to write if (prompt_user) { std::cout << "Enter Page to Write/Read From (Integer)" << std::endl; std::cin >> page_number; std::cout << "Enter String to Write (one page is 4 characters)" << std::endl; std::cin >> write_str; // Convert the string to a vector write_data = std::vector<uint8_t>(write_str.begin(), write_str.end()); prompt_user = false; std::cout << "Scan a Mifare Ultralight or NTAG" << std::endl; } // Wait until an NFC tag is activated do { status = nfc.Activate(); } while (matrix_hal::NFCStatus(status) != "Activation Done"); // Read the specified page from the NFC tag std::vector<uint8_t> read_page = nfc.mful.ReadPage(page_number); if (read_page.empty()) std::cout << "Error Reading" << std::endl; std::cout << "Page: " << page_number << " | Before Write: " << matrix_hal::PagesContent::BytesToString(read_page) << std::endl; // Write the specified page to the NFC tag status = nfc.mful.WritePage(page_number, write_data); // If the write succeeded then prompt the user for a new write next loop // iteration and set everloop to green, else set everloop to off if (matrix_hal::NFCStatus(status) == "Success") { prompt_user = true; for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 0; led.green = 20; led.blue = 0; led.white = 0; } } else { if (matrix_hal::NFCStatus(status) == "Incorrect Card Type For Function") { std::cout << "This example only supports Mifare Ultralight and NTAG " "cards" << std::endl; } for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 0; led.green = 0; led.blue = 0; led.white = 0; } } // Read the specified page from the NFC tag read_page = nfc.mful.ReadPage(page_number); if (read_page.empty()) std::cout << "Error Reading" << std::endl; std::cout << "Page: " << page_number << " | After Write: " << matrix_hal::PagesContent::BytesToString(read_page) << std::endl << std::endl; nfc.Deactivate(); // Update the Everloop everloop.Write(&everloop_image); // Sleep for a reasonable amount of time std::this_thread::sleep_for(std::chrono::microseconds(10000)); } while (true); return 0; }
NFC Read NDEF
The following example shows how to read the NDEF message from an NFC tag. The tag must be either a NTAG or a MIFARE Ultralight. You can download this example here.
///////////////////////// // INCLUDE STATEMENTS // /////////////////////// // For console output #include <iostream> // For sleep #include <chrono> #include <thread> // For using the Everloop #include "matrix_hal/everloop.h" #include "matrix_hal/everloop_image.h" #include "matrix_hal/matrixio_bus.h" // For using NFC #include "matrix_nfc/nfc.h" #include "matrix_nfc/nfc_data.h" int main() { //////////////////// // INITIAL SETUP // ////////////////// // Setting up HAL bus matrix_hal::MatrixIOBus bus; if (!bus.Init()) return false; // Setting up Everloop matrix_hal::EverloopImage everloop_image(bus.MatrixLeds()); matrix_hal::Everloop everloop; everloop.Setup(&bus); // Setting up NFC matrix_hal::NFC nfc; matrix_hal::NFCData nfc_data; ///////////////// // MAIN CODE // /////////////// std::cout << "Scan a tag to read NDEF!" << std::endl; do { // Scan NFC tag and read NDEF into nfc_data.ndef nfc.Activate(); nfc.ndef.Read(&nfc_data.ndef); nfc.Deactivate(); // If tag was detected output scanned tag's NDEF and set everloop to // green, else set everloop to off. if (nfc_data.ndef.recently_updated) { // Only output NDEF if the scanned tag was NDEF formatted if (nfc_data.ndef.valid) { std::cout << std::endl; std::cout << "String:\n" << nfc_data.ndef.ToString() << std::endl; std::cout << "Hex:\n" << nfc_data.ndef.ToHex() << std::endl; std::cout << "Output from NDEF parser:" << std::endl; matrix_hal::NDEFParser ndef_parser = matrix_hal::NDEFParser(&nfc_data.ndef); std::cout << ndef_parser.ToString() << std::endl; } for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 0; led.green = 20; led.blue = 0; led.white = 0; } } else { for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 0; led.green = 0; led.blue = 0; led.white = 0; } } // Update the Everloop everloop.Write(&everloop_image); // Sleep for a reasonable amount of time std::this_thread::sleep_for(std::chrono::microseconds(10000)); } while (true); return 0; }
NFC Write NDEF
The following example shows how to read the NDEF message from an NFC tag. The tag must be either a NTAG or a MIFARE Ultralight. You can download this example here.
///////////////////////// // INCLUDE STATEMENTS // /////////////////////// // For console output #include <iostream> // For sleep #include <chrono> #include <thread> // For using the Everloop #include "matrix_hal/everloop.h" #include "matrix_hal/everloop_image.h" #include "matrix_hal/matrixio_bus.h" // For using NFC #include "matrix_nfc/nfc.h" #include "matrix_nfc/nfc_data.h" // A helper function for writing NDEF to tag int NDEF_WriteToNewTag(matrix_hal::NFC &nfc, matrix_hal::NFCData &nfc_data) { std::cout << "Press enter to write" << std::endl; // Loop until enter pressed char temp = 'x'; while (temp != '\n') std::cin.get(temp); // Create an NDEFParser object and add a website NDEF record to the parser. matrix_hal::NDEFParser ndef_parser = matrix_hal::NDEFParser(); ndef_parser.AddUriRecord("http://docs.matrix.one"); std::cout << "Message Info:" << std::endl; // Output the NDEF message information from the NDEFParser. std::cout << ndef_parser.ToString() << std::endl; // Write the NDEF message from the NDEFParser to a NFC tag. nfc.Activate(); nfc.ndef.Write(&ndef_parser); nfc.Deactivate(); std::cout << "Wrote to new tag, try scanning tag with Android phone." << std::endl; return 0; } int main() { //////////////////// // INITIAL SETUP // ////////////////// // Setting up HAL bus matrix_hal::MatrixIOBus bus; if (!bus.Init()) return false; // Setting up Everloop matrix_hal::EverloopImage everloop_image(bus.MatrixLeds()); matrix_hal::Everloop everloop; everloop.Setup(&bus); // Setting up NFC matrix_hal::NFC nfc; matrix_hal::NFCData nfc_data; ///////////////// // MAIN CODE // /////////////// std::cout << "Scan a tag to read then write NDEF!" << std::endl; do { // Scan NFC tag and read NDEF into nfc_data.ndef nfc.Activate(); nfc.ndef.Read(&nfc_data.ndef); nfc.Deactivate(); // If tag was detected output scanned tag's NDEF, write new NDEF, and // set everloop to green, else set everloop to off. if (nfc_data.ndef.recently_updated) { // Only output NDEF if the scanned tag was NDEF formatted if (nfc_data.ndef.valid) { std::cout << std::endl; std::cout << "String:\n" << nfc_data.ndef.ToString() << std::endl; std::cout << "Hex:\n" << nfc_data.ndef.ToHex() << std::endl; std::cout << "Output from NDEF parser:" << std::endl; matrix_hal::NDEFParser ndef_parser = matrix_hal::NDEFParser(&nfc_data.ndef); std::cout << ndef_parser.ToString() << std::endl; std::cout << std::endl; } NDEF_WriteToNewTag(nfc, nfc_data); for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 0; led.green = 20; led.blue = 0; led.white = 0; } } else { for (matrix_hal::LedValue &led : everloop_image.leds) { led.red = 0; led.green = 0; led.blue = 0; led.white = 0; } } // Update the Everloop everloop.Write(&everloop_image); // Sleep for a reasonable amount of time std::this_thread::sleep_for(std::chrono::microseconds(10000)); } while (true); return 0; }