Зчитувач RFID: розповідаємо про технологію. RFID - це просто. Реалізація власного RFID транспондера та рідера

RFID (Радіочастотна ідентифікація) використовує електромагнітні поля для автоматичної ідентифікації та відстеження тегів, прикріплених до об'єктів. Мітки містять електронно збережену інформацію. Пасивні мітки збирають енергію від радіосигналів сусіднього зчитувача RFID. Активні теги мають локальне джерело живлення (наприклад, акумулятор) і можуть працювати в сотнях метрів від пристрою для зчитування. На відміну від штрих-коду, тег не повинен знаходитися в межах видимості приладу, тому він може бути вбудований в об'єкт, що відстежується. RFID - це один із методів автоматичної ідентифікації та збору даних.

Застосування

RFID-мітки використовуються у багатьох галузях промисловості. Наприклад, зчитувач RFID, прикріплений до автомобіля під час виробництва, може використовуватися для відстеження прогресу конвеєрної лінії. Фармацевтичні препарати з маркуванням можна відстежувати через склади. Імплантація RFID-мікрочіпів у худобу дозволяє ідентифікувати тварин.

Оскільки мітки RFID можуть бути прикріплені до грошей, одягу та майна або імплантовані у тварин та людей, можливість читати особисту інформаціюбез згоди користувача викликає серйозну проблемуконфіденційності. Ці ризики призвели до розробки стандартних специфікацій щодо питань безпеки особистих даних. Теги також можуть використовуватись у магазинах для прискорення оформлення замовлення та запобігання крадіжкам.

Історія

У 1945 році Леон Термен винайшов пристрій для прослуховування Радянського Союзу, що повторно передавало радіохвилі з доданою аудіоінформацією. Звукові коливання при вібрації впливали на діафрагму, яка трохи змінювала форму резонатора, що модулював відбиту радіочастоту. Незважаючи на те, що цей пристрій був прихованим приладом для прослуховування, а не ідентифікаційним тегом, він вважається попередником USB RFID-зчитувача, оскільки активувався аудіохвилями з зовнішнього джерела. Транспондери, як і раніше, використовуються більшістю працюючих літаків. А раніше подібна технологія, така як зчитувач RFID-міток, регулярно використовувалася союзниками та Німеччиною у Другій світовій війні для ідентифікації літаків.

Пристрій Маріо Кардулло, запатентований 23 січня 1973, був першим істинним попередником сучасної RFID, оскільки це був пасивний радіоприймач з пам'яттю. Початковий пристрій був пасивним, з живленням опитувального сигналу. Воно було продемонстровано у 1971 році адміністрації Нью-Йорка та іншим потенційним користувачамі складалося з транспондера з 16-розрядною пам'яттю для використання як платного пристрою. Основний патент Cardullo охоплює використання радіочастот, звуку та світла як середовище передачі.

Область використання

Початковий бізнес-план, представлений інвесторам у 1969 році, демонстрував такі сфери застосування зчитувача RFID:

  • використання у транспорті (ідентифікація автомобільних транспортних засобів, автоматична система оплати, електронний номерний знак, електронний маніфест, маршрутизація транспортного засобу, моніторинг ефективності транспортних засобів);
  • банківська справа (електронна чекова книжка, електронна кредитна карта);
  • персоналу, автоматичні ворота, спостереження); медична галузь (ідентифікація, історія пацієнтів).

Рання демонстрація відбитої потужності (модульованого зворотного розсіювання) RFID-міток, як пасивних, так і напівпасивних, була виконана Стівеном Деппом, Альфредом Коелле та Робертом Фрайманом у Національній лабораторії Лос-Аламоса у 1973 році. Портативна системапрацювала на частоті 915 МГц та використовувала 12-бітові теги. Цей метод застосовується більшістю сучасних UHFID та мікрохвильових RFID-зчитувачів. У сучасному житті такі пристрої дуже потрібні.

Специфікація

