Arduino UNO + Ethernet Shield + ЖК-дисплей + RFID, но RFID не работает
Я работаю над проектом, который использует Arduino для RFID, но при подключении к Ethernet-шилду RFID, похоже, не считывает ни одну карту, подключенную к датчику, но ЖК-дисплей, похоже, работает нормально. Вот код, который я использую с этой страницы: http:// www.instructables.com/id/RFID-CARD-READER-WITH-ARDUINORFID-RC522-and-LCD-16/
#include <EEPROM.h> //Библиотека для чтения и записи UID PICC из/в EEPROM
#include <SPI.h> //Модуль библиотеки RC522 использует протокол SPI
#include <MFRC522.h> //Библиотечный модуль RC522
#include <LiquidCrystal.h> //Библиотека для ЖК-дисплея
#include <Ethernet.h>
EthernetServer server(80);
boolean match = false; // инициализируем соответствие карты значением false
boolean programMode = false; // инициализируем режим программирования значением false
int successRead; // Целочисленная переменная, которую нужно сохранить, если у нас есть успешное чтение из Reader
byte storedCard[4]; // Сохраняет идентификатор, прочитанный из EEPROM
byte readCard[4]; // Сохраняет отсканированный идентификатор, считанный из RFID-модуля
byte masterCard[4]; // Сохраняет идентификатор мастер-карты, прочитанный из EEPROM
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Создание экземпляра MFRC522.
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); //Инициализация PIN-кодов ЖК-дисплея как (RS, EN, D4, D5, D6, D7)
void setup() {
Serial.begin(9600); // Инициализируем последовательную связь с ПК
lcd.begin(16, 2); //Инициализация ЖК-дисплея 16x2
pinMode(8, OUTPUT); //Вывод светодиода и зуммера
SPI.begin(); // Оборудование MFRC522 использует протокол SPI
mfrc522.PCD_Init(); // Инициализируем оборудование MFRC522
mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);
if (EEPROM.read(1) != 1) {
// Просматриваем EEPROM, если определена Master Card, адрес EEPROM 1 сохраняется, если определен
Serial.println("No Admin Card Defined");
//Когда в вашем EEROM нет мастер-карты (последовательный дисплей)
Serial.println("Scan A card to Define as Admin Card");
lcd.clear();
lcd.setCursor(0, 0);
lcd.println("SET ADMIN CARD ");
//Когда в вашем EEROM нет мастер-карты (ЖК-дисплей)
lcd.setCursor(0, 1);
lcd.println("SCAN A CARD.....");
//Сканируйте любую RFID-карту, чтобы установить вашу мастер-карту в вашем EEROM (ЖК-дисплей)
delay(1500);
do {
successRead = getID();
// устанавливает SuccessRead в 1, когда мы читаем из устройства чтения, в противном случае 0
}
while (!successRead);
//программа не пойдет дальше, пока вы не добьетесь успешного чтения
for (int j = 0; j < 4; j++) {
// Цикл 4 раза
EEPROM.write(2 + j, readCard[j]);
// Запись UID отсканированного PICC в EEPROM, начиная с адреса 3
}
EEPROM.write(1, 1); //Запись в EEPROM, которую мы определили Master Card.
Serial.println("Admin Card Defined");
}
Serial.println("Administrator Card's UID");
for (int i = 0; i < 4; i++) { // Считываем UID мастер-карты из EEPROM
masterCard[i] = EEPROM.read(2 + i); // Записываем это в masterCard
Serial.print(masterCard[i], HEX); //Master Card просмотр только в последовательном режиме
Serial.println("Waiting PICCs to bo scanned :)");
}
//ОЖИДАНИЕ СКАНИРОВАНИЯ RFID-КАРТ:
Serial.println("");
Serial.println("Waiting cards to bo scanned :)");
lcd.clear();
lcd.setCursor(4, 0);
lcd.println("WAITING ");
lcd.setCursor(3, 1);
lcd.println("FOR CARD... ");
delay(1500);
}
int getID() {
// Готовимся к чтению PICC
if (! mfrc522.PICC_IsNewCardPresent()) {
//Если новый PICC помещен в RFID-считыватель, продолжаем
return 0;
}
if (! mfrc522.PICC_ReadCardSerial()) {
//Поскольку установлен PICC, получаем Serial и продолжаем
return 0;
}
// Существуют Mifare PICC, которые имеют 4-байтовый или 7-байтовый UID, если вы используете 7-байтовый PICC
// Я думаю, нам следует принять во внимание все PICC, поскольку они имеют 4-байтовый UID
// Пока мы не поддержим 7-байтовые PICC
Serial.println("Scanning card's UID....");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SCANNING");
lcd.setCursor(0, 1);
lcd.print("Card's UID.....");
delay(2000);
for (int i = 0; i < 4; i++) {
readCard[i] = mfrc522.uid.uidByte[i];
Serial.print(readCard[i], HEX);
}
Serial.println("");
mfrc522.PICC_HaltA(); // Остановить чтение
return 1;
}
boolean isMaster(byte test[]) {
if (checkTwo(test, masterCard))
return true;
else
return false;
}
boolean checkTwo (byte a[], byte b[]) {
if (a[0] != NULL)
// Сначала убедитесь, что в массиве что-то есть
match = true;
// Предположим, что они сначала совпадают
for (int k = 0; k < 4; k++) {
// Цикл 4 раза
if (a[k] != b[k])
// ЕСЛИ a != b, то устанавливаем match = false, один не сработает, все не сработают
match = false;
}
if (match) {
// Проверяем, истинно ли совпадение
return true;
} else {
return false;
}
}
boolean findID(byte find[]) {
int count = EEPROM.read(0);
// Читаем первый байт EEPROM, который
for (int i = 1; i <= count; i++) {
// Цикл один раз для каждой записи EEPROM
readID(i);
// Считаем идентификатор из EEPROM, он хранится в StoreCard[4]
if (checkTwo(find, storedCard)) {
// Проверяем, прочитана ли сохраненная карта из EEPROM
return true;
break; // Хватит искать, мы нашли это
} else {
// Если нет, возвращаем false
}
}
return false;
}
void readID(int number) {
int start = (number * 4) + 2;
// Выясняем стартовую позицию
for (int i = 0; i < 4; i++) {
// Цикл 4 раза, чтобы получить 4 байта
storedCard[i] = EEPROM.read(start + i);
// Присвоить значения, прочитанные из EEPROM, в массив
}
}
void deleteID(byte a[]) {
if (!findID(a)) {
// Прежде чем удалять из EEPROM, проверим, есть ли у нас эта карта!
failedWrite(); // Если не
} else {
int num = EEPROM.read(0);
// Получаем количество использованных мест, в позиции 0 хранится количество удостоверений личности
int slot;
// Выясняем номер слота карты
int start;
// = (число * 4) + 6; // Выясняем, где начинается следующий слот
int looping;
// Сколько раз повторяется цикл
int j;
int count = EEPROM.read(0);
// Читаем первый байт EEPROM, в котором хранится количество карт
slot = findIDSLOT(a);
//Выясняем номер слота карты, которую нужно удалить
start = (slot * 4) + 2;
looping = ((num - slot) * 4);
num--; // Уменьшаем счетчик на единицу
EEPROM.write(0, num); // Записываем новый счетчик в счетчик
for (j = 0; j < looping; j++) {
// Зацикливаем время смены карт
EEPROM.write(start + j, EEPROM.read(start + 4 + j));
// Смещаем значения массива на 4 места раньше в EEPROM
}
for (int k = 0; k < 4; k++) {
//Сдвиг цикла
EEPROM.write(start + j + k, 0);
}
successDelete();
}
}
//Если не удалось добавить карту:
void failedWrite() {
Serial.println("something wrong with Card");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SOMETHING WRONG");
lcd.setCursor(0, 1);
lcd.print("WITH CARD");
delay(2000);
}
//Для успешного удаления:
void successDelete() {
Serial.println("Succesfully removed");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SUCCESFULLY");
lcd.setCursor(0, 1);
lcd.print("REMOVED CARD");
delay(2000);
}
int findIDSLOT(byte find[]) {
int count = EEPROM.read(0);
// Читаем первый байт EEPROM, который
for (int i = 1; i <= count; i++) {
// Цикл один раз для каждой записи EEPROM
readID(i);
// Считаем идентификатор из EEPROM, он хранится в StoreCard[4]
if (checkTwo(find, storedCard)) {
// Проверяем, прочитана ли сохраненная карта из EEPROM
// то же самое, что переданная идентификационная карта find[]
return i;
// Номер слота карты
break;
// Хватит искать, мы нашли это
}
}
}
//Для успешного добавления:
void successWrite() {
Serial.println("Succesfully added");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SUCCESFULLY");
lcd.setCursor(0, 1);
lcd.print("ADDED");
delay(2000);
}
//Для добавления карты в EEPROM:
void writeID(byte a[]) {
if (!findID(a)) {
// Прежде чем писать в EEPROM, проверим, видели ли мы эту карту раньше!
int num = EEPROM.read(0);
// Получаем количество использованных мест, в позиции 0 хранится количество удостоверений личности
int start = (num * 4) + 6;
// Выясняем, где начинается следующий слот
num++;
// Увеличиваем счетчик на единицу
EEPROM.write(0, num);
// Записываем новый счетчик в счетчик
for (int j = 0; j < 4; j++) {
// Цикл 4 раза
EEPROM.write(start + j, a[j]);
// Записываем значения массива в EEPROM в правильную позицию
}
successWrite();
} else {
failedWrite();
}
}
void loop() {
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("TAP YOUR");
lcd.setCursor(4, 1);
lcd.print("CARD HERE");
do {
successRead = getID(); // устанавливает SuccessRead в 1, когда мы читаем из устройства чтения, в противном случае 0
if (programMode) {
// Программный режим циклически проходит через RGB в ожидании чтения новой карты
} else {
}
}
while (!successRead);
//программа не пойдет дальше, пока вы не добьетесь успешного чтения
if (programMode) {
if (isMaster(readCard)) {
//Если мастер-карта просканирована еще раз, выходим из режима программирования
Serial.println("This is ADMIN Card");
Serial.println("Exiting ADMIN Mode");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("EXITING FROM");
lcd.setCursor(0, 1);
lcd.print("ADMINISTRATOR MODE");
delay(2000);
programMode = false;
return;
} else {
if (findID(readCard)) {
//Если сканированная карта известна, удаляем ее
Serial.println("I know this CARD, so removing");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("AVAILABLE!");
lcd.setCursor(0, 1);
lcd.print("SO DELETING.....");
delay(5000);
deleteID(readCard);
Serial.println("-----------------------------");
} else {
// Если сканированная карта неизвестна, добавьте ее
Serial.println("Adding this card...");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Card no:");
lcd.setCursor(0, 1);
lcd.print(readCard[0], HEX);
lcd.print(readCard[1], HEX);
lcd.print(readCard[2], HEX);
lcd.print(readCard[3], HEX);
lcd.print(readCard[4], HEX);
delay(4000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("NOT AVAILABLE");
lcd.setCursor(0, 1);
lcd.print("SO ADDING...");
delay(5000);
writeID(readCard);
Serial.println("-----------------------------");
}
}
} else {
if (isMaster(readCard)) {
// Если идентификатор сканируемой карты совпадает с идентификатором Master Card, войдите в программный режим
programMode = true;
Serial.println("Welcome to Administrator Mode");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WELCOME TO");
lcd.setCursor(0, 1);
lcd.print("ADMIN MODE");
delay(3000);
int count = EEPROM.read(0);
// Читаем первый байт EEPROM, который
Serial.print("I have ");
// сохраняет количество идентификаторов в EEPROM
Serial.print(count);
Serial.print(" record(s) on EEPROM");
Serial.println("");
Serial.println("Scan a card to ADD or REMOVE");
Serial.println("-----------------------------");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SCAN CARD TO");
lcd.setCursor(0, 1);
lcd.print("ADD OR REMOVE...");
delay(2500);
} else {
if (findID(readCard)) {
// Если нет, проверим, находится ли карта в EEPROM
Serial.println("Acces Granted");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ACCESS GRANTED");
lcd.setCursor(0, 1);
lcd.print("YOU MAY ENTER NOW");
digitalWrite(8, HIGH);
delay(1500);
digitalWrite(8, LOW);
lcd.clear();
} else {
// Если нет, покажем, что идентификатор недействителен
Serial.println("Access Denied");
for (int abcd = 0; abcd < 3; abcd++) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" SORRY");
lcd.setCursor(0, 1);
lcd.print(" ACCESS DENIED");
digitalWrite(8, HIGH);
delay(1000);
digitalWrite(8, LOW);
lcd.clear();
lcd.print(" YOU'RE NOT ");
lcd.setCursor(0, 1);
lcd.print(" AUTHORIZED ");
delay(1000);
}
lcd.clear();
}
}
}
}
Любая помощь будет оценена по достоинству!
@Ryan Baronia, 👍0
Обсуждение2 ответа
Невозможно использовать все дополнительные функции Arduino вместе с другими дополнительными функциями Arduino. Некоторые функции используют одни и те же ресурсы Arduino. Если на самом деле существует проблема с аппаратным обеспечением, вам необходимо углубиться в программные драйверы и оборудование, чтобы выяснить, существует ли возможное решение. Но вряд ли новые разработчики возьмут на себя такую задачу. Новому разработчику может быть проще использовать два разных Arduino для размещения желаемых функций и настроить канал связи между ними.
Если вы «следуете инструкциям», опубликуйте URL-адрес проекта, который использует все упомянутое вами оборудование., @st2000
Недавно я реализовал аналогичный проект с RFID-считывателем и защитой SD-карты, и у меня возникла та же проблема.
Объяснение, почему это не работает, заключается в том, что некоторые экраны, использующие связь SPI, на самом деле не заботятся о том, чтобы ваш вывод выбора подчиненного устройства был понижен на низком уровне, и мешают, когда Arduino общается с другим устройством SPI через вывод MISO.
р>Единственный способ заставить это работать — использовать буфер с тремя состояниями на выводах MISO моих устройств SPI. Вы можете найти много информации об этом в Интернете, а также о том, как использовать их в своем проекте.
Идея проста, он работает как транзистор. Когда вы подключаете контакт включения буфера к земле с помощью контакта SS, вы позволяете контакту MISO этого устройства подключиться к соответствующему входу Arduino. В противном случае вывод MISO будет находиться в состоянии высокого импеданса и больше не будет мешать обмену данными .
Удачи в вашем проекте.
- Как использовать SPI на Arduino?
- Проблема совместного использования MISO с несколькими RFID-считывателями RC522
- GSM-модуль IOT-GA6 Arduino + ошибка CME 58
- Разница между массивом char и массивом unsigned char
- Firmata: как установить определенный PIN на высокий уровень при загрузке?
- Arduino wrap или подкласс print() для работы с несколькими Serial
- Как подключить устройство SPI к плате Etherntet на Arduino Uno
- Сбой связи SPI
Ну, экран Ethernet также использует SPI и контакты 10-13. Кажется, это будет проблемой..., @KC Tucker
Спасибо, добрый сэр, я новичок в кодировании Arduino и просто следую инструкциям, поэтому не знаю, что добавить в код, чтобы добавить устройство SPI (экран Ethernet)., @Ryan Baronia
@KCTucker говорит о том, что вы не можете использовать каждую дополнительную функцию с любой другой дополнительной функцией., @st2000