Использование MFRC522 вместе с другими входами (Bluetooth, клавиатура)
Я делаю небольшую парковку, которая включает в себя в основном открытие серводвигателя с помощью клавиатуры, Bluetooth (hc-05) и недавно добавленного Rfid (RC522). Я не могу получить данные из других источников, если хочу получить UID из RFID. это означает, что когда я добавил единственный фрагмент кода, который я нашел, который возвращает UID, кажется, что он блокирует весь цикл void(), поэтому все остальные входы/код не работают. Вот полный код:
#include <Servo.h> //Серводвигатель
#include <SoftwareSerial.h>//Библиотека функций Bluetooth: HC05 ПРЕВОСХОДНО!
#include "TM1637.h" //Библиотека функций 4-разрядного дисплея
#include <SPI.h>
#include <MFRC522.h>
// Кредит Бароряну
//авторское право (с)*/
const int rs = 38, en = 39, d4 = 36 ,d5 = 37, d6 = 41, d7 = 40;//Определение пинов LCD
const int DA=31, D0=30,D1=33,D2=32,D3=35;//Определение пинов данных КЛАВИАТУРЫ
const int servoPin=43,buzzer=42,rx=53,tx=52;//Определение (по порядку): servo pin, buzzer pin, 4DD pins и bluetooth pins(rx tx)
//контакт зуммера 36!
//,CLK=34,DIO=35
#define SS_PIN 45
#define RST_PIN 44
int count = 0;
int cnt=0;//это cnt используется позже, чтобы убедиться, что все 5 символов равны.
int cnt2=0;//используется для случая переключения, чтобы подсчитать, сколько символов уже было получено
int cnt3=0;
char c=0;//здесь размещаем полученный от пользователя char
char password[5] = {'8', '5', '2', '0', '#'};
char keysPressed[5] = "";
char keys[5]="";
byte customChar2[] = {
B00000,
B00000,
B01010,
B00000,
B10001,
B01110,
B00000,
B00000
};
byte customChar[] = {//Custom Char для ЖК-экрана, в данном случае; сердце.
0x00,
0x00,
0x0A,
0x1F,
0x1F,
0x0E,
0x04,
0x00
};
// #define DA 25 Используется для определения контактов клавиатуры и прочего с помощью #Define, который взаимодействует с процессором->
// #define D0 24 ->решено использовать вместо него const int.
// # определить D1 27
// # определить D2 26
// # определить D3 29
// # определить сервопин 37
// #определить зуммер 36
// # определить CLK 34
// # определить DIO 35
void lcdSetup();
void gateOpenSequence();
void returnKey(int key);
void wrongPassword();
void Beep();
SoftwareSerial Bluetooth(rx,tx);//инициализировать bluetooth для контактов
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);//инициализировать LCD на контакты
MFRC522 mfrc522(SS_PIN, RST_PIN); // Создать экземпляр MFRC522.
Servo servo;//инициализация сервопривода
byte nuidPICC[4];
void printHex(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
void setup()
{
Serial.begin(9600);
Bluetooth.begin(9600);
SPI.begin(); // Инициируем шину SPI
pinMode(DA ,INPUT);
pinMode(D0 ,INPUT);
pinMode(D1 ,INPUT);
pinMode(D2,INPUT);
pinMode(D3,INPUT);
mfrc522.PCD_Init(); // Инициировать MFRC522
lcd.begin(20,4);
lcdSetup();//Самостоятельно созданная функция, которая превращает ЖК-дисплей в наш предпочтительный экран по умолчанию "Главный экран"
servo.attach(servoPin);
servo.write(5);
pinMode(buzzer,OUTPUT);
digitalWrite(buzzer, HIGH);
delay(200);
digitalWrite(buzzer, LOW);
Bluetooth.print("Enter 1 to open the gate!");//Записываем пользователю инструкции по bluetooth-терминалу
lcd.createChar(2, customChar2);
lcd.createChar(1, customChar);
}
void loop()
{
if (!mfrc522.PICC_IsNewCardPresent())
{
return;
}
//Выбираем одну из карт
if (!mfrc522.PICC_ReadCardSerial())
{
return;
}
// Показать UID на последовательном мониторе
Serial.print("UID tag :");
String content= "";
byte letter;
for (byte i = 0; i < mfrc522.uid.size; i++)
{
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
Serial.println();
Serial.print("Message : ");
content.toUpperCase();
if (content.substring(1) == "17 27 C7 A6" || "BA FA 21 28") // измените здесь UID карты/карт, которым вы хотите дать доступ
{
Serial.println("Authorized access");
Serial.println();
delay(3000);
}
else {
Serial.println(" Access denied");
delay(3000);
}
char Data=Bluetooth.read();//Получает данные из bluetooth и помещает их в переменную 'Data'
if(Data=='1'){//если данные от bluetooth равны 1(1, полученная от bluetooth, НЕ ЯВЛЯЕТСЯ целым числом, это символ.)
gateOpenSequence();//Самостоятельно созданная функция, которая выполняет все действия, когда нужно открыть ворота.
}
while(digitalRead(DA)==1){ //При получении символов с клавиатуры.
int key =digitalRead(D3)*8 + digitalRead(D2)*4 +digitalRead(D1)*2 + digitalRead(D0);//Определенная формула, используемая для расшифровки того, какая клавиша была нажата
returnKey(key);//Самостоятельно созданная функция, которая переводит расшифрованную клавишу в раскладку клавиатуры. помещает нажатую клавишу в переменную 'c'
Serial.print(c);
if(c!='D') keys[cnt3]=c;
switch(cnt2){
case 0:
if(c!='D'){
lcd.clear();
lcd.setCursor(9, 0);
lcd.print(keys[cnt3]);
++cnt3;
++cnt2;
Beep();
break;
}
else break;
case 1:
if(c!='D'){
lcd.setCursor(8,0);
lcd.print("*");
lcd.print(keys[cnt3]);
++cnt3;
++cnt2;
Beep();
break;
}
else{
lcd.clear();
--cnt3;
--cnt2;
break;
}
case 2:
if(c!='D'){
lcd.setCursor(8, 0);
lcd.print("**");
lcd.print(keys[cnt3]);
++cnt2;
++cnt3;
Beep();
break;
}
else{
lcd.clear();
lcd.setCursor(9,0);
cnt3--;
cnt2--;
lcd.print(keys[cnt3-1]);
break;
}
case 3:
if(c!='D'){
lcd.setCursor(8, 0);
lcd.print("***");
lcd.print(keys[cnt3]);
++cnt2;
++cnt3;
Beep();
break;
}
else{
lcd.clear();
lcd.setCursor(9,0);
lcd.print("*");
cnt3--;
cnt2--;
lcd.print(keys[cnt3-1]);
break;
}
case 4:
if(c!='D'){
cnt2=0;
cnt3=0;
}
else{
lcd.clear();
lcd.setCursor(9, 0);
lcd.print("**");
cnt2--;
cnt3--;
lcd.print(keys[cnt3-1]);
}
break;
}
while(digitalRead(DA)==1);//убедимся, что мы не получим двойной ввод от одного нажатия, заставляя цикл оставаться там, пока нажата клавиша
if(c!='D'){
keysPressed[count] = c;//Помещаем нажатую клавишу в массив
count++;//поднятие индекса массива
}
else{
keysPressed[count]="";
count--;
}
if (count == 5)//когда count достигает 5, что означает, что массив заполнен, проверьте, равен ли «пароль» массива 5 ключам, которые только что ввел пользователь.
{
for (int i = 0; i < 5; i++)
{
if (password[i] == keysPressed[i])//если ключи одинаковые добавляем к cnt единицу, если cnt равно 5 значит все ключи были одинаковые
{
cnt++;
}
}
if(cnt==5){
gateOpenSequence();
cnt=0;
}
else{
wrongPassword();
cnt=0;
}
}
}
}
void returnKey(int key)
{
char arrkey[16]={ '1','2','3','A','4','5','6','B','7','8','9','C','*','0','#','D' };
c=arrkey[key];
}
void lcdSetup(){
lcd.setCursor(0,0);
lcd.write(2);
lcd.setCursor(1, 0);
lcd.write(1);
lcd.setCursor(18,0);
lcd.write(1);
lcd.setCursor(19,0);
lcd.write(2);
lcd.setCursor(2,0);
lcd.print("----Welcome-----");
lcd.setCursor(0,1);
lcd.print("| Enter password |");
lcd.setCursor(0,2);
lcd.print("|and then press '#'|");
lcd.setCursor(0, 3);
lcd.print("|------------------|");
}
void gateOpenSequence(){
int start = 0;
int desired = 105;
lcd.clear();
lcd.setCursor(6,0);
lcd.print("Welcome");
lcd.setCursor(8,1);
lcd.print("Home");
count = 0;
digitalWrite(buzzer,HIGH);
while(start<desired){
servo.write(++start);
delay(10);
}
delay(1000);
digitalWrite(buzzer,LOW);
lcdSetup();
while(start>5){
servo.write(--start);
delay(10);
}
}
void wrongPassword(){
lcd.clear();
lcd.setCursor(7,0);
lcd.print("Wrong");
lcd.setCursor(6,1);
lcd.print("Password");
lcd.setCursor(4, 2);
lcd.print("Achalta ota");
count = 0;
for(int jj=0;jj<3;jj++){
Beep();
}
delay(2000);
lcdSetup();
}
void Beep(){
digitalWrite(buzzer,HIGH);
delay(200);
digitalWrite(buzzer,LOW);
delay(200);
}
Я буду очень признателен за помощь, так как не могу найти никаких объяснений по поводу этих двух функций:
if (!mfrc522.PICC_IsNewCardPresent())
{
return;
}
//Выбираем одну из карт
if (!mfrc522.PICC_ReadCardSerial())
{
return;
}
Заранее спасибо, Барзи.
@Barzy, 👍2
1 ответ
mfrc522.PICC_IsNewCardPresent()
проверит, поднесена ли к считывателю новая RFID-карта/метка. Поэтому, если это возвращает true
, вы можете прочитать карту.
mfrc522.PICC_ReadCardSerial()
фактически считывает данные с карты/тега, чтобы UUID был доступен через mfrc522.uid
.
Ваша проблема связана с тем, как вы используете эти функции. Давайте посмотрим на этот точный фрагмент кода:
if (!mfrc522.PICC_IsNewCardPresent())
{
return;
}
//Выбираем одну из карт
if (!mfrc522.PICC_ReadCardSerial())
{
return;
}
Когда мы переводим первый оператор if на английский язык, мы получаем:
If no new card is present restart the function `loop()`.
Этот фрагмент кода находится в начале функции. Это означает, что вы будете читать код ниже этого только в том случае, если новая карта присутствует и может быть прочитана. Эта логика работает хорошо только в том случае, если в этой функции выполняется только RFID-код, что не относится к вашему случаю.
Вместо этого вы можете немного изменить структуру своего RFID-кода:
if(mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()){
// Обработка всего RFID-кода здесь
// Показать UID на последовательном мониторе
Serial.print("UID tag :");
String content= "";
byte letter;
for (byte i = 0; i < mfrc522.uid.size; i++)
{
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
Serial.println();
Serial.print("Message : ");
content.toUpperCase();
if (content.substring(1) == "17 27 C7 A6" || "BA FA 21 28") // измените здесь UID карты/карт, которым вы хотите дать доступ
{
Serial.println("Authorized access");
Serial.println();
delay(3000);
} else {
Serial.println(" Access denied");
delay(3000);
}
}
Это выполнит код RFID, если новая карта может быть прочитана. В противном случае он просто продолжит работу с остальной частью кода.
Обратите внимание, что из-за вызова delay(3000)
ваш код не будет реагировать ни на что в течение 3 секунд после того, как карта была поднесена к считывателю. Возможно, вы захотите отказаться от этой задержки в пользу лучшего отклика.
- Использование RFID-RC522 с другими контактами
- Использовать Ethernet Shield и RFID rc522 вместе на мега
- Непрерывное считывание RFID-метки RDM6300
- Как сделать динамическое меню с подменю ( Arduino mega или Arduino Uno)
- Может ли 1 выход wiegand быть для 2 контроллеров?
- Как добавить условие в пример RFID?
- Плата MFRC522 не обнаружена. Красное светодиодное освещение
- RFID RC522 считывает предыдущий серийный номер метки с другой меткой