Система радіочастотної ідентифікації використовує мітки, прикріплені до об'єктів, що ідентифікуються. При виготовленні RFID-зчитувача своїми руками слід враховувати, що двосторонні радіопередавачі-приймачі, які називають запитувачами або зчитувачами, посилають сигнал тегу і зчитують його відповідь. Теги RFID можуть бути пасивними, активними чи пасивними. Активний тег має вбудований акумулятор і періодично передає ID-сигнал. Пасивний акумулятор (BAP) має невелику батарею на борту та активується за наявності зчитувача RFID. Пасивна бирка дешевша і менша, бо в неї немає батареї. Натомість тег використовує радіохвилю, передану зчитувачем. Однак для роботи пасивного тега він повинен бути освітлений рівнем потужності приблизно тисячу разів сильніше, ніж для передачі сигналу. Це впливає на інтерференцію та опромінення.

Цей проект було зроблено на прохання друга для встановлення на двері до складського приміщення. Надалі було виготовлено ще кілька на прохання друзів та знайомих. Конструкція виявилася простою та надійною. Працює цей пристрійтак: пропускає лише ті RFID-карти, які були заздалегідь занесені на згадку про пристрій.

Основні характеристики контролера доступу:

RFID-картки формат EMmarin 125кгц

Мікроконтролер ATtiny13

Кількість карток/брелоків - 10.
Кнопка "OPEN" нормально розімкнена, захищена від залипання.
Вихід керування замком, сильноточний польовий транзистор, режим роботи на клямку (включається на час).

Харчування – 12в.
Споживання у черговому режимі – 35 мА.
Кількість карток/брелоків доступу - 10 шт.
Довжина зв'язку з кнопкою "OPEN" – 10 метрів.
Тип виходу управління замком – відкритий стік (потужний польовий транзистор, струм до 2А).

Принципова схема контролера обмеження доступу на RFID-картах 125КГц (Em-Marin) на 10 карток (на мікроконтролері ATtiny13):

Якщо треба керувати електромагнітним замком, потрібне встановлення вихідного реле з необхідною контактною групою.

Зовнішній вигляд зібраного RFID-валідатора:

Установка Fuse-бітів у PonyProg:

Робота пристрою, завантажити відеоролик, записаний автором.
Також один із читачів опублікував відео роботи зібраного пристрою:

Інструкція з програмування

Робочий режим – при подачі 12В на контролер світлодіод блимає 1Гц.
Режим програмування - світлодіод блимає 2Гц.
При натисканні кнопки "OPEN" серія коротких звукових сигналів під час відкриття замка.

Звукові сигнали

1 короткий сигнал – карта або брелок записаний у пам'ять контролера.
2 короткі сигнали - карта або брелок вже записаний у пам'яті контролера.
5 коротких сигналів - вихід з режиму програмування.
1 довгий сигнал- Пам'ять карт-ключів стерта з контролера.
Безперервні короткі сигнали- Пам'ять карт/ключів заповнена, максимально 10шт. (Потрібно відключення живлення контролера).

Запис МАЙСТЕР-КАРТИ та часу відкривання замку

1 - Вимкнути живлення контролера.
2 - Натиснути кнопку "OPEN"
3 - Утримуючи кнопку підключити живлення до контролера через 5 сек. контролер "ПИСКНЕТ", світлодіод блиматиме з частотою 2 Гц.
4 – Відпустити кнопку.
5 - Піднести в зону зчитування картку або брелок, пролунає одиночний звуковий сигнал, Майстер-карта або брелок ЗАПИСАН, при цьому запишеться час відкриття замка 1 сек.

6 - Утримуючи карту або брелок у зоні зчитування - вважаємо звукові сигнали. Кількість визначає необхідний час відривання замку, збільшення 1 сек., але не більше 32 сек.
7 - Вимикаємо живлення контролера або витримуємо паузу 30 сек.

Стирання всієї пам'яті карт-брелків

1 – Робочий режим.
2 - Натискаємо кнопку "OPEN" і утримуючи підносимо до зчитувача МАЙСТЕР-карту або брелок і тримаємо, через 5 сек пролунає тривалий звуковий сигнал - пам'ять карт/брелків стерта.
3 - Відпускаємо кнопку віднімаємо карту або брелок.

Після кількох років роботи з RFID тематики та розробки різноманітних зчитувачів для моделей транспондерів популярних стандартів типу Mifare, EMMARINE, TIRIS… мене часто почало спантеличувати таке питання – буквально в останній рікшироку популярність набули різного роду емулятори під теги популярних протоколів та різноманітні копіювальники ключів/брелків.

