Кодовой замок на rfid-rc522

Oksymoron
Offline
Зарегистрирован: 28.01.2017

Доброго времени суток! Имееться скетч разработтаный Дмитрием Осиповым, все работает отлично, но когда подносишь карту "админа" ее считывает несколько раз и попросту не успеваешь отнести ее. как это можно исправить?


//Дмитрий Осипов. http://www.youtube.com/user/d36073?feature=watch
//Видео  https://www.youtube.com/watch?v=a583vq0vXyg&list=PLGgDni6kkxJ1YbFWXOnOt6...
#include <EEPROM.h> // Подключаем библиотеку для записи в энергонезависимую память "Card UID" / уникальный номер NFC карты.
#include <SPI.h>
#include <MFRC522.h> // скачанная библиотека "RFID" для RC522 Card Read Module.
// ****************************************
/*
Для RC522 Card Read Module. подключение для Arduino Uno и Mega, производится к разным Pin!
 ----------------------------------------------------- Nicola Coppola
 * Pin layout should be as follows:
 * Signal     Pin              Pin               Pin
 *            Arduino Uno      Arduino Mega      MFRC522 board
 * ------------------------------------------------------------
 * Reset      9                5                 RST
 * SPI SS     10               53                SDA
 * SPI MOSI   11               51                MOSI
 * SPI MISO   12               50                MISO
 * SPI SCK    13               52                SCK
 
 */

// Два Pin (SS и RST) допускают произвольное подключение и конфигурируются в коде.
// !(SS - он же - SDA).
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);  // Объект MFRC522C / reate MFRC522 instance.
unsigned long uidDec, uidDecTemp;  // Для отображения номера карточки в десятичном формате.
// **************************************************************

// Массив для хранения 50 "Card UID" / уникальных номеров NFC карт, считанных из EEPROM. 
unsigned long CardUIDeEPROMread[] = {
  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,
  30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49};

int ARRAYindexUIDcard; // Индекс для массива CardUIDeEPROMread.

int EEPROMstartAddr; // Стартовая ячейка памяти для записи / чтения EEPROM "Card UID".
// -----------------------------

int LockSwitch = 6; // Замок / Переключатель / Блокиратор.
int OpenDoor = 5; // открыть дверь
int PiezoPin = 7; // Piezo / Динамик.

void setup(){   
 Serial.begin(9600); 
 SPI.begin();
  mfrc522.PCD_Init(); // инициализация MFRC522 / Init MFRC522 card.

  pinMode(PiezoPin, OUTPUT);
  digitalWrite(PiezoPin, HIGH),delay(100),digitalWrite(PiezoPin, LOW); // Подадим писк при запуске.
  EEPROMreadUIDcard(); // Запускаем функцию, для перезаписи массива CardUIDeEPROMread, данными из EEPROM.

  // Если хотите увидеть в Serial мониторе все записанные № Card-UID, раскомментируйте строку.
  for(int i = 0; i <= 49; i++)Serial.print(i),Serial.print(" ---- "),Serial.println(CardUIDeEPROMread[i]);

  //for (int i = 0; i < 512; i++)EEPROM.write(i, 0); // EEPROM Clear / Очистить / стереть EEPROM. 
}

void loop() {

  // Поиск новой NFC карты / Look for new cards.
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // Выбор карточки / Select one of the cards.
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  // Выдача серийного номера карточки "UID".
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
    uidDecTemp = mfrc522.uid.uidByte[i];
    uidDec = uidDec*256+uidDecTemp;  
  }  
  // ----------------------------------------
  // uidDec - Это полученный "Card UID" / уникальный номер NFC карты.

  // Записываем "вручную" в sketch № "Card UID" карты администратора, для запуска "режима записи" в EEPROM "Card UID" пользователей.
  // Проверяем если "Card UID" совпадёт с заранее записанным "Card UID" администратора, или LockSwitch больше 0.
  // Внимание!, замените "Card UID" администратора № 3556194005, на свой "Card UID". 
  if (uidDec == 3556194005 || LockSwitch > 0)EEPROMwriteUIDcard(); // Запускаем функцию записи в EEPROM "Card UID" пользователей.
  // ----------------------------------------


  // Для режима управления.
  if (LockSwitch == 0) // только если находимся в "режиме управления".
  {
    // Подготавливаемся для перебора массива CardUIDeEPROMread.
    for(ARRAYindexUIDcard = 0; ARRAYindexUIDcard <= 49; ARRAYindexUIDcard++) 
    {
      // фильтр, на тот случай если мы не запишим все 50 переменных массива, в не записанных переменных массива будут значение 0.    
      if (CardUIDeEPROMread[ARRAYindexUIDcard] > 0) // Перебираем весь массив CardUIDeEPROMread, фильтруем от 0.
      {
        //  Перебираем весь массив CardUIDeEPROMread, Если поднесённая карта совпадёт с одной из 50  переменных массива.       
        if (CardUIDeEPROMread[ARRAYindexUIDcard] == uidDec) // Если обнаружено совпадение с поднесенной картой.
        {
          CommandsCARD(); // Запускаем функцию для выполнения любых действий, в зависимости от "Card UID" поднесённой карты.
          break; // Выходим, останавливаем проверку / перебор / поиск, в массиве CardUIDeEPROMread.
          // Полезная вещь! Итак, в момент перебора массива, в случае совпадения с поднесенным "Card UID", мы останавливаем 
          // цикл  for, с помощью break, и в значении ARRAYindexUIDcard сохранится индекс массива, в котором находился "Card UID".
          // Знания значения индекса массива, упростит выполнение других задач. 
        }
      }
    }   
    // ARRAYindexUIDcard == 50 Означает, что мы перебрали весь массив от 0 до 49, и не обнаружили совпадений с поднесённой "Card UID".
    // То есть поднесенная карта отсутствует в базе, выводим на дисплей "не найдена карта" и № "Card UID" карты.
    if (ARRAYindexUIDcard == 50)Serial.println("NOT  Found CARD-UID"),Serial.println(uidDec);
    delay(2000);    
    ARRAYindexUIDcard = 0;
  }
} 

