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();
      }
    }
  }
}

Любая помощь будет оценена по достоинству!

, 👍0

Обсуждение

Ну, экран Ethernet также использует SPI и контакты 10-13. Кажется, это будет проблемой..., @KC Tucker

Спасибо, добрый сэр, я новичок в кодировании Arduino и просто следую инструкциям, поэтому не знаю, что добавить в код, чтобы добавить устройство SPI (экран Ethernet)., @Ryan Baronia

@KCTucker говорит о том, что вы не можете использовать каждую дополнительную функцию с любой другой дополнительной функцией., @st2000


2 ответа


1

Невозможно использовать все дополнительные функции Arduino вместе с другими дополнительными функциями Arduino. Некоторые функции используют одни и те же ресурсы Arduino. Если на самом деле существует проблема с аппаратным обеспечением, вам необходимо углубиться в программные драйверы и оборудование, чтобы выяснить, существует ли возможное решение. Но вряд ли новые разработчики возьмут на себя такую задачу. Новому разработчику может быть проще использовать два разных Arduino для размещения желаемых функций и настроить канал связи между ними.

,

Если вы «следуете инструкциям», опубликуйте URL-адрес проекта, который использует все упомянутое вами оборудование., @st2000


2

Недавно я реализовал аналогичный проект с RFID-считывателем и защитой SD-карты, и у меня возникла та же проблема.

Объяснение, почему это не работает, заключается в том, что некоторые экраны, использующие связь SPI, на самом деле не заботятся о том, чтобы ваш вывод выбора подчиненного устройства был понижен на низком уровне, и мешают, когда Arduino общается с другим устройством SPI через вывод MISO.

р>

Единственный способ заставить это работать — использовать буфер с тремя состояниями на выводах MISO моих устройств SPI. Вы можете найти много информации об этом в Интернете, а также о том, как использовать их в своем проекте.

Идея проста, он работает как транзистор. Когда вы подключаете контакт включения буфера к земле с помощью контакта SS, вы позволяете контакту MISO этого устройства подключиться к соответствующему входу Arduino. В противном случае вывод MISO будет находиться в состоянии высокого импеданса и больше не будет мешать обмену данными .

Удачи в вашем проекте.

,