Враховуючи велику кількість доступних у продажу спеціальних мікросхем популярних протоколів RFID і дешевих рідерів, широкого поширення обладнання типу цифрових осцилографів, сніферів і спектроаналізаторів, це питаннястав для багатьох розробників актуальнішим. Тоді я зважився зробити для одного з проектів протокол для обміну різним від описаних стандартів.

Безумовно дана ідеяне вирішує глобальних проблемзахищеності нової системиі може бути проаналізована іншими розробниками за наявності обладнання, проте суть у тому, що все це не збігається з існуючими стандартамиі всі залозки копіювальників не дозволять швидко скопіювати і відтворити подібний алгоритм. Зрозуміло подібна системане подається тут не як повне рішенняпроблем безпеки, а як досвід адаптації RFID під закриту систему. Гарним плюсому питанні безпеки серед інших подібних бездротових системє сама технологія низькочастотних RFID - вона не дозволяє рахувати теги на великій відстані.

Пасивні теги досить малопотужні і потребують свого харчування досить потужному генераторі зчитувача, особливості поширення радіохвиль на даних частотах також обмежують межі роботи даної системи. Реальна дальність зчитування транспондерів рідко перевищує 20см для 125 Кгц стандартів типу EmMarine, скажімо стандарту EM4001, для інших протоколів типу Mifare (13,56 МГц) може бути більше (1,5 метра для iso15693). Можна домогтися більшої відстані зчитування для низькочастотних рідерів, якщо збільшити розміри котушки і напругу живлення, відповідно і потужність ридера. Однак такі системи мають громіздкі і, як правило, їх важко зробити портативними. Як правило, такі системи реалізуються лише стаціонарно – скажімо для автомобілів.

Отже, тепер власне з архітектури нашої системи RFID. Для експериментів було обрано контролера atmel atmega8. Для цілей виготовлення транспондера це здається безперечною надмірністю. Однак у даному випадкувирішувалося першорядне завдання розробки нового інтерфейсу на готовій налагоджувальній хустці c atmega з подальшим портуванням даного коду більш дешеві контролери типу tiny13. Для транспондера алгоритм роботи був побудований на основі режиму ШІМ генерації за допомогою таймера T1 у режимі CTC з перериванням та скиданням за збігом з OCR1. Дані передачі транспондера зчитуються з EEPROM при включенні живлення контролера. Усього транспондер передає 10 байт. Вміст EEPROM транспондера можна бачити на малюнку 1.Перший байт 0xE7 є обов'язковим заголовком пакета, оскільки його наявність перевіряється насамперед при розборі пакета зчитувачем.

Перші 8 байт є вмістом пакета транспондера, останні 2 байти містять контрольну суму CRC16 перших восьми байт пакета. Для прикладу в нашому транспондері були записані такі дані – пакет 0xE7, 0x05, 0xE8, 0x93, 0x43, 0x7F, 0x20, 0xFF та відповідно контрольну суму 0xF5 0xA8. Для виготовлення власного унікального транспондера потрібно, крім першого байта 0xE7, записати сім наступних байт в EEPROM, після чого розрахувати контрольну суму для перших восьми байт. Після цього записати в EEPROM два байти CRC16 наприкінці пакета. Перший байт залишаємо без змін – 0xE7. При включенні транспондера дані цих байт розбиваються по бітах і кодуються відповідною довжиною імпульсу відповідно до значення регістра OCR. Для передачі використовуються 2 частоти 2Кгц та 5Кгц для передачі логічних “0” та “1”. Крім того, дані розділяються імпульсами синхронізації – стартові мітки пакетів.

Рис.1Вміст пакету транспондера.


Рис.2Дамп передачі транспондер на екрані віртуального осциллографа.

Схему транспондера можна побачити на малюнку 3.Частота генератора, що задає 8МГц. Живлення контролера +5В. Можна використовувати контролер mega8 з маркуванням “L”, тоді живлення можна здійснювати від літієвої батарейки 3в (параметри для такого чіпа +2,7…. +3,5). Замість цього транзистора можна використовувати будь-який інший малопотужний транзистор NPN. Котушка транспондера була намотана на оправці діаметром 50мм дротом 0,22мм і налічує 50 витків. на Наразітранспондер зроблений активним - з зовнішнім харчуванням. На наступному етапі планується зробити пасивний варіант транспондера, що досить просто зробити розв'язку для живлення від даної котушки, додати діоди моста випрямляча і стабілізатор.


Рис.3Схема транспондера.

