Frequently Asked Question

如何修改 UHF Tag 的 PC 值?
最後更新 3 months ago

⚠️ 警告: 錯誤地修改 PC (Protocol Control) 值可能會導致嚴重後果。
如果設定了錯誤的長度或將資料覆蓋到錯誤的位址(例如 CRC 或 EPC 資料本體),可能會使該 Tag 無法被讀取設備正常讀取與辨識,甚至造成標籤資料損毀與遺失。
進行修改前,請務必再三確認寫入偏移量與新 PC 值的計算是否正確!

1. 注意事項

  • start / offset 單位是 Word(2 Bytes): 修改 PC 請務必帶 1。如果帶錯數字會蓋掉 CRC 或 EPC 資料本體。
  • epc 參數是用來「定位 Tag」: 傳入錯誤的 EPC 會報「找不到 Tag」。
  • 改 PC 不會自動清除/填補 EPC 資料: 延長宣告長度後,Reader 會讀到 Tag 記憶體後續的殘留資料。若需要完整改寫,需另行將資料寫入 offset = 2 起始的位址。

2. 參數對照說明表

參數名稱 資料型別 V1 支持 V2 支持 詳細說明與注意事項
password byte[] ✅ ✅ Access Password(存取密碼)
• 固定長度 4 bytes。
• Tag 未密碼鎖定時帶 new byte[4](全 0)或 null。
epc byte[] ✅ ✅ 目標 Tag 當前的 EPC 值
• 用於發送 Select 命令尋找/定位空中該顆 Tag。
• ⚠️ 必須是 Tag「當下實際」的 EPC。
bank RFIDMemoryBank ✅ ✅ 要寫入的 Memory Bank
• 修改 PC 值時固定傳入 RFIDMemoryBank.EPC。
• ⚠️ 不可傳入 RFIDMemoryBank.Err。
start (或 offset) int ✅ ✅ 起始 Word 偏移量
• 單位為 16-bit Word(2 bytes),非 Byte!
• 0 = CRC-16(請勿修改)
• 1 = PC 值(修改 PC 固定帶入 1)
• 2 以上 = EPC 資料本體
retry int ✅ ✅ 重試次數
• 通訊不佳失敗時的自動重試次數,建議設為 1 ~ 3 次。
data (或 pcData) byte[] ✅ ✅ 要寫入的 PC 數值(2 bytes)
• Big-Endian 格式。
• 例:96 bits 長度帶 {0x30, 0x00}。
• 安全計算公式:(wordCount << 11) | (oldPC & 0x07FF)
timeoutMilliseconds int ❌ ✅ 單次操作逾時時間(毫秒)
• V2 專屬參數。
• 建議設定為 3000 ~ 5000(3~5 秒)。

3. API V1 與 V2 基本方法對照

項目 API V1 API V2
類別名稱 com.cipherlab.rfidapi.RfidManager com.cipherlab.rfidapi2.RfidManager2
方法名稱 RFIDDirectWriteTagByEPC (首字大寫) rfidDirectWriteTagByEPC (首字小寫)
回傳型別 DeviceResponse (OperationSuccess 表示成功) int (0 表示成功)
失敗訊息 mRfidManager.GetLastError() mRfidManager2.getLastError()
逾時時間 無 timeoutMilliseconds (毫秒)

4. API V1 完整指令與範例

參考指令

public DeviceResponse RFIDDirectWriteTagByEPC(
    byte[] password, 
    byte[] epc, 
    RFIDMemoryBank bank, 
    int start, 
    int retry, 
    byte[] data
);

呼叫範例 (以改寫 PC 長度為 96-bit 為例)

// 1. 準備參數
byte[] password = new byte[4];                        // 未鎖定 Tag 帶 4 個全 0
byte[] currentEpc = hexToBytes("300833B21111222233334444"); // 目標 Tag 當前實際 EPC (用於空中定位)
RFIDMemoryBank bank = RFIDMemoryBank.EPC;             // 指定 EPC Bank (固定值)
int start = 1;                                        // Word Offset = 1 (指向 PC 位址)
int retry = 3;                                        // 重試 3 次
byte[] pcData = new byte[] {(byte)0x30, (byte)0x00};  // 新 PC 值 (0x3000 = 宣告 96-bit 長度)

// 2. 執行寫入
DeviceResponse response = mRfidManager.RFIDDirectWriteTagByEPC(
    password,
    currentEpc,
    bank,
    start,
    retry,
    pcData
);

// 3. 判斷結果
if (response == DeviceResponse.OperationSuccess) {
    Log.i("RFID", "V1 寫入 PC 成功!");
} else {
    String errorMsg = mRfidManager.GetLastError();
    Log.e("RFID", "V1 寫入失敗,原因:" + errorMsg);
}

5. API V2 完整指令與範例

參考指令

public int rfidDirectWriteTagByEPC(
    byte[] password, 
    byte[] epc, 
    RFIDMemoryBank bank, 
    int start, 
    int retry, 
    byte[] data, 
    int timeoutMilliseconds
);

呼叫範例

new Thread(new Runnable() {
    @Override
    public void run() {
        // 1. 準備參數
        byte[] password = new byte[4];                        // 未鎖定 Tag 帶全 0
        byte[] currentEpc = hexToBytes("300833B21111222233334444"); // 目標 Tag 當前實際 EPC
        RFIDMemoryBank bank = RFIDMemoryBank.EPC;             // 指定 EPC Bank
        int start = 1;                                        // Word Offset = 1 (指向 PC 位址)
        int retry = 3;                                        // 重試 3 次
        byte[] pcData = new byte[] {(byte)0x30, (byte)0x00};  // 新 PC 值 (0x3000)
        int timeout = 5000;                                   // 逾時設定 5000 ms (5 秒)

        // 2. 執行寫入
        int result = mRfidManager2.rfidDirectWriteTagByEPC(
            password,
            currentEpc,
            bank,
            start,
            retry,
            pcData,
            timeout
        );

        // 3. 判斷結果
        if (result == 0) {
            Log.i("RFID", "V2 寫入 PC 成功!");
        } else {
            String errorMsg = mRfidManager2.getLastError();
            Log.e("RFID", "V2 寫入失敗,代碼:" + result + ",原因:" + errorMsg);
        }
    }
}).start();

請稍後!

請稍後幾分鐘!