Как заставить работать rfid метку и клавиатуру вместе

maks.dav
Offline
Зарегистрирован: 13.12.2015

Делаю курсовой проект на тему "электронный замок". В основе проект лежит именно программирование микроконтроллера. Так вот, устройство работает по следующему принципу: подносим одну из 3х карт. Если это карта администартора или охраны - сразу происходит открытие двери, если карта служащего - необходимо подтвердить её вводом пароля с клавиатуры. Так вот, проблема в том, что после аутентификации карты работника не происходит ввод пароля, клавиатура не отвечает!.. Интересует пока только этот вопрос, почему? Код пока на стадии написания (выделяю интересующую часть кода жирным). Используется плата мега2560, rfid модуль RC522, и 16ти символьная клавиатура и экран подключенный по i2c интерфейсу (но его пока не писал).

#include <SPI.h>
#include <MFRC522.h> // библиотека "RFID".
#include <Keypad.h> // Подключаем библиотеку клавиатуры
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define SS_PIN 53
#define RST_PIN 48
MFRC522 mfrc522(SS_PIN, RST_PIN);

LiquidCrystal_I2C lcd(0x27, 16, 2);

const byte ROWS = 4; // 4 строки
const byte COLS = 4; // 4 столбца
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
  }; 
byte rowPins[ROWS] = {31, 33, 35, 37}; 
byte colPins[COLS] = {39, 41, 43, 45}; 
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

unsigned long uidDec, uidDecTemp;  // для храниения номера метки в десятичном формате
unsigned long uidDecAdmin = 1513925427; // карта Администартора
unsigned long uidDecSec = 909639397; // карта Охраны
unsigned long uidDecEmp = 1694405799; // карта Работника
String passInp = "";
String pass = "";
String passSave = "123456AB";

int ledProg = 1;
int ledDel = 2;
int butProg = 3;
int butDel = 4;
int countChar = 0;
int countError = 0;
char key;

void setup() {
  Serial.begin(9600);
  Serial.println("Waiting for card...");
  SPI.begin();  //  инициализация SPI / Init SPI bus.
  mfrc522.PCD_Init(); // инициализация MFRC522 / Init MFRC522 card.
  
  Serial.begin(9600);
  Serial.println("HELLOW!)");
  pinMode(ledProg, OUTPUT);
  pinMode(ledDel, OUTPUT);
  pinMode(butProg, INPUT);
  pinMode(butDel, INPUT);
 }

 void loop() {
  
  // Поиск новой метки
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }
  // Выбор метки
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  uidDec = 0;
  // Выдача серийного номера метки.
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    uidDecTemp = mfrc522.uid.uidByte[i];
    uidDec = uidDec * 256 + uidDecTemp;
  }
  Serial.println("Card UID: ");
  Serial.println(uidDec); 
  
  if (uidDec == uidDecAdmin) // Сравниваем Uid метки с Uid карты администратора.
  {
    Serial.println("Admin Card");
   
  }
  if (uidDec == uidDecSec)// Сравниваем Uid метки с Uid карты охраны.
  {
    Serial.println("Security Card");
  }
  if (uidDec == uidDecEmp)// Сравниваем Uid метки с Uid карты работника.
  {
    Serial.println("Employee Card");
    delay(2000);
// Ожидание ввода с клавиатуры
     char key = keypad.getKey(); 
          if (key){
          Serial.print(key);
          countChar++;
          if (countChar==9){
          pass="";
          passInp="";
          countChar = 0;
          Serial.println("Pass Long!!");
          }}
          pass = pass + key;
          Serial.println(pass);
          passInp=String(key);
          
          if (passInp=="#"){
          pass="";
          passInp="";
          countChar = 0;
          Serial.println("RESET");
          }
          if (passInp=="*"){
          pass="";
          passInp="";
          countChar = 0;
          Serial.println("RESET2");
          }
          if (pass==passSave){
          Serial.println("PASS OK");
          pass="";
          passInp="";
          countChar = 0;
          } 
   
    }  

    
}

P.S. Логику в работе кода искать не нужно - это всего лишь для обучения)

maks.dav
Offline
Зарегистрирован: 13.12.2015

Извиняюсь, код не выделился! Интересующая часть находится с 84 строки.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

строка 90: если после паузы в 2 сек в течение 0,0000001 сек ничего не нажато, перескакиваем на строку 99. Так задумано?

maks.dav
Offline
Зарегистрирован: 13.12.2015

Нет, не задумано. Были у меня тоже такие мысли, что я проскакиваю то самое время нажатия клавиши, и его каким-то способом нужно увеличить. Теперь опять же встречный вопрос, может посоветуете, как это сделать?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

maks.dav пишет:

