Предисловие: чем меньше люди будут разбираться в теме - тем больше у меня будет работы Задача: вывалить практически готовый скетч, чтобы махом решить две проблемы: первая - вынесена в предисловие, вторая - чтобы унять жажду быстрого результата у источников первой проблемы Железо: ардуина + RFID RDM6300, тот, который выплёвывает данные поднесённого ключа в UART и прост в общении, как рубь с полтиной. Реализация (комментарии присутствуют, на случай - а ну вдруг кто-то всё-таки захочет вкурить, как оно работает? ): Код (C++): #include <SoftwareSerial.h> // на каких пинах подключен RFID-считыватель SoftwareSerial sSerial(8,9); // тестовый пин, на котором будем включать светодиод, говорящий о том, что система закрыта/открыта const int ledPin = 13; // флаг, что юзер залогинен bool isUserLoggedIn = false; // длина ключа RFID-метки const byte RFID_TAG_LENGTH = 14; // сюда будем читать ключ byte enteredKey[RFID_TAG_LENGTH] = {0}; // здесь будем хранить информацию о последнем сравненном ключе, чтобы избежать повторного выполнения кода byte lastKey[RFID_TAG_LENGTH] = {0}; // массив ключей, которые нам известны byte knownKeys[][RFID_TAG_LENGTH]= { { 0x02, 0x30, 0x39, 0x30, 0x30, 0x34, 0x46, 0x35, 0x33, 0x46, 0x33, 0x45, 0x36, 0x03 } , { 0x02, 0x30, 0x46, 0x30, 0x30, 0x36, 0x31, 0x42, 0x46, 0x39, 0x32, 0x34, 0x33, 0x03 } // сюда дописывать ключи , {0,0,0,0,0,0,0,0,0,0,0,0,0,0} // заглушка, признак окончания массива ключей }; byte writePos = 0; // позиция записи unsigned long eraseKeyTimer = 0; // таймер присутствия ключа в считывателе const unsigned int waitEraseInterval = 1000; // через сколько миллисекунд можно повторно приложить ключ void setup() { Serial.begin(57600); sSerial.begin(9600); pinMode(ledPin,OUTPUT); digitalWrite(ledPin,LOW); Serial.println(F("System ready, locked.")); } // сравниваем ключи на совпадение bool sameKey(byte* k1, byte* k2) { return !memcmp(k1,k2,RFID_TAG_LENGTH); } // проверяем - известен ли нам ключ bool isKnownKey(byte* key) { byte pos = 0; while(1) { if(!memcmp(knownKeys[pos],key,RFID_TAG_LENGTH)) // ключ совпал { return true; } if(knownKeys[pos][0] == 0) // дошли до конца массива известных ключей break; pos++; } return false; } void loop() { while(sSerial.available()) { // есть данные от ключа, считываем их enteredKey[writePos++] = sSerial.read(); if(writePos >= RFID_TAG_LENGTH) { // прочитали весь ключ, проверяем его writePos = 0; if(isKnownKey(enteredKey)) // ключ известен { if(!sameKey(enteredKey,lastKey)) // если только его не продолжают держать у считывателя { // пишем, что мы узнали ключ Serial.println(F("Key known :)))")); // меняем статус системы isUserLoggedIn = !isUserLoggedIn; digitalWrite(ledPin,isUserLoggedIn ? HIGH: LOW); Serial.println(isUserLoggedIn ? F("System unlocked.") : F("System locked.")); } } else // ключ неизвестен { // если только ключ не тот же, т.е. если его не держат на считывателе if(!sameKey(enteredKey,lastKey)) Serial.println(F("Key unknown :(")); } // запоминаем, какой ключ на считывателе memcpy(lastKey,enteredKey,RFID_TAG_LENGTH); // обновляем таймер присутствия ключа в считывателе eraseKeyTimer = millis(); } // if(writePos >= RFID_TAG_LENGTH) } // while // если ключ отсутствует больше N секунд - стираем информацию о последнем введённом ключе if(millis() - eraseKeyTimer > waitEraseInterval) { memset(lastKey,0,RFID_TAG_LENGTH); } /* // тестовый код для считывания поднесённых ключей if(sSerial.available()) { while(sSerial.available()) { char ch = sSerial.read(); Serial.print("0x"); if(ch < 16) Serial.print('0'); Serial.print(ch, 16); Serial.print(' '); } Serial.println(); } */ } Пользуйтесь, никогда не жалко поделиться набросками
Этот ридер действительно прост как огурец (не соленый), особенно в сравнении с RC522. Плюет ключи в виде строки в сериал порт и все. Если экзотики от ридера не нужно, например хранения данных в брелоках, то он даже лучше. Можно просто сравнивать как текст с эталоном с помощью какого нибудь string.compareTo(), благо громадной скорости от этой процедуры не требуется. Вот единственное, что мне не понравилось в нем по сравнению с RC522 - хрупкость. Нужно как можно быстрее зафиксировать его на рабочей поверхности пока проводки не отвалились. А то что радиус обнаружения метки мал, так этом в каком то смысле даже плюс.