Как подключить устройство SPI к плате Etherntet на Arduino Uno

В моем проекте мне нужно подключить считыватель RFID (RC522) поверх Ethernet-шилда, так как он может считывать и редактировать SD-карты. Когда я подключаю только датчик RFID к Arduino, он работает. То же самое касается экрана Ethernet. Но когда я использую оба вместе, это просто не работает. Я могу скомпилировать его и загрузить, но я ничего не получаю в последовательном мониторе. Я думаю, это потому, что и экран Ethernet, и считыватель RFID используют одни и те же контакты для SPI, такие как MOSI, MISO и SCK. Мой вопрос: если это проблема, как подключить несколько устройств SPI к Arduino или, по крайней мере, к экрану Ethernet.

Вот мой код, хотя я думаю, что в нем нет ничего плохого. Я только что объединил код для RFID и Ethernet-щита с помощью копирования и вставки. Извините за плохое форматирование, мне это нужно только для теста, позже я сделаю реальный код.

#include <SPI.h>
#include <MFRC522.h>
#include <SD.h>

#define RST_PIN         6          // Настраиваемый, см. типичное расположение выводов выше
#define SS_PIN          7

MFRC522 mfrc522(SS_PIN, RST_PIN);

// устанавливаем переменные с помощью функций библиотеки утилит SD:
Sd2Card card;
SdVolume volume;
SdFile root;

// измените это, чтобы оно соответствовало вашему экрану SD или модулю;
// Экран Arduino Ethernet: контакт 4
// Экраны и модули Adafruit SD: контакт 10
// Экран Sparkfun SD: контакт 8
// MKRZero SD: SDCARD_SS_PIN
const int chipSelect = 4;

void setup() {
  // Открытие последовательной связи и ожидание открытия порта:
  Serial.begin(9600);
  while (!Serial) {
    ; // ждем подключения последовательного порта. Требуется только для родного порта USB
  while (!Serial);    // Ничего не делать, если последовательный порт не открыт (добавлено для Arduino на базе ATMEGA32U4)
  SPI.begin();      // Инициируем шину SPI
  mfrc522.PCD_Init();   // Инициализация MFRC522
  mfrc522.PCD_DumpVersionToSerial();  // Показать сведения о PCD — сведения о считывателе карт MFRC522
  Serial.println(("Scan PICC to see UID, SAK, type, and data blocks..."));



  Serial.print("\nInitializing SD card...");

  // будем использовать код инициализации из служебных библиотек
  // так как мы просто проверяем, работает ли карта!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    while (1);
  } else {
    Serial.println("Wiring is correct and a card is present.");
  }

  // печатаем тип карты
  Serial.println();
  Serial.print("Card type:         ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Теперь попробуем открыть "том"/"раздел" - это должна быть FAT16 или FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    while (1);
  }

  Serial.print("Clusters:          ");
  Serial.println(volume.clusterCount());
  Serial.print("Blocks x Cluster:  ");
  Serial.println(volume.blocksPerCluster());

  Serial.print("Total Blocks:      ");
  Serial.println(volume.blocksPerCluster() * volume.clusterCount());
  Serial.println();

  // вывести тип и размер первого тома FAT-типа
  uint32_t volumesize;
  Serial.print("Volume type is:    FAT");
  Serial.println(volume.fatType(), DEC);

  volumesize = volume.blocksPerCluster();    // кластеры — это наборы блоков
  volumesize *= volume.clusterCount();       // у нас будет много кластеров
  volumesize /= 2;                           // Блоки SD-карты всегда имеют размер 512 байт (2 блока по 1 КБ)
  Serial.print("Volume size (Kb):  ");
  Serial.println(volumesize);
  Serial.print("Volume size (Mb):  ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Gb):  ");
  Serial.println((float)volumesize / 1024.0);

  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);

  // список всех файлов на карте с датой и размером
  root.ls(LS_R | LS_DATE | LS_SIZE);
  }
}

void loop() {
    if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // Выбираем одну из карт
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  // Дамп отладочной информации о карте; PICC_HaltA() вызывается автоматически
  mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}

, 👍0

Обсуждение

Извините за глупость, где ваш битовый код Ethernet? Также вы знаете, что SPI использует выбор чипа для выбора устройства, с которым он хочет общаться?, @Martynas

установите контакт 10 HIGH, если вы не используете чип Ethernet, @Juraj

Вы имеете в виду, потому что щиты SS 10? И вы имеете в виду, что я делаю pinMode(10, HIGH); ?, @Mirakul

да, установите 10 как OUTPUT и HIGH. пока он плавает, он случайным образом включает и отключает чип Wiznet на шине SPI., @Juraj


1 ответ


1

Два устройства должны иметь общие SCK, MISO и MOSI, но SS (или CS, как его иногда называют) должны быть разными, и оба экрана, вероятно, пытаются использовать контакт 10 для SS. Пусть экран Ethernet имеет контакт 10 для SS. На другом экране возьмите этот штифт и согните его, чтобы он не попал в разъем, когда вы их складываете, а затем припаяйте к нему провод и подключите его к другому контакту. Войдите в код и измените код для этого экрана, чтобы использовать новый контакт как SS вместо контакта 10.

,

у них есть контакт 7 как SS для считывателя RFID. и это не щит я думаю, @Juraj

Означает ли CS выбор чипа? Кстати вы правы юрай., @Mirakul

Да, CS - выбор чипа., @Delta_G

Хорошо, если линии CS уже разделены, то следующее, что нужно проверить, это режимы SPI. Возможно, два устройства используют разные режимы SPI., @Delta_G