Как подключить устройство 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));
}
@Mirakul, 👍0
Обсуждение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
- Проблема совместного использования MISO с несколькими RFID-считывателями RC522
- Arduino UNO + Ethernet Shield + ЖК-дисплей + RFID, но RFID не работает
- SPI между ведущим arduino и ведомым arduino
- Как использовать SPI на Arduino?
- OVF в последовательном мониторе вместо данных
- Использование прерываний с RC522
- Как отправить строку с подчиненного устройства Arduino с помощью SPI?
- rfid_default_keys проверить с помощью RC522
Извините за глупость, где ваш битовый код Ethernet? Также вы знаете, что SPI использует выбор чипа для выбора устройства, с которым он хочет общаться?, @Martynas
установите контакт 10 HIGH, если вы не используете чип Ethernet, @Juraj
Вы имеете в виду, потому что щиты SS 10? И вы имеете в виду, что я делаю
pinMode(10, HIGH);
?, @Mirakulда, установите 10 как OUTPUT и HIGH. пока он плавает, он случайным образом включает и отключает чип Wiznet на шине SPI., @Juraj