P.S. Логику в работе кода искать не нужно - это всего лишь для обучения)

:))))))))))))

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

maks.dav пишет:
Нет, не задумано. Были у меня тоже такие мысли, что я проскакиваю то самое время нажатия клавиши, и его каким-то способом нужно увеличить. Теперь опять же встречный вопрос, может посоветуете, как это сделать?

один из вариантов - тупо ждать нажатия хоть какой-то клавиши, т.е. key будет равно любому числу, кроме нуля.

Например, в строке 90: вместо if сделать while:

while(key == 0){}; // ждем до тех пор, пока не будет нажата любая клавиша

Но это блокирующее условие, т.е МК не будет реагировать ни на что иное в это время.

 

 

maks.dav
Offline
Зарегистрирован: 13.12.2015

Tomasina пишет:

один из вариантов - тупо ждать нажатия хоть какой-то клавиши.

Например, в строке 90: вместо if сделать while:

А не получится так, что пока будет происходить ожидание нажатия, карты с большим приоритетом в этот момент не смогут считываться?

maks.dav
Offline
Зарегистрирован: 13.12.2015

нужно придумать немного другой вариант, или доработать предложенный вами) Спасибо

maks.dav
Offline
Зарегистрирован: 13.12.2015

а можно сделать так, чтобы, при отсутствии нажатия какой-либо клавиши, по истечении, к примеру, 5 секунд, происходил игнор оставшегося кода в теле условной конструкции?

добавлю-

подумал, не получится, мы ведь даже в тело условной конструкции не попадём..

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

[quote=maks.dav]подумал, не получится, мы ведь даже в тело условной конструкции не попадём..[/quote]

можно много чего, в том числе и таймаут, и реакцию на карту, но давайте сначала выстроим "на словах" четкий алгоритм - последовательность действий и реакций на возникающие события. А то сейчас получается слепили одно, потом судорожно пытаемся впихнуть в код новые мысли. Это непродуктивно.

maks.dav
Offline
Зарегистрирован: 13.12.2015

алгоритм следующий: опрос одной из трёх карт, в случае опроса администраторской - происходит открывание двери, в случае опроса карты охраны - происходит то же самое, но ещё с её помощью будем добавлять в базу новые коды. В случае опроса пользовательской карты - необходимо подтверждать её кодом, после чего дверь откроется. но в случае, если пользовательская карта была активирована, администратор или охранник беспрепятственно и без манипуляций с клавиатурой могли открыть дверь с помощью только своих карт. Ну вот как-то так.

Следовательно, вариант с постоянным ожиданием ввода пароля и блокировкой дальнийших возможных действий нам не подходит. Нужно этот процесс прерывать.

Согласен, алгоритм смешной, но преподавателю главное, чтобы были выполнены эти условия в коде.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

это описание задачи, а не алгоритм.

Поднесли карту - что происходит?
Карта опознана как администраторская - что происходит?
Карта опознана как карта охраны - что происходит?
Карта опознана как пользовательская - что происходит?
Карта не опознана однократно - что происходит? Не опознана N раз подряд (подбор карты) - что происходит?
"открывание двери" - как и на какую длительность? Что если дверь уже/еще открыта?
"подтверждение карты кодом" - что происходит при: при вводе неверной цифры в коде? 
вводе неверного кода? как опознать окончание ввода кода? что будет при поднесении карты при вводе кода?

И это далеко не полный перечень того, что должно быть отражено в алгоритме.

Попробуй нарисовать графически, в виде схемы, чтобы самому разобраться в нюансах.

Это с виду алгоритм простой, на самом деле даже в такой задаче много зависимостей, которые надо учесть.  К слову, в лифте от нажатия кнопки этажа до начала движения происходит около сотни проверок и прохождений условий. А кажется что все просто: "нажал - поехали".

maks.dav
Offline
Зарегистрирован: 13.12.2015

Я понимаю, что такое алгоритм, но я не вижу смысла его здесь описывать, т.к. причина создания темы мало с этим связана. Интересовало, как начать пользоваться клавиатурой, при выполнении определённых условий. И понятно, что постоянное ожидание ввода с клавиатуры и блокировка дальнейших действий - не лучший вариант. А использование исполняющих устройств и индикации, при выполнении определённых условий, пока второстепенно.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

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

Поэтому в контексте данной задачи выражаю полное несогласие с постулатом "Я понимаю, что такое алгоритм, но я не вижу смысла его здесь описывать, т.к. причина создания темы мало с этим связана. "

maks.dav
Offline
Зарегистрирован: 13.12.2015

я вас понял, и, пожалуй, соглашусь!.. Спасибо за помощь... видимо, придётся самому изобретать велосипед.