Тепер поговоримо про схему зчитувача для транспондера. Схема була адаптована на основі раніше використаного зчитувача для карт EMMARINE. Частина схеми з генератором на 74hc4060 даному етапісміливо видаляти, оскільки ми використовуємо активну мітку. Однак ця частина схеми нам знадобиться надалі, коли ми робитимемо пасивну мітку і нам буде потрібно отримати харчування від зчитувача. В іншому схема немає істотних відмінностей від схеми зчитувача для EMMARINE: пасивний піковий детектор - фільтр - підсилювач - компаратор. Схема має максимально можливу простоту та дозволяє зчитувати дані транспондера на відстані 10-12см при добре налаштованих контурах.

Можна ще далі спрощувати схему, залишивши тільки детектор і фільтр, поставити один транзистор на виході, який буде грати роль компаратора, але я не став так робити. На виході ми отримуємо двійковий сигнал прямокутної форми відповідно до кодованих тривалостей імпульсів переданих транспондером. Допустимі відхилення номіналів елементів при якому схема працездатна 5-10%. Живлення контролера та операційника +5В. Частота кварцу генератора, що задає контролера 12МГц. Вихід компаратора на LM358 підключений до ніжки переривання зовнішнього контролера INT0. У програмі контролера налаштований виклик переривання по фронту, що наростає, на ніжці зовнішнього переривання INT0. В обробнику переривання відбувається перевірка синхронізуючих імпульсів, а потім перевірка заголовка пакета і запис вмісту в буфер контролера. Дані лічені пакети передаються за інтерфейсом RS232 на ПК. Для налаштування терміналки вказуємо наступні параметри: швидкість 57.6Kb/s, 8 біт даних, 1стоп біт, без контролю парності.

При прийомі пакета контролер розраховує контрольну суму прийнятих байт і передає дані терміналку (пакет і CRC). У разі збігу контрольних сумрозрахованої контролером і прийнятої пакеті виводиться сигнал на ніжку PORTB.0 (14) контролера (LED1 на схемі). Можна підключити до дану точкупищалку із вбудованим генератором або світлодіод через опір. При зчитуванні коректного ключа контролер забороняє зовнішні переривання і затримує 1с перед наступним зчитуванням. Передбачено також режим роботи даного зчитувача як основи RFIDзамку. Для цього необхідно в EEPROM контролера зчитувача повністю записати байти дампа транспондера - 10 байт. Дані пишуться в EEPROM зчитувача так само, як у EEPROM транспондера. В даному випадку при зчитуванні чергового транспондера та збігу його із записаним в EEPROM зчитувача виводиться сигнал на ніжку PORTB.1 (15) контролера (LED2 на схемі). До цієї точки можна підключити світлодіод через опір або вихідний ключ (транзистор) на реле виконавчого устрою. Тепер ми отримали замок RFID під конкретний ключ і звичайний зчитувач в одному флаконі.


Рис.4Схема зчитувача RFID міток. (Збільшити схему)

Отже, підіб'ємо проміжні підсумки. Виготовлено власний рідер та транспондер під даний зчитувач. Ми захистили своє обладнання від сторонніх пристроївякі працюють із популярними протоколами RFID. Наступним кроком буде виготовлення пасивної мітки для нашого зчитувача. відомі виробникипромислових транспондерів та портування коду обладнання на дешевші моделі контролерів. В архіві до статті додаю прошивки для транспондера та зчитувача.

Завантажити прошивку:
У вас немає доступу до скачування файлів з нашого сервера

Сьогодні я розповім про RFID модуль RC522, на базі чіпа MFRC522. Живлення 3.3В, дальність виявлення до 6см. Призначений для читання та записи RFIDміток із частотою 13.56 МГц. Частота в даному випадку дуже важлива, оскільки RFID мітки існують у трьох частотних діапазонах:


  • Мітки діапазону LF (125-134 кГц)

  • Мітки діапазону HF (13,56 МГц)

  • Мітки діапазону UHF (860-960 МГц)

Саме цей модуль працює з мітками діапазону HF, зокрема з протоколом MIFARE.

Для роботи з модулем можна використовувати стандартну бібліотеку RFID що входить у Arduino IDE, проте є інша бібліотека, написана спеціально під даний модуль - MFRC522 (1 Мб) . Обидві бібліотеки цілком зручні, однак у MFRC522 більше спеціальних функцій, дозволяють максимально скоротити підсумковий код програми.

