Запись RFID меток. Модуль RC522
- Войдите на сайт для отправки комментариев
Пт, 12/04/2019 - 13:37
Приветствую!
Пытаюсь научится записывать метки на ключ. Нашёл единственный рабочий пример тут (https://arthurphdent.livejournal.com/1759.html)
вот когд:
#include <SPI.h>//include the SPI bus library
#include <MFRC522.h>//include the RFID reader library
#define RST_PIN 9
#define SS_PIN 10
MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
void setup() {
Serial.begin(9600);
while (!Serial);
SPI.begin();
mfrc522.PCD_Init();
// Подготовим ключ
// используем ключ FFFFFFFFFFFFh который является стандартом для пустых карт
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
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);
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;
}
// В этом примере мы используем первый сектор данных карты, блок 4
byte sector = 1;
byte blockAddr = 4;
byte dataBlock[] = { // Данные, которые мы запишем на карту
0x01, 0x02, 0x03, 0x04, // 1, 2, 3, 4,
0x05, 0x06, 0x07, 0x08, // 5, 6, 7, 8,
0x08, 0x09, 0xff, 0x0b, // 9, 10, 255, 12,
0x0c, 0x0d, 0x0e, 0x0f // 13, 14, 15, 16
};
byte trailerBlock = 7;
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);
}
}
Блин, не успел дописать в вопрос в посте, он уже опубликовался и не изменяется... ну ок продолжим.
Дак вот, этот код работает с указаным блоком
// В этом примере мы используем первый сектор данных карты, блок 4 byte sector = 1; byte blockAddr = 4; byte dataBlock[] = { // Данные, которые мы запишем на карту 0x01, 0x02, 0x03, 0x04, // 1, 2, 3, 4, 0x05, 0x06, 0x07, 0x08, // 5, 6, 7, 8, 0x08, 0x09, 0xff, 0x0b, // 9, 10, 255, 12, 0x0c, 0x0d, 0x0e, 0x0f // 13, 14, 15, 16и отлично перезаписывает. Но если изменить
байт сектор на 0, или любой другой, ничего не работает. происходит бесперрывный отбмен с сериалом по кругу и ничего не перезаписывается...
как перезаписать другие блоки и сектора???
Спасибо!
Блок 0 - специальный блок, хранящий системные данные карточки. Пытаться его перезаписать без должного понимания - верный путь заблочить всю карту. Похоже именно это у вас и произошло, если так - эту конкретную карту теперь можно выкинуть.
Для проверки возьмите новую карточку и попробуйте свой код на ней. записывая. к примеру, вместо блока 4 - блок 11 или 16... но только не 0.
Насчет "единственный рабочий пример" - это чистое вранье, примеров записи блоков в инете десятки, и в первую очередь в примерах к самой библиотеке.
Блок 0 - специальный блок, хранящий системные данные карточки. Пытаться его перезаписать без должного понимания - верный путь заблочить всю карту. Похоже именно это у вас и произошло, если так - эту конкретную карту теперь можно выкинуть.
Для проверки возьмите новую карточку и попробуйте свой код на ней. записывая. к примеру, вместо блока 4 - блок 11 или 16... но только не 0.
Насчет "единственный рабочий пример" - это чистое вранье, примеров записи блоков в инете десятки, и в первую очередь в примерах к самой библиотеке.
нет, запись любых блоков кроме первоначально установленого, вообще не происходит. не с 0, не с 11 не с 16.
данные не пишутся. с 0 тоже ничего вообще не перезаписалось, карта рабочая по прежнему.
По поводу примеров запеси, простите я не нашёл. в примерах к бибилотеке,с запесью тоже непонятно что за скетчи и как они работают. у меня не получилось
и на ютубе примеров запеси рабочих нет, которые можно повторить
вот, при любой конфигурации (в данном случаии 11,47),
byte sector = 11; byte blockAddr = 47;в порт шлётся бесконенчо (пока не уберешь ключь от ридера) вот это
byte sector = 11; byte blockAddr = 4; byte dataBlock[] = { // NEW DATA to Write 0x00, 0x00, 0x00, 0x00, // 1, 2, 3, 4, 0xFF, 0xFF, 0xFF, 0xFF, // 5, 6, 7, 8, 0xFF, 0xFF, 0xFF, 0xFF, // 9, 10, 255, 12, 0xFF, 0xFF, 0xFF, 0xFF // 13, 14, 15, 16получаем это
byte sector = 16; byte blockAddr = 4;вот это:
ну вы сами-то не видите, что делаете ерунду? - вы же говорите, что хотите писать в другой блок - а сами все время пишете в один и тот же - в блок номер 4.
У вас не работает, потому что вы авторизуетесь в один сектор, а писать пытаетесь в другой. Номер сектора и номер блока должны соответвовать друг другу. Сектор 0 содержит блоки с 0 до 3, сектор 1 - с 4 до 7 и так далее Таким образом, когда вы указываете сектор 1 и блок 4 - все пишется. Если же вы хотите писать в сектор 11, то в нем нет блока номер 4 - номера блоков в секторе 11 - от 44 до 47.
Укажите в строчках 56 и 57
и проверьте - все должно заработать
ну вы сами-то не видите, что делаете ерунду? - вы же говорите, что хотите писать в другой блок - а сами все время пишете в один и тот же - в блок номер 4.
У вас не работает, потому что вы авторизуетесь в один сектор, а писать пытаетесь в другой. Номер сектора и номер блока должны соответвовать друг другу. Сектор 0 содержит блоки с 0 до 3, сектор 1 - с 4 до 7 и так далее Таким образом, когда вы указываете сектор 1 и блок 4 - все пишется. Если же вы хотите писать в сектор 11, то в нем нет блока номер 4 - номера блоков в секторе 11 - от 44 до 47.
Укажите в строчках 56 и 57
и проверьте - все должно заработать
всё тоже самое
(это оказывается и есть код из примеров библиотеке ReadandWrite). но работает она только с одними дефолтными настройками 1.4)
Scan a MIFARE Classic PICC to demonstrate read and write.
причем я же делал сектор как по таблице (комментарий #4)
(
вот, при любой конфигурации (в данном случаии 11,47),
1bytesector = 11;2byteblockAddr = 47;в порт шлётся бесконенчо (пока не уберешь ключь от ридера) вот это
)
поменяйте строчку 97 на
поменяйте строчку 97 на
Огромное Вам спасибо!!! Всё заработало с любыми параметрами!!!
А вы немоглибы помочь мне понять, почему изначально там была дапущена эта ошибка и ничего не работало в иной онфигурации блоков? А так же что эта строчка конкретно делает? Ещё раз спасибо!
опять всё сломалось. причем с дургим ключом работает. Интересно, сколько раз можно перезаписать этот ключ (синий брелок с китая), я всего раз 7 записал по вашему способо и писатся перестало, причем и читатся первые 4 блока перестали...
А вы немоглибы помочь мне понять, почему изначально там была дапущена эта ошибка и ничего не работало в иной онфигурации блоков? А так же что эта строчка конкретно делает? Ещё раз спасибо!
Этой строчкой мы меняем ключ, используемый для записи блоков, с key_B на key_А. Никакой ошибки в библиотеке и в примере нет, какой ключ подойдет - зависит только от того, как запрограммировали карту при продаже. Так что на одних карточках для записи используется ключА, а на других Б. В дальнейшем вы можете поменять эти настройки сами путем перезаписи битов доступа.
Ещё раз огромное спасибо!
опять всё сломалось. причем с дургим ключом работает. Интересно, сколько раз можно перезаписать этот ключ (синий брелок с китая), я всего раз 7 записал по вашему способо и писатся перестало, причем и читатся первые 4 блока перестали...
я вам писал, что далеко не все данные на карте можно переписывать. Совет - прежде чем что-то писать на карту. тщательно изучите описание формата. В последнем блоке каждого сектора хранятся биты доступа и ключи. Пока не разберетесь с ними - старайтесь не писать ничего в эти блоки. Я ж не зря вам указал для примера блок 46 а не 47, а вы зачем-то изменили
опять всё сломалось. причем с дургим ключом работает. Интересно, сколько раз можно перезаписать этот ключ (синий брелок с китая), я всего раз 7 записал по вашему способо и писатся перестало, причем и читатся первые 4 блока перестали...
я вам писал, что далеко не все данные на карте можно переписывать. Совет - прежде чем что-то писать на карту. тщательно изучите описание формата. В последнем блоке каждого сектора хранятся биты доступа и ключи. Пока не разберетесь с ними - старайтесь не писать ничего в эти блоки. Я ж не зря вам указал для примера блок 46 а не 47, а вы зачем-то изменили
Безпредельно Вам благодарен за помощь!!! всё понял. дальше буду разбиратся с блоками.
п.с. Вторую карту перезаписал более 10 раз в "правельные блоки (в средние), всё работает. (прочитал что можно до 1000 раз презаписывать, очевидно там обычнаяя eeprom) Жаль что залочил единстенный синий ключ...