RFID аутентификация или 1001 проблема

Нет ответов
RockHammer
Offline
Зарегистрирован: 21.08.2017

Здравствуйте.

Нужно было сделать так, чтобы ардуинка записывала кое-какие данные на nfc карту, нашёл в интернетах исходник, схожий по назначению с моей целью и попытался переделать.

Что изменил: добавил либы для взаимодействия с экраном и переделал стандарный 12 F ключ на тот, который используется конкретно у меня в карте (тот костыль на switch'e). 

Итак, тот костыль вводит ключ B для сектора 8, a = 786D80C7B832, b = 86FD651B5E98

Проблема: в мониторе порта выходит ошибка аутентификации

PICC type: MIFARE 1KB
Authenticating using key A...
PCD_Authenticate() failed: Error in communication.

Ключи для аутентификации в сектор 8 вы видите выше. Ключ B универсальный - и для чтения и для записи в моей карте.

Как решить проблему? Если можно, скиньте готовые куски кода, или его целиком, я уже запарился с этим.

#include <MFRC522.h>               // Подключаем библиотеку для работы с модулем RC522
#include <Wire.h>
#include <LiquidCrystal_I2C.h>


LiquidCrystal_I2C lcd(0x27,20,4);

#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args)  write(args);
#else
#define printByte(args)  print(args,BYTE);
#endif

    int serNum0;
    int serNum1;
    int serNum2;
    int serNum3;
    int serNum4;

#define RST_PIN         9          // Пин подключения вывода RST модуля
#define SS_PIN          10         // Пин подключения SDA(SS) вывода модуля

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Создаем объект для работы с библиотекой MFRC522 и сообщаем ей пины подключения модуля
MFRC522::MIFARE_Key key;

void setup() {
  lcd.init();
  lcd.backlight();
  
  Serial.begin(9600);                                         // Инициализируем вывод данных на монитор серийного порта
  while (!Serial);                                            // Ждем пока не инициализируется монитор серийного порта
  SPI.begin();                                                // Инициализируем интерфейс SPI
  mfrc522.PCD_Init();                                         // Инициализируем модуль MFRC522
  
  mfrc522.PCD_DumpVersionToSerial();                          // Выводим версию прошивки модуля на монитор серийного порта
  //Serial.println("Please, place RFID-label over the reader"); // Выводим сообщение о том, что модуль готов к считыванию и ожидает метку
  
  for (byte i = 0; i < 6; i++) {
        switch (i) {
          case 0:
          key.keyByte[i] = 0x86;
          break;
          case 1:
          key.keyByte[i] = 0xFD;
          break;
          case 2:
          key.keyByte[i] = 0x65;
          break;
          case 3:
          key.keyByte[i] = 0x1B;
          break;
          case 4:
          key.keyByte[i] = 0x5E;
          break;
          case 5:
          key.keyByte[i] = 0x98;
          break;
        }
        
    }
    
    
    Serial.println(F("Scan a MIFARE Classic PICC to demonstrate read and write."));
    Serial.print(F("Using key (for A and B):"));
    dump_byte_array(key.keyByte, MFRC522::MF_KEY_SIZE);
    Serial.println();
    
    Serial.println(F("BEWARE: Data will be written to the PICC, in sector #1"));

  
}

void loop() {
    // Ждем новую карту
    if ( ! mfrc522.PICC_IsNewCardPresent())
        return;

    // Выбираем одну из карт
    if ( ! mfrc522.PICC_ReadCardSerial())
        return;

    // Показываем подробности карты
    Serial.print(F("Card UID:"));
    dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
    lcd.print(F("Card UID: ")); //костыль
    lcd.print((byte)mfrc522.uid.uidByte); //для вывода Uid, который не работает
    Serial.println();
    Serial.print(F("PICC type: "));
    byte piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
    Serial.println(mfrc522.PICC_GetTypeName(piccType));

    // Проверяем совместимость
    if (    piccType != MFRC522::PICC_TYPE_MIFARE_MINI
        &&  piccType != MFRC522::PICC_TYPE_MIFARE_1K
        &&  piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
        Serial.println(F("This sample only works with MIFARE Classic cards."));
        return;
    }

    // В этом примере мы используем восьмой сектор данных карты, блок 33
    byte sector         = 8;
    byte blockAddr      = 33;
    byte dataBlock[]    = { // Данные, которые мы запишем на карту
        0x40, 0x0D, 0x03, 0x00, //  1,  2,   3,  4,
        0xBF, 0xF2, 0xFC, 0xFF, //  5,  6,   7,  8,
        0x40, 0x0D, 0x03, 0x00, //  9, 10, 255, 12,
        0x22, 0xDD, 0x22, 0xDD  // 13, 14,  15, 16
    };
    byte trailerBlock   = 36;
    byte status;
    byte buffer[18];
    byte size = sizeof(buffer);
    
    // Аутентификация
    Serial.println(F("Authenticating using key A..."));
    status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
    if (status != MFRC522::STATUS_OK) {
        Serial.print(F("PCD_Authenticate() failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
        return;
    }

    // Показываем текущие данные сектора
    Serial.println(F("Current data in sector:"));
    mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
    Serial.println();

    // Читаем данные из блока
    Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
    Serial.println(F(" ..."));
    status = mfrc522.MIFARE_Read(blockAddr, buffer, &size);
    if (status != MFRC522::STATUS_OK) {
        Serial.print(F("MIFARE_Read() failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
    }
    Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
    dump_byte_array(buffer, 16); Serial.println();
    Serial.println();

    // Аутентификация
    Serial.println(F("Authenticating again using key B..."));
    status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));
    if (status != MFRC522::STATUS_OK) {
        Serial.print(F("PCD_Authenticate() failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
        return;
    }

    // Записываем данные в блок
    Serial.print(F("Writing data into block ")); Serial.print(blockAddr);
    Serial.println(F(" ..."));
    dump_byte_array(dataBlock, 16); Serial.println();
    status = mfrc522.MIFARE_Write(blockAddr, dataBlock, 16);
    if (status != MFRC522::STATUS_OK) {
        Serial.print(F("MIFARE_Write() failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
    }
    Serial.println();

    // Читаем данные снова, чтобы проверить, что запись прошла успешно
    Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
    Serial.println(F(" ..."));
    status = mfrc522.MIFARE_Read(blockAddr, buffer, &size);
    if (status != MFRC522::STATUS_OK) {
        Serial.print(F("MIFARE_Read() failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
    }
    Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
    dump_byte_array(buffer, 16); Serial.println();
       
    Serial.println(F("Checking result..."));
    byte count = 0;
    for (byte i = 0; i < 16; i++) {
        if (buffer[i] == dataBlock[i])
            count++;
    }
    Serial.print(F("Number of bytes that match = ")); Serial.println(count);
    if (count == 16) {
        Serial.println(F("Success :-)"));
    } else {
        Serial.println(F("Failure, no match :-("));
        Serial.println(F("  perhaps the write didn't work properly..."));
    }
    Serial.println();
        
    // Выводим данные
    Serial.println(F("Current data in sector:"));
    mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
    Serial.println();

    mfrc522.PICC_HaltA();
    mfrc522.PCD_StopCrypto1();
}

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);
    }
}