Підключення

Деякі зіткнутися з проблемою - назва пінів у більшості уроків та посібників може не відповідати розпинуванню на вашому модулі. Якщо в скетчах вказано пін SS, а на вашому модулі його немає, то швидше за все він позначений як SDA. Нижче наведено таблицю підключення модуля для найпоширеніших плат.

MFRC522 Arduino Uno Arduino Mega Arduino Nano v3

Arduino Leonardo/Micro

Arduino Pro Micro
RST 9 5 D9 RESET/ICSP-5 RST
SDA(SS) 10 53 D10 10 10
MOSI 11 (ICSP-4) 51 D11 ICSP-4 16
MISO 12 (ICSP-1) 50 D12 ICSP-1 14
SCK 13 (ICSP-3) 52 D13 ICSP-3 15
3.3V 3.3V 3.3V Стабілізатор 3,3В Стабілізатор 3,3В Стабілізатор 3,3В
GND GND GND GND GND GND

Піни управління SS(SDA) і RST задаються в скетчі, так що якщо ваша плата відрізняється від тієї, що я використовуватиму в своїх прикладах, а використовую UNO R3, вказуйте піни з таблиці на початку скетчу:


#define SS_PIN 10 #define RST_PIN 9

Приклад №1: Зчитування номера картки

Розглянемо приклад із бібліотеки RFID – cardRead. Він не видає дані з карти, а лише її номер, чого зазвичай буває достатньо для багатьох завдань.


#include #include #define SS_PIN 10 #define RST_PIN 9 RFID rfid(SS_PIN, RST_PIN); // Дані про номер карти зберігатися в 5 змінних, запам'ятовуватимемо їх, щоб перевіряти, чи ми вже зчитували таку карту int serNum0; int serNum1; int serNum2; int serNum3; int serNum4; void setup() ( Serial.begin(9600); SPI.begin(); rfid.init(); ) void loop() ( if (rfid.isCard()) ( if (rfid.readCardSerial())) ( // Порівнюємо номер картки з номером попередньої картки if (rfid.serNum != serNum0 && rfid.serNum != serNum1 && rfid.serNum != serNum2 && rfid.serNum != serNum3 && rfid.serNum != нова, то зчитуємо*/ Serial.println(" "); Serial.println("Card found"); serNum0 = rfid.serNum; rfid.serNum; //Виводимо номер картки Serial.println("Cardnumber:"); Serial.print("Dec: "); Serial.print(rfid.serNum,DEC); Serial.print(", "); .print(rfid.serNum,DEC); Serial.print(", "); Serial.print(rfid.serNum,DEC); Serial.print(", "); Serial.print(rfid.serNum,DEC); Serial.print(", "); Serial.print(rfid.serNum,DEC); Serial.println(" "); Serial.print("Hex: "); Serial.print(rfid.serNum,HEX); .print(", "); Serial.print(rfid.serNum,HEX); Serial.print(", "); Serial.print(rfid.serNum,HEX); Serial.print(", "); Serial.print(rfid.serNum,HEX); Serial.print(", "); Serial.print(rfid.serNum,HEX); Serial.println(" "); ) else ( /* Якщо це вже лічена карта, просто виводимо точку */ Serial.print("."); ) ) ) rfid.halt(); )

Скетч залився, світлодіод живлення на модулі спалахнув, але модуль не реагує на карту? Не варто панікувати, чи тікати шукати "правильні" приклади роботи. Швидше за все, на одному з пінів просто немає контакту - отвори на платі трохи більші за товщину перемички, так що варто спробувати їх переставити. На платі не світиться світлодіод? Спробуйте переставити перемичку, яка веде в 3.3В, і переконайтеся, що на платі вона підключена саме до 3.3В, подача харчування в 5В може вашу плату запросто вбити.

Допустимо, все у вас заробило. Тоді, зчитуючи модулем RFID мітки, у моніторі послідовного портупобачимо таке:


Тут я зчитував 3 різні мітки, і як видно всі 3 він успішно рахував.

Приклад №2: Зчитування даних із картки

Розглянемо більш опрацьований варіант - зчитуватиме не тільки номер картки, а й усі доступні для зчитування дані. Цього разу візьмемо приклад із бібліотеки MFRC522 – DumpInfo.


