[第八課] NFC感應魔法-1 (SPI / ISO14443A)

『存在就是被感知』 "To be is to be perceived" ~ Berkeley

還是這開頭,嵌入式系統的設計,其中與使用者互動經驗的設計,常常是系統成敗的關鍵之一。就像手機與電腦的使用者,如果少了『搜尋』這把放大鏡的工具,你就會開始『懷疑人生』...我記得檔案不是放在...。所以,只要標榜儲存容量大;那相對應快速便捷的索引方式必須同時存在。


課程進行到現在,應該要知道NFC ACCP最主要的系統需求是什麼:對ACCP來說,就是如何在SD卡的茫茫歌海裡,選定音樂來播放。所以必須在動用到最少資源的考量下,來選定適用的組件,來達成這個功能。

裝個滑鼠或是鍵盤如何?對於MP3隨身聽這個行動裝置而言,這是癡人說夢般的不切實際;

那麽,裝一個滾輪輸入裝置,來選擇要播哪首曲子如何?想法是可以,但除了  I2C  接線外,至少還需要另外2個輸入端子做選項切換及確認;但,目前系統沒有足夠的GPIO端子可用;

那好,如果可選用NFC感應輸入,那麽用QR Code掃描應該也可以吧?當然可以啊!如果你不考慮加入鏡頭的成本的話,這個常常糾纏NFC的技術,在光線不好的時候,也還有掃描不到Code的疑慮;那藍牙?WiFi呢?我應該說,都可以!但是就是:『我不行!』。

所以,非選NFC不可!

NFC 近場通訊,感覺是一個很技術的應用,不容易理解。但現在,我們卻常常應用在搭捷運,過門禁的識別之用。加上現在很多智慧型的手機,都已經選為標配,相信這種利用感應方式來讀取識別碼的應用,你應該不陌生。說到NFC有很多不同的通訊協定,什麼ISO14443A/B/C、ISO15693...,也許你也可以不必太在意,目前只專注在 ISO14443A上,利用感應的方式去讀取NFC標籤晶片上的記憶體資料就可以了。

首先會引用萬象創造所提供的NFC模組與程序,使用的方式,一樣先引入作SPI的連結:
/* SICRE31 NFC Re-Writer via SPI */
class RE31_SPI{
public:  
  RE31_SPI(SPIClass &spi, uint8_t ss);
  void begin();
  void writeReg(byte addr, byte* data, uint8_t len);
  void writeReg(byte addr, byte data);
  void writeCmd(byte cmd);
  void writeFIFO(byte* data, uint8_t len);
  int16_t readReg(byte addr, byte* data, uint8_t len);
  byte readReg(byte addr);
  void readFIFO(byte* data, uint8_t len);
  uint8_t getFIFOLength();
      
  inline void select(boolean e){
    if(!e){
      digitalWrite(_ss, HIGH);
    }else{
      digitalWrite(_ss, LOW);
    }
  }
      ...... 
      RE31_SPI RE31_SPI(SPI, SS);
  
雖然在使用上,可以說是相當的方便,但唯一可能會令你有餘慮的是,無線的訊號我們看不見、也摸不到,該怎麼去確認呢?首先,在 setup() 做SPI連通的測試,去讀取Reader晶片的型號來確認 SIC931_Check_Device(),如果成功就進行RF通訊協定的初值設定即可。

RE31_SPI.begin();
delay(100);
if (SIC931_Check_Device() < 0) {
    sl1 = "-NFC RWD is FAIL..";
    digitalWrite(LED_R, LOW);
    ss = "System is some fault...";
} else {
    sl1 = "-NFC RWD is OK..";
        SIC931_Config_14443a(); 
}

<NFC_ReWriter.ino> 中,是會使用到對第二型Tag標籤存取的命令。當開機完成進入主程序時,會在每個  SCAN  狀態開始進行對Tag的感應 isTagPresent()如果有NFC的標籤出現在有效的感應區時,會自動完成通訊協定上的選取,獲得此標籤的唯一識別碼(UID)。

case SCAN: {
      rwdIdle();
      if (isTagPresent()) {
         lowPowerHandler();
         t2_ReadPage(0x03, rxbuf); 
         if (rxbuf[2] >= 0x12) { //check CC files, memoy size 
            tag_in = 1; 
            if (t2_ReadPage(addrTkt, t_mem)) {
                digitalWrite(LED_B, LOW);
            ...}
         ...}
      ...} 

然後,檢查是否為X-DISC使用的同系列晶片,並讀取指定的曲目索引內容(頁0x27)。

下回待續...


留言

熱門文章