我是想用Arduino做出一機複製卡片UID
但不確定是哪裡寫錯
白卡的UID改不了qwq
希望各位大老可以幫幫我這個小菜雞交出學習歷程
以下為程式碼(有點雜亂還請見諒
// OLED 函式庫
#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
#define CURSOR_X  0
#define CURSOR_Y  8
// U8g2 建構子( Frame Buffer )
// 完整列表: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp
// 以下以0.96吋 4Pin IIC-I2C示範
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
U8G2LOG u8g2log;
// 設定終端機 (U8G2LOG) 並連接到 U8g2 自動刷新螢幕
// 選擇的字體將會決定 (width * height) 的大小
// 設定 4x6 字體
#define U8LOG_WIDTH 32
#define U8LOG_HEIGHT 10
uint8_t u8log_buffer[U8LOG_WIDTH * U8LOG_HEIGHT];
// MFRC522 函式庫
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN   9     // RST腳位
#define SS_PIN    10    // SDA(SS)腳位
MFRC522 mfrc522(SS_PIN, RST_PIN);   // 建立 MFRC522 物件
/* 設定要寫入的UID */
//#define NEW_UID {0xCA, 0xB0, 0x62, 0xBD}
MFRC522::MIFARE_Key key;
void setup() {
  // OLED
  u8g2.begin();
  u8g2.setFont(u8g2_font_6x10_tf);   // 設定終端機視窗字體
  u8g2log.begin(u8g2, U8LOG_WIDTH, U8LOG_HEIGHT, u8log_buffer);
  u8g2log.setLineHeightOffset(0); // 設定行距
  u8g2log.setRedrawMode(0);   // 0: 在下一行更新螢幕, 1: 每個字元更新螢幕
  u8g2log.print("Initialize...\n");   // 顯示於螢幕
  // 針腳設定
  pinMode(7, INPUT_PULLUP); //copy btn
  // 序列埠通訊
  Serial.begin(9600);  // 初始化序列埠通訊 並設定傳輸速率
  // SPI
  SPI.begin();         // 初始化序列周邊介面
  // MFRC522
  mfrc522.PCD_Init();  // 初始化 MRFC522
  Serial.print(F("Reader "));
  Serial.print(F(": "));
  mfrc522.PCD_DumpVersionToSerial(); // 顯示讀卡設備的版本
  Serial.println();
  // 準備金鑰 - 所有金鑰在卡片出廠時被設成 FF FF FF FF FF FF
  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }
  u8g2log.print("Finish\n");
  delay(500);
  u8g2log.print("\f");  // \f = 跳頁字元: 清空螢幕
  delay(500);
}
// 把讀到的 Byte 陣列用16進位顯示出來
void dump_byte_array(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
  Serial.println("");
}
// OLED 顯示 UID
void oled_dump_uid(byte *buffer, byte bufferSize) {
  for (int j = 0; j < bufferSize; j++) {
    u8g2.firstPage();
    do {
      u8g2.setCursor(CURSOR_X, CURSOR_Y);
      u8g2.print("UID:");
      for (byte i = 0; i < bufferSize; i++) {
        if (buffer[i] < 0x10) {  // 讀到小於10的數字時,前面多顯示一個零
          u8g2.setCursor(26 + i * 16, CURSOR_Y);
          u8g2.print("0");
          u8g2.setCursor(26 + i * 16 + 6, CURSOR_Y);
          u8g2.print(buffer[i], HEX);
        } else {
          u8g2.setCursor(26 + i * 16, CURSOR_Y);
          u8g2.print(buffer[i], HEX);
        }
      }
    } while ( u8g2.nextPage() );  // UID列印結束
  }
}
// 複製UID
void copy_uid(byte *buffer, byte bufferSize, byte *newbuffer) {
  for (int i = 0; i < bufferSize; i++) {
    newbuffer[i] = buffer[i];
  }
  for (int i = 0; i < bufferSize; i++) {
    Serial.print(newbuffer[i]);
    Serial.print(" ");
  }
  Serial.println();
}
void loop() {
  int cursor_x = CURSOR_X;
  int cursor_y = CURSOR_Y;
  bool want_to_copy = false;
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_6x10_tf);
    u8g2.drawStr(cursor_x, cursor_y, "Scanning...");
    delay(50);
  } while ( u8g2.nextPage() );
  // 偵測卡片並讀取
  if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
    delay(50);
    return;
  }
  // 列印 UID
  Serial.print("卡片 UID:");
  dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
  oled_dump_uid(mfrc522.uid.uidByte, mfrc522.uid.size);
  Serial.print("PICC type: "); // 印出 PICC
  MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
  Serial.println(mfrc522.PICC_GetTypeName(piccType)); // 顯示卡片的類型
  Serial.println();
  // 複製 UID
  if (digitalRead(7) == LOW) {
    byte *newUid = mfrc522.uid.uidByte;
    byte uidsize = mfrc522.uid.size;
    u8g2log.print("UID was copied.\n");
    //copy_uid(mfrc522.uid.uidByte, mfrc522.uid.size, newUid);
    Serial.print("要複製的UID:");
    dump_byte_array(mfrc522.uid.uidByte, uidsize);
    Serial.print("被複製的UID:");
    dump_byte_array(newUid, uidsize);
    Serial.println();
    delay(500);
    // 讀取新卡片
    mfrc522.PICC_HaltA();
    bool read_new_card = false;
    do {
      u8g2.firstPage();
      do {
        u8g2.setFont(u8g2_font_6x10_tf);
        u8g2.drawStr(cursor_x, cursor_y, "Scanning new card...");
        delay(50);
      } while ( u8g2.nextPage() );
      if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
        delay(50);
        continue;
      }
      read_new_card = true;
      // 列印 UID
      Serial.print("卡片 UID:");
      dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
      oled_dump_uid(mfrc522.uid.uidByte, mfrc522.uid.size);
      Serial.println();
      delay(1000);
      u8g2log.print("Writing UID to\n");
      u8g2log.print("new card...\n");
      if ( mfrc522.MIFARE_SetUid(newUid, (byte)4, true) ) {
        u8g2log.print("Finish\n");
        Serial.println("完成寫入新的 UID 至卡片\n");
        delay(2000);
        u8g2log.print("\f");
        u8g2.clear();
        break;
      } else {
        u8g2log.print("Failed\n");
        delay(2000);
        u8g2log.print("\f");
        u8g2.clear();
        break;
      }
    } while (!read_new_card);
  } // 複製 UID 結束
  mfrc522.PICC_HaltA(); // 卡片進入停止模式
  delay(1000);
}   // loop() 結束