[Решено] Как подружить 2 RFID-сканера RC522 и Arduino Nano

Тема в разделе "Arduino & Shields", создана пользователем onmironov, 11 сен 2015.

  1. geher

    geher Гуру

    Например, так:
    Код (Text):

    #define MAXMFRCS 2
    MFRC522 *mfrc522[MAXMFRCS];
    byte mfrcSSpins [MAXMFRCS]={SS_PIN_1,SS_PIN_2};
    byte mfrcRSTpins [MAXMFRCS]={RST_PIN_1,RST_PIN_2};
     
    В setup:
    Код (Text):

    for (byte i=0;i<MAXMFRCS;i++)
    {
        mfrc522[i]=new MFRC522(mfrcSSpins[i], mfrcRSTpins[i]);
    }
     
     
    Последнее редактирование: 13 сен 2015
  2. DrProg

    DrProg Вечный нерд

    Можно ли считать притянутым через светодиоды, которые сигнализируют о включении того или иного MISO?
     
    ИгорьК нравится это.
  3. DrProg

    DrProg Вечный нерд

    По моему, как минимум, квадратные скобочки пропустил. )
    Да и SCK разделять вроде бы не надо.
     
    ИгорьК нравится это.
  4. geher

    geher Гуру

    Квадратные скобки поправил. Действительно забыл. А вот RST, разве это SCK? Не знаю, нужно ли его разделять. Так, на всякий случай.
     
  5. DrProg

    DrProg Вечный нерд

    Такой вопрос тогда, ss включать и выключать принудительно или они сами определяются при опросе?
     
    ИгорьК нравится это.
  6. Unixon

    Unixon Оракул Модератор

    Сигнал должен включаться на время транзакции SPI, это делает библиотека.
     
  7. DrProg

    DrProg Вечный нерд

    А выключает после? Или все остальные SS таки выключать вручную перед опросом очередной?
     
    ИгорьК нравится это.
  8. geher

    geher Гуру

    Тут два варианта действий.
    1. Посмотреть библиотеку, на предмет, что она делает с SS пином.
    2. Для гарантии SS устанавливать в LOW перед транзакцией и в HIGH после нее.
     
  9. DrProg

    DrProg Вечный нерд

    Вероятно какие то требованию к буферу имеют место, второй раз подряд он не считывается. Добавлением одной строки с дополнительным заполнением буфера ситуация исправилась, хоть это очень странно. Данный скетч работает четко, независимо определяя метки у каждого рфида. Всем большое спасибо. Автору темы особенно посвящается:
    Код (Text):
    #include <SPI.h>
    #include <MFRC522.h>

    #define RST_PIN        9          // пин RST

    byte maxRF = 1;                // всего рфидов (включая нулевой)
    byte ssRFpin[2] = {2, 3};      // SS пины рфидов

    byte massRFuid[2][4];          // массив UID меток (первый - номер ридера, второй - 4 числа UID)

    MFRC522 *mfrc522[2];

    void setup() {
      for (byte i = 0; i <= maxRF; i++) { // выставляем пины
        mfrc522[i] = new MFRC522(ssRFpin[i], RST_PIN);
      }

      Serial.begin(9600);
      while (!Serial);
      SPI.begin();
      for (byte i = 0; i <= maxRF; i++) {
        mfrc522[i]->PCD_Init();
      }
      Serial.println("Card please:");
    }


    void loop() {
      for (int i = 0; i <= maxRF; i++) { // заполняем массив меток
        readRF(i);
        delay (100);                    // не знаю надо ли
      }
      SerialRFprint();                  // печатаем содержимое массива меток на экран
      delay(2000);
    }



    void readRF (byte RF) {
      if ( ! mfrc522[RF]->PICC_IsNewCardPresent()) { // если метки нет
        massRFuid[RF][0] = 0;        // метим отсуствие метки в первом числе UID
        return;
      }
      if ( ! mfrc522[RF]->PICC_ReadCardSerial()) {
        massRFuid[RF][0] = 0;
        return;
      }

      dump_byte_array(mfrc522[RF]->uid.uidByte, 4, RF);
      mfrc522[RF]->PICC_IsNewCardPresent();
      mfrc522[RF]->PICC_ReadCardSerial();
    }


    void dump_byte_array(byte * buffer, byte bufferSize, byte RF) { // считываем UID в массив
      for (byte i = 0; i < bufferSize; i++) {
        massRFuid[RF][i] = buffer[i];
      }
    }

    void SerialRFprint () {            // печать массива меток на экран
      for (int i = 0; i <= maxRF; i++) {
        Serial.print("Card ");
        Serial.print(i, DEC);
        Serial.print(": ");
        if (massRFuid[i][0] == 0) {
          Serial.println("NO card");
        } else {
          for (int j = 0; j < 4; j++) { // печатаем UID
            Serial.print(massRFuid[i][j], HEX);
            Serial.print(" ");
          }
          Serial.println("");
        }
      }
    }
    Надо схему подключения нарисовать?

     
    Последнее редактирование: 13 сен 2015
    demiurg85, helpkey, redven и 3 другим нравится это.
  10. onmironov

    onmironov Нерд

    Огромное спасибо!

    Было бы замечательно

    п. с. Если находитесь в Мск -- готов угостить пивом, ну или отправить на карту на пиво (или на печеньки) =)
     
    Фисташка Трям и redven нравится это.
  11. onmironov

    onmironov Нерд

    Извиняюсь, что дергаю, но, если есть возможность, скиньте, пожалуйста, схему подключения. Заранее спасибо.
     
  12. DrProg

    DrProg Вечный нерд

    Пример для двух рфид, если нужно больше. под каждую выделяется своя нога и ее привязываем на свой SS (на схеме зеленым проводом).

    [​IMG]

    Хотя бы поставьте "мне нравится". )
     
    Последнее редактирование: 16 сен 2015
    demiurg85, helpkey, Andrey_K и 5 другим нравится это.
  13. onmironov

    onmironov Нерд

    Все сделал, все заработало, спасибо. Но теперь возник вопрос, который, собственно был изначально. Нужно заставить работать серв только при условии, что к нужным меткам поставлены нужные карты.
    На сколько я понимаю, нужно сравнить номер карты от нужного сканера, и, если все ок, повернуть серв. Т.е., мне нужно занести номер каждой карты в переменную, и потом переменную сравнивать с нужным значением. Попробовал вытащить номер карты из массива massRFuid таким образом:
    Код (Text):

    void OpenClose () {
      x = (massRFuid[0][1], DEC);
      Serial.println(x);
    }
     
    Но выводится 16, и не зависит от того, есть карта или нет. Сейчас попробую еще какие-нибудь варианты, но, если это не долго и не трудно, не подскажете? =)
     
  14. DrProg

    DrProg Вечный нерд

    Так это, в сериал порт же выводит номера карты при считывании. Бери да выписывай.
     
    ИгорьК нравится это.
  15. onmironov

    onmironov Нерд

    Номера-то выводятся, но мне нужно этот номер сравнить, и если он "правильный", повернуть серв
    Код (Text):
    Serial.println(x);
    это я написал, чтобы просто проверить, что в x попало
     
  16. DrProg

    DrProg Вечный нерд

    UID состоит из четырех чисел, поэтому они и хранятся у меня в массиве. Чтобы сравнить нужно делать это либо поэлементно, либо сложить в строковую переменную в виде текста и сравнивать с ключевым текстом.
     
    ИгорьК и onmironov нравится это.
  17. onmironov

    onmironov Нерд

    Т.е., мне нужно сравнить каждый элемент массива с нужным мне числом. А есть возможность сравнивать массив с массивом?

    upd: Извиняюсь, только что понял, о чем вы сказали, сейчас попробую
     
  18. DrProg

    DrProg Вечный нерд

    Вот этот простой пример поможет вам понять как сделать текстовую строку из нескольких чисел:

    Код (Text):
    String stroka1 = "hello!";
    int a = 18;
    int b = 12;


    void setup() {
      // put your setup code here, to run once:
    Serial.begin(9600);
    Serial.println(stroka1);
    stroka1 = String(a,DEC);
    stroka1 = stroka1 + String(b,DEC);
    Serial.println(stroka1);
    }

    void loop() {
      // put your main code here, to run repeatedly:

    }
     
    ИгорьК и onmironov нравится это.
  19. onmironov

    onmironov Нерд

    Огромно, просто громадное спасибо!

    Сделал вот так (мб коряво, но работает):

    Код (Text):

    void OpenClose () {
      firstCard = String(massRFuid[0][0], DEC) + String(massRFuid[0][1], DEC) + String(massRFuid[0][2], DEC) + String(massRFuid[0][3], DEC);
      secondCard = String(massRFuid[1][0], DEC) + String(massRFuid[1][1], DEC) + String(massRFuid[1][2], DEC) + String(massRFuid[1][3], DEC);
      if (firstCard == "НОМЕР_КАРТЫ_1" && secondCard == "НОМЕР_КАРТЫ_2")
        {
          servo.write(180);
          } else {
              servo.write(0);
            }
    }
     
     
  20. Скажите пожалуйста, в схеме нет светодиодов они там нужны?