Почему несколько RFID меток не работают вместе, даже из стандартного примера?

pavelcdn
Offline
Зарегистрирован: 24.08.2019

нашел в интернете вот такой скетч, работает по принципу "приложил 6 ключей, сработало реле" 

но штука в том что RFIID метки то работают через раз, то вообще не работают, то читаются только брелки , а карты совсем не читаются то некоторые брелки не читаются

если подключить одну RFID то она работает идеально! Куда копать? Я первый раз с ардуино связался

 

p.s. где найти описание классов для библиотеки MFRC522? На гитхабе где качать эту либу есть только голый код, там я уверен даже сам разраб ногу сломает пока найдет что ему надо, как же понять что значит 

mfrc522[reader].PICC_IsNewCardPresent()  например и прочий код

/**

   --------------------------------------------------------------------------------------------------------------------
   Example sketch/program showing how to read data from more than one PICC to serial.
   --------------------------------------------------------------------------------------------------------------------
   This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
   Example sketch/program showing how to read data from more than one PICC (that is: a RFID Tag or Card) using a
   MFRC522 based RFID Reader on the Arduino SPI interface.
   Warning: This may not work! Multiple devices at one SPI are difficult and cause many trouble!! Engineering skill
            and knowledge are required!
   @license Released into the public domain.
   Typical pin layout used:
   -----------------------------------------------------------------------------------------
               MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
               Reader/PCD   Uno/101       Mega      Nano v3    Leonardo/Micro   Pro Micro
   Signal      Pin          Pin           Pin       Pin        Pin              Pin
   -----------------------------------------------------------------------------------------
   RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
   SPI SS 1    SDA(SS)      ** custom, take a unused pin, only HIGH/LOW required *
   SPI SS 2    SDA(SS)      ** custom, take a unused pin, only HIGH/LOW required *
   SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
   SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
   SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
*/

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

// PIN Numbers : RESET + SDAs
#define RST_PIN         9
#define SS_1_PIN        2
#define SS_2_PIN        4
#define SS_3_PIN        10
#define SS_4_PIN        8
#define SS_5_PIN        7
#define SS_6_PIN        6

// Led and Relay PINS
#define GreenLed        2
#define relayIN         3
#define RedLed          5


// List of Tags UIDs that are allowed to open the puzzle
byte tagarray[][6] = {
        {0xC3, 0x97, 0x01, 0x31},
        {0xC1, 0x3C, 0x6A, 0x31},
        {0xC1, 0x3E, 0x68, 0x31},
        {0xA6, 0x38, 0x35, 0x13},
        {0x93, 0x4C, 0x16, 0x1D},
        {0x91, 0x93, 0x7C, 0x2F},
};

// Inlocking status :
int tagcount = 0;
bool access = false;

#define NR_OF_READERS   6

byte ssPins[] = {SS_1_PIN, SS_2_PIN, SS_3_PIN, SS_4_PIN, SS_5_PIN, SS_6_PIN};

// Create an MFRC522 instance :
MFRC522 mfrc522[NR_OF_READERS];

/**
   Initialize.
*/
void setup() {

    Serial.begin(9600);           // Initialize serial communications with the PC
    while (!Serial);              // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)

    SPI.begin();                  // Init SPI bus

    /* Initializing Inputs and Outputs */
    pinMode(GreenLed, OUTPUT);
    digitalWrite(GreenLed, LOW);
    pinMode(relayIN, OUTPUT);
    digitalWrite(relayIN, LOW);
    pinMode(RedLed, OUTPUT);
    digitalWrite(RedLed, LOW);


    /* looking for MFRC522 readers */
    for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
        mfrc522[reader].PCD_Init(ssPins[reader], RST_PIN);
        Serial.print(F("Ридер "));
        Serial.print(reader);
        Serial.print(F(": "));
        mfrc522[reader].PCD_DumpVersionToSerial();
        //mfrc522[reader].PCD_SetAntennaGain(mfrc522[reader].RxGain_max);
    }
}