// ******************************************
// ******************************************



// Делаем функцию, записи в EEPROM "Card UID" пользователей, максимум 50 "Card UID".
void EEPROMwriteUIDcard() {

  if (LockSwitch == 0) // Если находились в режиме управления.
  {
    Serial.println("   START    RECORD   Card UID   CLIENT"); 
    for(int i = 0; i <= 2; i++)delay(500),digitalWrite(PiezoPin, HIGH),delay(500),digitalWrite(PiezoPin, LOW); // 3 раза пискнем.
  } 

  // -------

  // Для пропуска записи в ячейку памяти.
  if (LockSwitch > 0) // Если находимся в "режиме записи".
  {
    // Внимание!, замените "Card UID" администратора № 3556194005, на свой "Card UID". 
    if (uidDec == 3556194005) // Если поднесена карта администратора. 
    {
      Serial.println("   SKIP     RECORD   "); 
      Serial.println(EEPROMstartAddr/5); // Выводим № пропущенной ячейки памяти.
      EEPROMstartAddr += 5; // Пропускаем запись в ячейку памяти, если не хотим записывать туда "Card UID".
      digitalWrite(PiezoPin, HIGH),delay(200),digitalWrite(PiezoPin, LOW); // 1 раз пискнем.
    }

    else // Иначе, то есть поднесена карта для записи.

    // "Card UID" / № карты это "длинное число", которое не поместится в одну ячейку памяти EEPROM. 
    // Разрубим "длинное число" на 4 части, и кусками, запишем его в 4 ячейки EEPROM. Начинаем запись с адреса EEPROMstartAddr.

    {
      EEPROM.write(EEPROMstartAddr, uidDec & 0xFF); 
      EEPROM.write(EEPROMstartAddr + 1, (uidDec & 0xFF00) >> 8); 
      EEPROM.write(EEPROMstartAddr + 2, (uidDec & 0xFF0000) >> 16); 
      EEPROM.write(EEPROMstartAddr + 3, (uidDec & 0xFF000000) >> 24);
      // Записали!.
      delay(10);
      // --
      Serial.println("RECORD OK! IN MEMORY "); 
      Serial.println(EEPROMstartAddr/5); // Выводим № записанной ячейки памяти.
      EEPROMstartAddr += 5; // Прибавляем 5 к стартовой ячейки записи.
      for(int i = 0; i <= 40; i++)delay(5),digitalWrite(PiezoPin, HIGH),delay(5),digitalWrite(PiezoPin, LOW); // пискнем.
    }   
  }

  LockSwitch++; // Разблокируем режим записи, и заблокируем режим управления. 

  if (EEPROMstartAddr/5 == 50) // если дошли до 50. 
  {
    delay(2000);
    Serial.println("RECORD FINISH"); 
     digitalWrite(PiezoPin, HIGH),delay(3000),digitalWrite(PiezoPin, LOW); // Длинный писк.
    EEPROMstartAddr = 0;   
    uidDec = 0;
    ARRAYindexUIDcard = 0;
    EEPROMreadUIDcard(); // Запускаем функцию, для перезаписи массива CardUIDeEPROMread, данными из EEPROM.
  } 
}

// -------------------------------------------