#include #include #define RST_PIN 9 // #define SS_PIN 10 // MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance void setup() ( Serial.begin(9600); // Ініціалізуємо монітор послідовного порту while (!Serial); // Нічого не робимо доки він не відкритий (для Arduino на чіпі ATMEGA32U4) SPI.begin() // Ініціалізуємо SPI шину mfrc522.PCD_Init(); // Ініціалізуємо RFID модуль ShowReaderDetails(); // Виводимо дані про модуль MFRC522 Serial.println(F("Scan PICC to see UID, type, and data blocks...")); ) void loop() ( // Шукаємо нову карту if (! mfrc522.PICC_IsNewCardPresent()) ( return; ) // Вибираємо одну з карт if (! mfrc522.PICC_ReadCardSerial()) ( return; ) // Виводимо дані з карти mfrc522.PICC_DumpToSerial&. ) void ShowReaderDetails() ( // Отримуємо номер версії модуля byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg); Serial.print(F("MFRC522 Software Version: 0x")); Serial.print(v, HEX); (v == 0x91) Serial.print(F(" = v1.0")); else if (v == 0x92) Serial.print(F(" = v2.0")); else Serial.print(F ("(unknown)"));Serial.println(""); // Коли отримуємо 0x00 або 0xFF, передача даних порушена if ((v == 0x00) || (v == 0xFF)) ( Serial.println( F("WARNING: Communication failure, is the MFRC522 propery connected?")); ) )

Якщо попередній приклад працював без помилок, то й у цьому виникнути проблем не повинно. Хоча проїзний на метро, ​​який без проблем видавав номер картки в попередньому прикладі, в цьому виявився з невизначеним типом даних, і модуль нічого крім номера карти рахувати не зміг.

Як результат, вважаючи дані з карти, отримаємо її тип, ідентифікатор і дані з 16 секторів пам'яті. Слід зазначити, що карти стандарту MIFARE 1K складаються з 16 секторів, кожен сектор складається із 4 блоків, а кожен блок містить 16 байт даних.


Приклад №3: Запис нового ідентифікатора на карту

У цьому прикладі ми розглянемо зміну ідентифікатора картки (UID). Важливо знати, що не всі карти підтримують зміну ідентифікатора. Карта може бути перезаписувана, але це означає лише перезаписування даних. На жаль, ті карти, які були у мене на руках, перезапис UID не підтримували, але код скетчу я тут про всяк випадок наведу.


#include #include /* Задаємо тут новий UID */ #define NEW_UID (0xDE, 0xAD, 0xBE, 0xEF) #define SS_PIN 10 #define RST_PIN 9 MFRC522 mfrc522(SS_PIN, RST_PIN); MFRC522::MIFARE_Key key; void setup() ( Serial.begin(9600); while (!Serial); SPI.begin(); mfrc522.PCD_Init(); Serial.println(F("Warning: this example overwrite use with care!")); for (byte i = 0; i< 6; i++) { key.keyByte[i] = 0xFF; } } void loop() { if (! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial()) { delay(50); return; } // Считываем текущий UID Serial.print(F("Card UID:")); for (byte i = 0; i < mfrc522.uid.size; i++) { Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "); Serial.print(mfrc522.uid.uidByte[i], HEX); } Serial.println(); // Записываем новый UID byte newUid = NEW_UID; if (mfrc522.MIFARE_SetUid(newUid, (byte)4, true)) { Serial.println(F("Wrote new UID to card.")); } // Halt PICC and re-select it so DumpToSerial doesn"t get confused mfrc522.PICC_HaltA(); if (! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial()) { return; } // Считываем данные с карты Serial.println(F("New UID and contents:")); mfrc522.PICC_DumpToSerial(&(mfrc522.uid)); delay(2000); }

Приклад №4: Запис даних на карту

Ось і нарешті те, до чого ми так довго добиралися – запис даних на карту. Найсолодша частина роботи з модулем - можливість зробити копію вже існуючої карти, щось додати або змінити, це набагато цікавіше, ніж просте зчитування.

Змінимо один із блоків даних на карті:


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

І як результат, отримуємо картку із зміненим блоком даних:


Тепер, навчившись зчитувати та записувати блоки даних картки, ви можете поексперементувати з мітками, які, швидше за все, є у вас - пропуски, проїзні громадського транспорту. Спробуйте зчитувати і записувати дані з цих карт, пара дублікатів пропуску ніколи не завадить, так?

