КОРЗИНА
магазина
8 (499) 500-14-56 | ПН. - ПТ. 12:00-18:00
ЛЕСНОРЯДСКИЙ ПЕРЕУЛОК, 18С2, БЦ "ДМ-ПРЕСС"

Система контроля доступа на 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).

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

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

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

Ссылки




Обсуждение

Гарантии и возврат Используя сайт Вы соглашаетесь с условями