// Делаем функцию, перезаписи массива CardUIDeEPROMread, данными из EEPROM.
void EEPROMreadUIDcard()
{
  for(int i = 0; i <= 49; i++)
  {
    byte val = EEPROM.read(EEPROMstartAddr+3);   
    CardUIDeEPROMread[ARRAYindexUIDcard] = (CardUIDeEPROMread[ARRAYindexUIDcard] << 8) | val; 
    val = EEPROM.read(EEPROMstartAddr+2); 
    CardUIDeEPROMread[ARRAYindexUIDcard] = (CardUIDeEPROMread[ARRAYindexUIDcard] << 8) | val; 
    val = EEPROM.read(EEPROMstartAddr+1); // увеличиваем EEPROMstartAddr на 1.
    CardUIDeEPROMread[ARRAYindexUIDcard] = (CardUIDeEPROMread[ARRAYindexUIDcard] << 8) | val; 
    val = EEPROM.read(EEPROMstartAddr); 
    CardUIDeEPROMread[ARRAYindexUIDcard] = (CardUIDeEPROMread[ARRAYindexUIDcard] << 8) | val;

    ARRAYindexUIDcard++; // увеличиваем на 1.
    EEPROMstartAddr +=5; // увеличиваем на 5.
  }

  ARRAYindexUIDcard = 0;
  EEPROMstartAddr = 0; 
  uidDec = 0;
  LockSwitch = 0;
  DisplayWAiT_CARD();        
}


// -------------------------------------------



// Делаем функцию, заставка дисплея.
void DisplayWAiT_CARD()
{
  Serial.println("WAIT");
  Serial.println("CARD");
 }

// -------------------------------------------

// Делаем функцию, для выполнения любых действий, в зависимости от "Card UID" поднесённой карты.
void CommandsCARD()
{
  Serial.println("Hi "); // Выводим на дисплей "привет".

  // В "ARRAYindexUIDcard" будет временно хранится номер индекса массива, совпавшего с поднесенной Card-UID.
  // Например, если поднесённый Card-UID совпал, с записанным  Card-UID в ячейке № 0 / индексом массива ARRAYindexUIDcard № 0. 
  if (ARRAYindexUIDcard == 0)
  {
    Serial.println("Dmitry"); // Выводим на дисплей "Dmitry".
	digitalWrite(OpenDoor, HIGH),delay(1500),digitalWrite(OpenDoor, LOW);
    // ! Здесь, можно дописать любые другие действия. 
  }  

  else if (ARRAYindexUIDcard == 1) // Если Card-UID получен из ячейки № 1 / индекс массива № 1. 
  {
    Serial.println("Sergey"); 
    // ! Здесь, можно дописать любые другие действия. 
  }

  else if (ARRAYindexUIDcard == 2) // Если Card-UID получен из ячейки № 2 / индекс массива № 2.
  {
    Serial.println("Peter");
    // ! Здесь, можно дописать любые другие действия. 
  }

  else if (ARRAYindexUIDcard == 3) 
  {
    Serial.println("Vasily");
  }
  //....................... 
  else if (ARRAYindexUIDcard == 49) 
  {
    Serial.println("OSIPOV");
  }
  //---
  // Далее, самостоятельно пропишите ножное количество "else if (ARRAYindexUIDcard == ", максимум 50 условий.

  //---------------------------------------

  Serial.println(CardUIDeEPROMread[ARRAYindexUIDcard]); // Выводим на дисплей обнаруженный Card-UID.
  Serial.println(ARRAYindexUIDcard); // Выводим на дисплей  № индекса массива / ячейки, где хранился обнаруженный Card-UID
  // -------------

  // Подаём звуковой сигнал через PiezoPin, 
  // количество раз зависит от  № индекса массива / ячейки, где хранился обнаруженный Card-UID.
  for(int i = 0; i <= ARRAYindexUIDcard; i++)delay(20),digitalWrite(PiezoPin, HIGH),delay(20),digitalWrite(PiezoPin, LOW);
  delay(1); // Дёргаем микроконтроллер.
}





















qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Есть такой такой "ну очень редкий девайс" обычная кнопка. Ее тоже вроде опрашивают регулярно. Но почему-то народ делает так, что на нажатие кнопки выполняется действие однократно. И вот загадка как же они этого достигают :)

Oksymoron
Offline
Зарегистрирован: 28.01.2017

я просто новичок.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Oksymoron пишет:

я просто новичок.

Так раз новичок, не разрабатывайте сложные темы. Начните с простых. 

Oksymoron
Offline
Зарегистрирован: 28.01.2017

qwone пишет:

Oksymoron пишет:

я просто новичок.

Так раз новичок, не разрабатывайте сложные темы. Начните с простых. 

Прошу если вы можите помочь, помогите. Если не можите или не хотите пожалусто не флудите.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Oksymoron пишет:

Прошу если вы можите помочь, помогите. Если не можите или не хотите пожалусто не флудите.

Как я могу помочь, если вы не знаете основ. А если вы считаете что основы программирования на Ардуине, это стянуть чужой скечь и залить в Ардуину. А если он вас не устроит, то выложить здесь на форуме. То пожалуста, я не буду мешать вам набивать шишки. 

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

строку 83 заменить на 

if (uidDec == 3556194005 || LockSwitch > 0){delay(3000);EEPROMwriteUIDcard();}

даст задержку 3 сек перед началом записи.

код конечно говно, но раз работает - то и х с ним.

Oksymoron
Offline
Зарегистрирован: 28.01.2017

NeiroN пишет:

даст задержку 3 сек перед началом записи.

Большое спасибо.