Главная chevron_right Наши уроки chevron_right Arduino chevron_right Система контроля доступа на RFID считывателе и электромеханическом замке

Система контроля доступа на RFID считывателе и электромеханическом замке

Собираем систему контроля доступа на Arduino: RFID считыватель, электромеханический замок и силовой ключ. Добавляем и удаляем метки через карту-мастер, данные хранятся в энергон...

Видео-обложка запускается при наведении

Описание

В этом уроке мы разработаем систему контроля доступа в помещение, шкаф, ящик стола... Да куда угодно! В основе проекта электромеханический замок и RFID считыватель.

Видео

Нам понадобится

Для работы со считывателем необходимо установить библиотеку Wiegand. При необходимости, ознакомьтесь с нашей инструкцией по установке библиотек в Arduino IDE.

Подключение

RFID считывательPiranha UNO
D0 (зеленый провод)2
D1 (белый провод)3
ZUMMER (желтый провод)4
LED (коричневый провод)5
Vcc+ 12В
GND- 12В
Силовой ключPiranha UNO
GGND
VVcc
S6
+Vin+12В
-Vin-12В
+Vout+ замка
-Vout- замка

Скетч проекта

#include <Wiegand.h>         //  подключение библиотеки
#include <EEPROM.h>          //  Подключаем библиотеку для работы с энергонезависимой памятью

WIEGAND wg;                  //  создание объекта считывателя

#define INIT_ADDR 1023       // номер резервной ячейки (для EEPROM)
#define INIT_KEY 50          // ключ первого запуска. 0-254, на выбор (для EEPROM)

#define lock 6                  //  замок подключен к 6 пину
#define led 5                   //  светодиод (встроенный с считыватель) - 4 пин
#define zummer 4                //  зуммер (встроенный в считыватель) - 5 пин

///////////////////НАСТРОЙКИ///////////////////////
const int openTime = 200;     //  время, мс, на которое открывается замок
const int masterTime = 3000;  //  время, на которое активируется режим добавления новой метки
const int zummerTime = 2000;  // время работы светодиода и зуммера во время открытия замка
long masterKey = 5687942;       //  идентификационный номер метки мастера (мастер позволяет добавлять новые метки)
long keysArr[10] = {};          //  массив ключей из 10 меток

///////////////////////////////////////////////////

bool ledState = true;           //  установка флага для мигания светодиода
long timeStart;                 //  время, в которое сработала карта
long timeMasterStart;           //  время, в которое запустился цикл добавления новой метки
uint8_t k;                      //  счётчик количества приложенных раз метки Мастер
long printKey[10] = {};         //  массив выводимых меток в монитор порта