/*
   Main loop.
*/

void loop() {
// test
if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }
  // Выбор метки
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    uidDecTemp = mfrc522.uid.uidByte[i];
    uidDec = uidDec * 256 + uidDecTemp;
  }
  Serial.println("Card UID: ");
  Serial.println(uidDec); // Выводим UID метки в консоль.
  
// test


        // Show some details of the PICC (that is: the tag/card)
        Serial.print(F(": Card UID:"));
        int asdasd = dump_byte_array(mfrc522[0].uid.uidByte, mfrc522[0].uid.size);
        Serial.print(asdasd);
        Serial.println();
wait(1000);

        for (int i = 0; i < mfrc522[0].uid.size; i++){
            if (mfrc522[0].uid.uidByte[i] != tagarray[0][i]){
                DenyingTag();
                break;
            } else {
                if (i == mfrc522[0].uid.size - 1){
                    AllowTag();
                } else {
                    continue;                                           // We still didn't reach the last cell/column : continue testing!
                }
            }
        }
        if (access)                                       // If the Tag is allowed, quit the test.



        if (access) {
            if (tagcount == NR_OF_READERS) {
                OpenDoor();
            } else {
                MoreTagsNeeded();
            }
        } else {
            UnknownTag();
        }
        /*Serial.print(F("PICC type: "));
          MFRC522::PICC_Type piccType = mfrc522[reader].PICC_GetType(mfrc522[reader].uid.sak);
          Serial.println(mfrc522[reader].PICC_GetTypeName(piccType));*/
        // Halt PICC
        mfrc522[0].PICC_HaltA();
        // Stop encryption on PCD
        mfrc522[0].PCD_StopCrypto1();
     //if (mfrc522[reader].PICC_IsNewC..


//    for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {

    // Looking for new cards
//        if (mfrc522[reader].PICC_IsNewCardPresent() && mfrc522[reader].PICC_ReadCardSerial()) {
//            Serial.print(F("Reader "));
//            Serial.print(reader);
//
//            // Show some details of the PICC (that is: the tag/card)
//            Serial.print(F(": Card UID:"));
//            dump_byte_array(mfrc522[reader].uid.uidByte, mfrc522[reader].uid.size);
//            Serial.println();
//
//            for (int x = 0; x < sizeof(tagarray); x++)                  // tagarray's row
//            {
//                for (int i = 0; i < mfrc522[reader].uid.size; i++)        //tagarray's columns
//                {
//                    if ( mfrc522[reader].uid.uidByte[i] != tagarray[x][i])  //Comparing the UID in the buffer to the UID in the tag array.
//                    {
//                        DenyingTag();
//                        break;
//                    }
//                    else
//                    {
//                        if (i == mfrc522[reader].uid.size - 1)                // Test if we browesed the whole UID.
//                        {
//                            AllowTag();
//                        }
//                        else
//                        {
//                            continue;                                           // We still didn't reach the last cell/column : continue testing!
//                        }
//                    }
//                }
//                if (access) break;                                        // If the Tag is allowed, quit the test.
//            }
//
//
//            if (access)
//            {
//                if (tagcount == NR_OF_READERS)
//                {
//                    OpenDoor();
//                }
//                else
//                {
//                    MoreTagsNeeded();
//                }
//            }
//            else
//            {
//                UnknownTag();
//            }
//            /*Serial.print(F("PICC type: "));
//              MFRC522::PICC_Type piccType = mfrc522[reader].PICC_GetType(mfrc522[reader].uid.sak);
//              Serial.println(mfrc522[reader].PICC_GetTypeName(piccType));*/
//            // Halt PICC
//            mfrc522[reader].PICC_HaltA();
//            // Stop encryption on PCD
//            mfrc522[reader].PCD_StopCrypto1();
//        } //if (mfrc522[reader].PICC_IsNewC..
    //} //for(uint8_t reader..

}