На цьому все, підписуйтесь і стежте за публікаціями. Наступного разу я розповім і покажу як на стандартний символьний дисплей 1602 додавати символи користувача, фактично додаючи на дисплей графіку.

  • Програмування мікроконтролерів
  • Як відомо, у багатьох системах доступу використовуються карти RFID стандарту EM-Marin із частотою 125 КГц. Не винятком став домофон мого будинку. Одна проблема – непогано б навчитися копіювати такі карти, бо цінники на їхнє копіювання не радують. У мережі, звичайно, існує досить багато схем копіювальників (та й китайці продають свої копіювальники за копійки – правда, вони часто при копіюванні ставлять свій пароль на болванки), але чому б не зібрати свій власний копіювальник? Ось про це і наведена нижче стаття.

    Починати розробку копіювальника варто з'ясувати, а на що взагалі можна скопіювати такі мітки? Почитавши форуми, можна дізнатися, що найпоширенішими болванками для копіювання є T5577, T5557, EM4305.

    Тепер потрібна схема. Візьмемо аналогову частину такого копіювальника у RECTO та підключимо її до мікроконтролера atmega8. Доповнимо перетворювачем рівнів для підключення до COM-порту на базі max232 (бажаючі можуть використовувати ST232 або ще що, щоб підключитися по USB, але у мене на комп'ютері COM-порт є, як є і перехідник USB-COM, так що у мене таке завдання не стояло).

    Вийде ось така схема:

    Що вона собою являє? Подвійний емітерний повторювач, коливальний контур, детектор та RC-фільтри. За рахунок того, що RC-фільтри мають різні постійні часу, порівнюючи між собою рівні напруги між каскадами, можна виділяти зміну сигналу RFID-мітки. Даним завданням у нас буде займатися вбудований в atmega8 компаратор. Генерацію 125 КГц сигналу у нас буде забезпечувати вбудований у atmega8 ШІМ-контролер.

    Комбінація RFID-мітка – зчитувач утворюють трансформатор, де мітка є вторинною обмоткою. Передача інформації міткою здійснюється шляхом зміни навантаження вторинної обмотки. В результаті в котушці зчитувача (первинної обмотки) змінюється струм. Виділенням цих імпульсів струму займається наведена вище аналогова частина схеми. Коливальний контурпотрібно налаштувати максимальна напругав контрольній точці, наприклад, змотуючи/намотуючи витки котушки. Щоправда, кажуть, краще все ж таки напруга трохи менша за максимум - стабільніше працює. У мене в контрольній точці близько 40 ст.

    Копіювана мітка використовує кодування типу манчестер. Для того, щоб розшифрувати даний код, Досить за будь-якою зміною фронту сигналу пропускати три чверті періоду слота біта і наступного за ним перепаду сигналу фіксувати значення біта, яке буде відповідати значенню сигналу після перепаду. При декодуванні варто встановити вікно, в яке повинен відбутися перепад сигналу - не більше половини періоду біта слота.

    Метод розшифрування манчестерського кодуванняі код для цього я взяв у Shads. Можна, звичайно, було написати свій власний, але я поспішав запустити копіювальник - хотілося переконатися, що робоча схема і прийом міток проводиться. Так цей фрагмент і залишився у коді копіювальника. Також виявилося, що у мене компаратор налаштований інверсно, ніж потрібно код декодування. Змінив у коді. Отже, ми отримали послідовності нулів та одиниць. Як отримати код карти?

    А дуже просто. Приймемо, що номер картки по нібблам має вигляд AB CD EF GH IJ. Карта видає ось що:

    1) Дев'ять одиниць на початку;
    2) Ніббл A;
    3) парність ніблу A (1 біт);
    4) Ніббл B;
    5) парність ніббла B (1 біт);

    16) Нібл I;
    17) парність ніббла I (1 біт);
    18) Ніббл J;
    19) парність ніббла J (1 біт);
    20) Ніббл парності колонок для ніблів A B C D E F G H I J;
    21) Біт 0.

    Зчитуємо всі 64 біти, розшифровуємо та отримуємо 40 біт коду карти. Логічно, якщо самому видати такий код, замикаючи котушку картки доданої до зчитувача, ми отримаємо емулятор карти. Але зараз нас цікавить не він.

    Карту ми читати навчилися, а ось як передати дані карті? Для цього потрібно просто вмикати або вимикати частоту 125 КГц відповідно до протоколу обміну карткою. На час "мовчання" зчитувача карта живиться запасеною енергією.

    Болванки T5557/T5577 повністю сумісні між собою за протоколами запису, однак, мають трохи різні мінімальні та максимальні часиімпульсів (на щастя, часи T5557 перекриваються з T5577). У EM4305 протокол запису інший.

    Щоб записати T5557, я скористався кодом BolshoyK. У таблиці нижче наведено параметри сигналів для брелока T5557.

    Запис починається із сигналу StartGape – потрібно вимкнути сигнал 125 КГц приблизно на 300 мкс. Це сигнал на карті, що зараз їй почнуть передавати дані. Далі слід передати болванці інформацію. Кодування даних - той же манчестер.

    Болванки T5557/T5577 та EM4305 багатофункціональні та вміють різні видимодуляцій, підтримують паролі та ще багато чого. У кожній болванці на борту є набір блоків по 32 біти. Призначення цих блоків є різним. У деяких – код ключа, що видається (він займає два блоки). В інших – конфігурація. По-третє – ідентифікатор виробника. Ми будемо використовувати обмежений функціонал, тому охочі розібратися, що означають усі ці біти, можуть зазирнути в документацію до болванок (я доклав її до архіву).

    Блоки зібрані на дві сторінки (0 і 1).

    У нульовій сторінці є блок конфігурації з індексом 0. Його ми й задаватимемо. Для T5557/T5577 у нас будуть наступні конфігураційні байти: 0x00,0x14,0x80,0x40 відповідно до таблиці з документації (червоним я відмітив обрані одиничними бітами режими):

    Таким чином, у нас вибрано: частота передачі даних RF/64 (125 КГц/64), кодування типу манчестер, видача блоків до другого (у блоках 1 і 2 у нас розташовуватиметься код, що видається карткою). Перед записом слід надіслати код операції (2 біти opcode) та один біт клямки (lockbit). Коди операції 10b і 11b передують запису даних для сторінок 0 і 1 (молодший біт визначає номер сторінки, старший - код запису сторінки). У нас видається 10b для коду операції (вся робота йде з нульовою сторінкою) і 0b для біта клямки. Після передачі всіх цих даних необхідно передати трибітну адресу сторінки, що записується. Всі передачі для T5557/T5577 ведуться від старшого біта до молодшого.

    Задавши код карти в блоках 1 та 2 та конфігурацію в блоці 0 можна отримати дублікат RFID-мітки. Як бачите, все просто.

    Наступний тип болванок – це EM4305. Ось розбиратися із записом цієї болванки мені довелося самому. Вона також складається з блоків по 32 біти, але їхнє призначення інше.

    Кодування даних, що передаються карті – за перепадами за інтервал часу. Якщо перепад за інтервал часу був, то це нуль, а якщо не було – одиниця. Конфігураційне слово зберігається в 4 байті і собі я визначив його так: 0x5F,0x80,0x01,0x00 (кодування манчестер, RF/64, видача слова 6). У слова 5 і 6 записую код карти (ті самі 64 біта, що видає карта). EM4305 вимагає щоб передача велася з молодшого біта до старшого. Карта розуміє, що з нею починають обмін після видачі комбінації імпульсів:

    1. Вимикаємо поле на 48 мкс.
    2. Включаємо поле на 96 мкс.
    3. Вимикаємо поле на 320 мкс.
    4. Включаємо поле на 136 мкс.
    5. Відключаємо поле до наступної команди.
    Команда на запис блоку карті передається так:
    1. Шолом вищевказану послідовність імпульсів.
    2. Шолом 0b.
    3. Передаємо CC0-CC1 та їх парність P. (0101b для запису, див. таблиці нижче).
    4. Передаємо адресу блоку (див. таблицю), два доповнюють нуля та парність адреси.
    5. Передаємо дані блоку (32 біти).

    Формат команди


    Коди команд

    Формат адреси блоку

    Таким чином задається конфігурація болванки EM4305 та її код.

    Власне, нічого більшого простому копіювальнику і не потрібно.

    Я зробив кілька варіантів копіювальника з різними дисплеями. Наприклад, ось копіювальник з дисплеєм 1602:

    А ось відео роботи копіювальника на екрані LPH9157-02.