void setup() {                  //  светодиод, зуммер, замок - выходы
  pinMode(lock, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(zummer, OUTPUT);
  digitalWrite(led, HIGH);      //  светодиод, зуммер, замок ВЫКЛючены (светодиод и зуммер включаются подачей минуса на пин)
  digitalWrite(zummer, HIGH);
  digitalWrite(lock, LOW);

  Serial.begin(9600);           //  Инициализация последовательного порта на скорости 9600 бод
  wg.begin();                   //  Инициализация считывателя

  if (EEPROM.read(INIT_ADDR) != INIT_KEY) {     // первый запуск
    EEPROM.write(INIT_ADDR, INIT_KEY);          // записываем ключ
    EEPROM.put(0, keysArr);                     // записываем массив ключей (обнуляем данные, которые могли остаться в памяти после других проектов)
    Serial.println ("Массив данных обновлён.");
  }
  else{
    EEPROM.get(0, keysArr);                     //  читаем ключи
  }
}

void loop(){
  if(wg.available()){
    long id = wg.getCode(); if (id == masterKey) Serial.print("Master "); Serial.print("id = "); Serial.println(id);  //  чтение идентификатора метки и отправка в монитор порта

    if (id == masterKey){           //  если id карты - мастер. Добавляем новую метку в массив
      timeMasterStart = millis();   //  фиксируем время начала выполнения функции
      master();                     //  запускаем функцию master()
    }
    else{
      for (uint8_t i = 0; i < sizeof(keysArr)/sizeof(long); i++){ //  проверяем все элементы массива номеров меток
        if (id == keysArr[i]) {     //  если считанный номер совпал с i-м элементом
          succes();                 //  открываем замок
          return;                   //  заканчиваем перебор элементов
        }
      }
      reject();                     //  иначе отказ
    }
  }
}

void succes(){                      //  функция открытия замка
  digitalWrite(led, LOW);           //  ВКЛючаем светодиод и зуммер (для включения на них нужно подать "-")
  digitalWrite(zummer, LOW);
  digitalWrite(lock, HIGH);         //  открываем замок на время openTime
  delay(openTime);
  digitalWrite(lock, LOW);          //  заканчиваем подавать напряжение для открытия
  delay(zummerTime-openTime);
  digitalWrite(led, HIGH);          //  ВЫКЛючаем светодиод и зуммер
  digitalWrite(zummer, HIGH);
}

void master(){                      //  функция мастер
  while(timeMasterStart + masterTime > millis()){        //  пока время нахождения в режиме Мастер не вышло
    if (timeStart + 100 < millis()){                     //  мигаем светодиодом каждые 100 мс
      timeStart = millis();
      ledState = ! ledState;
      digitalWrite(led, ledState);
    }
    if(wg.available()){
      long idNew = wg.getCode();                          //  считываем новую метку
      if (idNew != masterKey){                            //  если метка - не мастер
        for (uint8_t i = 0; i < sizeof(keysArr)/sizeof(long); i++){  //  перебираем массив идентификаторов меток для поиска первого нуля, вместо котого можно её записать
          if (keysArr[i] == 0 || keysArr[i] == idNew) {   //  смотрим, записана ли метка, или мы осмотрели все записи и нашли первый 0 - свободное место, куда запишем метку
            keysArr[i] = idNew;                           //  записываем в массив
            EEPROM.put(0, keysArr);                       //  записываем массив в EEPROM
            Serial.print("Массив ключей изменён: ");      //  вывод в монитор порта всех номеров в массиве
            writeEEPROM();                                //  функция вывода массива в монитор порта
            succes();                                     //  открываем замок
            digitalWrite(led, HIGH);                      //  выключаем светодиод и зуммер
            digitalWrite(zummer, HIGH);
            break;
          }
        }
      }
      else if (idNew == masterKey){                       //  если метка - мастер
        k++;                                              //  увеличиваем счётчик - сколько раз подряд прикладывали метку мастер
        if (k >= 2){                                      //  если два раза
          k=0;
          for (uint8_t p = 0; p < sizeof(keysArr)/sizeof(long); p++){ // очищаем массив и EEPROM
            keysArr[p] = 0;
          }
          EEPROM.put(0, keysArr);
          Serial.println("Массив ключей очищен!");
          writeEEPROM();                                  //  выводим в монитор порта массив меток
        }
      }
    }
  }
  digitalWrite(led, HIGH);         //  отключаем светодиод и зуммер
  digitalWrite(zummer, HIGH);
  k=0;
}

void reject(){                     //  функция отказа в открытии замка
  for (uint8_t n=0; n<=2; n++){    //  повторяем три раза
    digitalWrite(led, LOW);        //  включаем зуммер и светодиод, ждём, выключаем
    digitalWrite(zummer, LOW);
    delay(100);
    digitalWrite(led, HIGH);
    digitalWrite(zummer, HIGH);
    delay(100);
  }
}

void writeEEPROM(){                //  функция вывода в монитор порта массива ключей меток
  EEPROM.get(0, printKey);
  for (uint8_t j = 0; j < sizeof(printKey)/sizeof(long); j++){
    Serial.print(printKey[j]);
    Serial.print("; ");
  }
  Serial.println("");
}

Описание работы

В начале скетча вы найдёте настройки, в том числе, номер карты-мастера, и массив из меток, изначально открывающих замок. Для того, чтобы узнать код метки (например для добавления мастера), запустите тестовый скетч. Полученный идентификатор впишите в переменную masterKey

Все добавленные метки помещаются в энергонезависимую память и остаются в ней даже при отключении питания.

Если что-то пошло не так, измените ключ первого запуска (INIT_KEY) на любой другой в указанном в скетче диапазоне. Это позволит стереть все добавленные ранее ключи на программном уровне.

Вы можете не использовать метку Мастер. В таком случае, запишите в массив keysArr[]номера меток, которые будут открывать замок. При необходимости, размер массива может быть увеличен.

Добавление новой метки

Для добавления новой метки, приложите метку Мастер к считывателю. С этого момента начинается отсчёт времени нахождения в режиме "Мастер" (задаётся переменной masterTime).

Пока устройство находится в режиме "Мастер", приложите новую метку к считывателю. Она будет добавлена в массив меток.

Удаление всех меток

Для удаления всех добавленных меток приложите карту Мастер к считывателю три раза подряд. Произойдет удаление всех меток (кроме Мастера).

Ссылки

Комплект для повторения проекта

Что понадобится

Это быстрый ориентир по основным модулям и деталям. Полный список для повторения проекта смотрите в самой статье.

11 позиций
Замок электромеханический невидимка (5 В) электромеханический замок Открыть в iArduino Стационарный RFID-считыватель бесконтактных карт 125 кГц RFID считыватель Открыть в iArduino Замок электромагнитный, 12V Электромагнитный замок Открыть в iArduino Замок электромеханический невидимка (12 В) Электромеханический замок Открыть в iArduino Piranha Uno R3 Прямой аналог Arduino Uno c микроконтроллером ATmega328P на ядре AVR для разработки электронных устройств на языке C++ Открыть в iArduino Trema Shield Плата расширения для удобного подключения периферийных устройств Открыть в iArduino Силовой ключ N-канал (Trema-модуль) Позволит управлять нагрузкой ШИМ сигналом. Например яркостью светодиодной ленты или скоростью мотора Открыть в iArduino Силовой ключ P-канал (Trema-модуль) Позволит управлять нагрузкой ШИМ сигналом. Например яркостью светодиодной ленты или скоростью мотора Открыть в iArduino Провод питания, DC (Папа) Открыть в iArduino Коннектор power jack Мама с клемником Открыть в iArduino Набор разъёмов JST Dupont (620 шт.) вот такими клемниками Открыть в iArduino
Все уроки Arduino