/**
   Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
    for (byte i = 0; i < bufferSize; i++) {
        Serial.print(buffer[i] < 0x10 ? " 0" : " ");
        Serial.print(buffer[i], HEX);
    }
}

void printTagcount() {
    Serial.print("Всего карт считано из 6:");
    Serial.println(tagcount);
}

void DenyingTag() {
    tagcount = tagcount;
    access = false;
}

void AllowTag() {
    tagcount = tagcount + 1;
    access = true;
}

void Initialize() {
    tagcount = 0;
    access = false;
}

void OpenDoor() {
    Serial.println("Следующий квест заработал!");
    Initialize();
    digitalWrite(relayIN, LOW);
    digitalWrite(GreenLed, HIGH);
    delay(2000);
    digitalWrite(relayIN, HIGH);
    delay(500);
    digitalWrite(GreenLed, LOW);
}

void MoreTagsNeeded() {
    printTagcount();
    Serial.println("ждем следующую карту");
    digitalWrite(RedLed, HIGH);
    delay(1000);
    digitalWrite(RedLed, LOW);
    access = false;
}

void UnknownTag() {
    Serial.println("карта не подходит");
    printTagcount();
    for (int flash = 0; flash < 5; flash++) {
        digitalWrite(RedLed, HIGH);
        delay(100);
        digitalWrite(RedLed, LOW);
        delay(100);
    }
}

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Таблица в коде не то?

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Я не понял, вы сразу пачку из 6 карточек прикладываете?????

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Стоки №№ 7 и 8 видели?

Гриша
Offline
Зарегистрирован: 27.04.2014

ЕвгенийП пишет:

Стоки №№ 7 и 8 видели?

 ну так у ТС уже уровень БОГА :)))) нужно сделать быстренько, зачем читать чужие каракули?!!!! :))))))))

b707
Offline
Зарегистрирован: 26.05.2017

pavelcdn если модули стандартные "синенькие" с Али:

то это известная проблема, они не отпускают шину SPI даже при управлении посредством SS Там надо MOSI MISO через ключи пускать, принудительно оставляя на шине только один модуль в каждый момент. Если вам нужно прочитать одновременно 6 карт на 6 модулях - боюсь, не получится.

Что за "документация" вам нужна на библиотеку? - есть исходник, есть комментарии...

b707
Offline
Зарегистрирован: 26.05.2017

pavelcdn пишет:

 как же понять что значит 

mfrc522[reader].PICC_IsNewCardPresent()  например и прочий код

 

у вас вообще как с английским? вроде название функции более чем говорящее

b707
Offline
Зарегистрирован: 26.05.2017

О, да я гляжу тут все куда более запущено. До проблемы раздела шины шестью модулями далеко.. В коде-то полный бред, оказывается.

Павел, у вас шесть экземпляров класса MFRC522 организованы в массив -  а вы к нему обращаетесь, как к единсвенному элементу. Неудивительно, что у вас ничего не работает. Этот код и компилироваться-то не должен.

Вы вообще язык С++ насколько знаете? - например, как обращаться к элементу массива?

 

UPDATE - сделал поиск по форуму - оказывается вы уже дважды задавали этот вопрос. Судя по Вашем сообщениям. это ваш первый проект ардуино. Боюсь, вы себе выбрали непосильную задачу для начала. Добиться одновременной работы стольких RFID на одной плате может оказаться непростой задачей и для опытного разработчика, а для вас - это как учиться водить машину на горном серпантине в гололед....

Прочитайте для начала какой-нить учебник для чайников. соберите пару простеньких проектов - а потом начинайте подбираться к своей задаче, штудируя документацию и примеры.

pavelcdn
Offline
Зарегистрирован: 24.08.2019

вы правы , для меня это сложная задача, С++ я не знаю , я знаю js и php 

я нашел видео https://www.youtube.com/watch?v=ahc8Yai_sWI , вот тут как то работает 

по сути мне и циклы то не нужны , я просто не знаю как записать 1 ридер чтоб читал только свою метку и так с каждым , не городить там кучу циклов , а простыми условиями записать

if (reader[1]==key[1]){true}

и так 6 раз 

b707
Offline
Зарегистрирован: 26.05.2017

pavelcdn пишет:

 я просто не знаю как записать 1 ридер чтоб читал только свою метку и так с каждым , не городить там кучу циклов , а простыми условиями записать

if (reader[1]==key[1]){true}

и так 6 раз 

ну как-то так:

for (byte i =0; i<6 ; i++) {
 if (reader[i] == key[i]) {
   // сделать что-то с клучом номер i
}
}

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

 

pavelcdn
Offline
Зарегистрирован: 24.08.2019

ну если бы все все знали , зачем бы нужно было сообщество и форумы , верно?)

Вообще задача у меня сделать чтобы к 1 приемнику подходил только один ключ , при одновременном приложении всех ключей к всем меткам например засветился светодиод

в этом примере насколько я могу читая код понять , ключ подходит к любому ридеру , при успешном считывании выполняется AllowTag() , который добавляет в tagcount единичку , если в этой переменной 6 (количество наших ридеров) то срабатывает реле в коде из примера

как же быть если надо читать 6 меток? 6 ардуино использовать?

b707
Offline
Зарегистрирован: 26.05.2017

pavelcdn пишет:

в этом примере насколько я могу читая код понять , ключ подходит к любому ридеру , при успешном считывании выполняется AllowTag() , который добавляет в tagcount единичку , если в этой переменной 6 (количество наших ридеров) то срабатывает реле в коде из примера

для начала Ваш пример просто нерабочий. Рабочим был код, который Вы (или кто-то другой) закомментировал начиная со строчки 160 и дальше. А тот код, что вписан вместо закомментированого - рассчитан на подключение к ардуине всего одного ридера и с шестью работать не будет.

Общий принцип того, как решить вашу задачу - я написал выше. Организуете шесть ридеров в массив, другой массив делаете для ключей. Ключи в массив кладете в том же порядке, как ридеры, то есть например ключ. который должен открывать ридер номер 3 - должен ледать в третьей ячейке массива ключей.

Далее проходите цикл по всем ридерам, проверя на них приложение их ключей. Если ключ совпадает - добавляете в tagout единичку....

Проблема в том, что писать это за вас никто не будет.

Гриша
Offline
Зарегистрирован: 27.04.2014

b707 пишет:

Далее проходите цикл по всем ридерам, проверя на них приложение их ключей. Если ключ совпадает - добавляете в tagout единичку....

Проблема в том, что писать это за вас никто не будет.

в продолжение сказанного :) 

ДА, можно использовать 6 ардуинок, в данном конкретном случае это, пожалуй, оптимальный по времени выход. далее собрать по "И" или поставить седьмой контроллер.

выше было правильно написано про алгоритм: обратился к нужному ридеру -> считал метку -> сравнил -> если все правильно, приростил  переменную, а если ложь обнулил -> в конце цикла проверил эту переменную и либо исполнил либо нет.

но кроме программной сложности у вас, есть еще и железные трудности, о которых вам написали выше про шину SPI. 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

pavelcdn пишет:

ну если бы все все знали , зачем бы нужно было сообщество и форумы , верно?)

Неверно.

Форум - место общения по интересам.

Вы пока форумчанам ничего интересного не предложили. Вместо этого пренебрегли правилами сетевой этики и нарушили правила форума.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Мне кажется автор или не договаривает, или врет откровенно. PHP - по синтаксису от Си почти ничем не отличается. Есть разница (огромная) в работе с массивами, наследованием, и строками. Ну и самое главное - в PHP нет типов данных. Там любая переменная может быть и строкой и float и массивом (причём индексами массива может быть что угодно что меня после PHP на Си и сбивает с толку, причём одновременно по ходу скрипта). А в остальном (для данной задачи) нет там разницы. Вообще. 

pavelcdn
Offline
Зарегистрирован: 24.08.2019

BOOM пишет:

Мне кажется автор или не договаривает, или врет откровенно. PHP - по синтаксису от Си почти ничем не отличается. Есть разница (огромная) в работе с массивами, наследованием, и строками. Ну и самое главное - в PHP нет типов данных. Там любая переменная может быть и строкой и float и массивом (причём одновременно по ходу скрипта). А в остальном (для данной задачи) нет там разницы. Вообще. 

у меня по коду только 1 вопрос , как указать № конкретной метки и № ридера. 

Больше нечего сложного там вроде по коду нет , а вот с подключением всей периферии огромные сложности , так как уже не одна тема тянется на N листов и некого нет даже примерного плана действия кроме использования кучи ардуино 

массивы такие же, а что такое типизирование любой кодер php знает , если их не задаешь не значит что их нет 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Вам b707 отвечал, причём даже привёл все факты (если контроллер тот же). А вы ничего в ответ не сказали. Кроме глупого высказывания о типизировании заранее нетепизорованных (в документации так и написано) переменных. 

ЗЫ: а ещё я был не отличником, сейчас говорят вообще надо ввести русское правописание - «как слышу так и пишу», но я человек старой закалки - Вы пишите убого. Не и ни надо писать в соотвествии с моментом. Оффтоп. 

К примеру палач говорит - отрубить ни одного пальца или отрубить не одного пальца, как? (Если не понятно - первое говорит вообще пальцы не отрубить, а второе - не оставить пальцев вообще) грубый пример, но показательный)))

pavelcdn
Offline
Зарегистрирован: 24.08.2019

BOOM пишет:

Вам b707 отвечал, причём даже привёл все факты (если контроллер тот же). А вы ничего в ответ не сказали. Кроме глупого высказывания о типизировании заранее нетепизорованных (в документации так и написано) переменных. 

ЗЫ: а ещё я был не отличником, сейчас говорят вообще надо ввести русское правописание - «как слышу так и пишу», но я человек старой закалки - Вы пишите убого. Не и ни надо писать в соотвествии с моментом. Оффтоп. 

вот и весь дух русских форумов , нет желания помочь , дайка нагажу в коментах чего нибудь эдакого... 

типичный троль. Да b707 сказал мысль , которую я изначально знал, но поскольку на этот код нет читабельного примера, я не могу понять как мне по простому взять ридер и ключ.

.А код этот из примера в интернете еще раз повторюсь. 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Это меня тролем называешь? Да я тут среди всех остальных - куколка от бабочки. А он сказал вообще говоря далеко не код, а правильную статистику - если у тебя той же марки считыватель  меток - так они не работают по spi одновременно. Ты вообще читаешь, что тебе пишут? Переключаешься на какое то видео (я не смотрел), а что говорят - сквозь пальцы. Надеюсь тебе нет и 30ти, иначе печаль за поколения. 

pavelcdn
Offline
Зарегистрирован: 24.08.2019

BOOM пишет:

Это меня тролем называешь? Да я тут среди всех остальных - куколка от бабочки. А он сказал вообще говоря далеко не код, а правильную статистику - если у тебя той же марки считыватель  меток - так они не работают по spi одновременно. Ты вообще читаешь, что тебе пишут? Переключаешься на какое то видео (я не смотрел), а что говорят - сквозь пальцы. Надеюсь тебе нет и 30ти, иначе печаль за поколения. 

ладно ладно, погорячился... сорян, просто привык я к вменяемой документации что сказать , на php что угодно можно найти...

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Документация везде одинаковая - описывает все что может. Ладно, читать надо всем. Желательно умные книги. :-)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

BOOM пишет:

Документация везде одинаковая - описывает все что может.

Отнюдь.

Зачастую бывает так:

1. Ищешь по всему И-нету и скачиваешь откуда только можно дэйташит на конкретное устройство - штук 20 экземпляров.

2. Сравниваешь скачанное между собой и устанавливаешь, что из 20 скачанных многие повторяются, а различаются между собой только 3-4.

3. Обнаруживаешь, что ни в одном из скачанных дэйташитов нужные тебе функции не описаны.

4. Ищешь по всему И-нету и скачиваешь откуда только можно примеры работы с нужным устройством.

5. Ищешь в этих примерах работу с теми регистрами устройства, которые не описаны ни в одном из дйташитов.

6. Заодно проверяешь, что в найденных примерах в регистры пишутся именно рекомендованные в дэйташитах величины. В случае расхождения - анализируешь и выясняешь истину путем экспериментов. Зачастую оказывается, что врет именно дэйташит.

7. Пытаешься экспериментально применить те регистры, которые не описаны ни в одном дэйташите, и выясняешь, к чему это приводит. Нередко истину удается установить только полным перебором (благо, в подавляющем числе случаев перебору нужно подвергнуть не более 1-4 битов).

b707
Offline
Зарегистрирован: 26.05.2017

pavelcdn пишет:

у меня по коду только 1 вопрос , как указать № конкретной метки и № ридера.

Очень просто - индексом в массиве. Если у вас все ключи лежат в массиве keys[6], то указать, например, значение третьего ключа можно так - keys[2] (два - потому что нумерация идет с нуля)

Цитата:
а вот с подключением всей периферии огромные сложности , так как уже не одна тема тянется на N листов и некого нет даже примерного плана действия кроме использования кучи ардуино

Павел, а чего вы ждете? Тут исполнителю надо собирать макет и пробовать. Какие могут быть действия без реальной работы с железом? Для этого проекта в первую очередь нужны считыватели - и я очень сомневаюсь что у кого-то их шесть в наличии. Вы думаете, кто-то уже побежал их заказывать, чтобы решить вашу задачку?

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

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

В

andriano пишет:

BOOM пишет:

Документация везде одинаковая - описывает все что может.

Отнюдь.

Зачастую бывает так:

1. Ищешь по всему И-нету и скачиваешь откуда только можно дэйташит на конкретное устройство - штук 20 экземпляров.

2. Сравниваешь скачанное между собой и устанавливаешь, что из 20 скачанных многие повторяются, а различаются между собой только 3-4.

3. Обнаруживаешь, что ни в одном из скачанных дэйташитов нужные тебе функции не описаны.

4. Ищешь по всему И-нету и скачиваешь откуда только можно примеры работы с нужным устройством.

5. Ищешь в этих примерах работу с теми регистрами устройства, которые не описаны ни в одном из дйташитов.

6. Заодно проверяешь, что в найденных примерах в регистры пишутся именно рекомендованные в дэйташитах величины. В случае расхождения - анализируешь и выясняешь истину путем экспериментов. Зачастую оказывается, что врет именно дэйташит.

7. Пытаешься экспериментально применить те регистры, которые не описаны ни в одном дэйташите, и выясняешь, к чему это приводит. Нередко истину удается установить только полным перебором (благо, в подавляющем числе случаев перебору нужно подвергнуть не более 1-4 битов).

Это вы углубились. В даташиты ушли и другие тонкости. Я о доступной открытой документации говорил (PHP в частности). Нет там никаких подводных камней или чего хуже. Читай, понимай, делай. Да и в Си так же... 

Гриша
Offline
Зарегистрирован: 27.04.2014

на всякий случай напомню небольшую железную трудность...

ЕвгенийП пишет:

Стоки №№ 7 и 8 видели?

b707 пишет:

pavelcdn если модули стандартные "синенькие" с Али:

то это известная проблема, они не отпускают шину SPI даже при управлении посредством SS Там надо MOSI MISO через ключи пускать, принудительно оставляя на шине только один модуль в каждый момент. Если вам нужно прочитать одновременно 6 карт на 6 модулях - боюсь, не получится.