MFRC522モジュールが複数のPICCを連続して読み込めない

私は最近、MiFare 1Kカードを2個セットしたキットとして登場したArduino Unoで使用するMFRC522 RFIDモジュールを購入しました。

私が抱えていた問題は、Sketchをリセットせずにカードを連続してスキャンすることはできません(同じカードか2つのカードを連続してスキャンすることはできません)。私はリーダーの前にカードを持っていてスキャンしますが、リーダーの前に別のカードを置くと、それが mfrc522.PICC_IsNewCardPresent()関数にあると認識されません。ただし、この例のスケッチ "DumpInfo"を使用すると機能します。

ここに私が書いたコードがあります(私の悪い習慣/不安定さを許してください)。

/* Include Required Libraries */
#include 
#include 

/* Define Values for MFRC522 */
#define RST_PIN 9
#define SS_PIN 10

/* Instantiate the MFRC522 Object */
MFRC522 mfrc522(SS_PIN, RST_PIN);

/* Initialize Variables */
byte resultBuffer[18];
MFRC522::MIFARE_Key key;
unsigned int integerValue = 0;
char incomingByte;

void setup()
{
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  Serial.println(F("Ready to scan card..."));

  for (byte i = 0; i < 6; i++)
  {
    key.keyByte[i] = 0xFF;
  }
}

void loop()
{
  if (!mfrc522.PICC_IsNewCardPresent())
  {
    if (Serial.available() <= 0)
    {
      return;
    }

    integerValue = 0;
    while(true)
    {
      incomingByte = Serial.read();
      if (incomingByte == '\n') break;
      if (incomingByte == -1) continue;
      integerValue *= 10;
      integerValue = ((incomingByte - 48) + integerValue);
    }

    printHeader();
    Serial.println("NEW BLOCK READ VALUE :");
    Serial.println(integerValue);
  }

  if (!mfrc522.PICC_ReadCardSerial())
  {
    return;
  }

  readAndPrint(integerValue);
}

void printHeader()
{
  Serial.println(" ");
  Serial.println("----------------------------------------");
}

int authenticateKeyA(int blockNumber)
{
  printHeader();
  Serial.println("Authenticating with key A...");

  int largestModulo4Number = blockNumber/4 * 4;
  int trailerBlock = largestModulo4Number + 3;

  byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));

  if (status != MFRC522::STATUS_OK)
  {
    Serial.println("ERROR : Authentication was unsuccessful.");
    return 0;
  }
  else
  {
    Serial.println("SUCCESS : Authentication was successful.");
    return 1;
  }
}

int authenticateKeyB(int blockNumber)
{
  printHeader();
  Serial.println("Authenticating with key B...");

  int largestModulo4Number = blockNumber/4 * 4;
  int trailerBlock = largestModulo4Number + 3;

  byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));

  if (status != MFRC522::STATUS_OK)
  {
    Serial.println("ERROR : Authentication was unsuccessful.");
    return 0;
  }
  else
  {
    Serial.println("SUCCESS : Authentication was successful.");
    return 1;
  }
}

int readBlock(int blockNumber, byte *resultBuffer)
{
  printHeader();
  Serial.println("Starting read block function...");

  int authSuccess = authenticateKeyA(blockNumber);
  Serial.println(" ");

  if (!authSuccess)
  {
    Serial.println("ERROR : Terminating function.");
    return 0;
  }

  byte bufferSize = 18;

  byte status = mfrc522.MIFARE_Read(blockNumber, resultBuffer, &bufferSize);

  if (status != MFRC522::STATUS_OK)
  {
    Serial.println("ERROR : Read failed.");
    return 0;
  }
  else
  {
    Serial.print("SUCCESS : Block ");
    Serial.print(blockNumber);
    Serial.print(" was read successfully.");
    return 1;
  }

  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}

void readAndPrint(int blockNumber)
{
  readBlock(blockNumber, resultBuffer);

  printHeader();
  Serial.println("RESULT :");
  for (int j=0 ; j<16 ; j++)
  {
   Serial.print(resultBuffer[j], HEX);
   Serial.print(" ");
  }
  Serial.println(" ");

  delay(2000);
  printHeader();
  Serial.println("Ready to scan card...");
}

最初にカードをスキャンする前に、シリアル出力は次のようになります。

First capture of serial monitor.

カードを最初にスキャンした後、シリアル出力は次のようになります。

Second capture of serial monitor.

2回目にカードをスキャンした後、シリアル出力は画像2から変化しません。 serial.println( "no card detected"); プログラムがフリーズしているかどうかを確認するだけです(私は他の誰かが最初のカードをスキャンした後にプログラムが凍結してしまうという問題を抱えていると聞いていました) - それは凍結されていませんでした。最初のカードをスキャンする前後に、「カードが検出されませんでした」というメッセージが繰り返し表示されます。

どのように進めるべきかについての手がかりがないので、私は大いに助けていただきたいと思います。

乾杯、

0
'loop()'から戻らないでください。ループは永遠に繰り返されます。
追加された 著者 dotnetengineer,
@TisteAndii画像が質問に追加されました。乾杯
追加された 著者 Brandon,
あなたがそれを返すなら、それはまだループします。
追加された 著者 Nick Gammon,
シリアルモニタには何が印刷されていますか?あなたの質問に画像を投稿してください。
追加された 著者 TisteAndii,

1 答え

if(mfrc522.PICC_IsNewCardPresent())でなければなりませんが、IFブロック内のコードは、カードが存在するときに実行されるように、あなたの意図する正しい条件は if構造。あなたが発見したように、プログラムはフリーズしていません。 readAndPrint()を呼び出す前に、2つのreturn文の1つ(わからない)が loop()を中止する原因になっています。あなたの現在のコードで:

  • 最初の return は、カードが検出されなくても常に実行されます。 serial.available()は0を返し、 loop()が返されます。
  • 2番目の return は、 SELECT でカードのUIDを取得できない場合に実行されます。 SELECT は、新しいカード(範囲内に入ったばかり)、または PICC_WakeupA()を最初に呼び出していない場合にのみ失敗します。 HALT されたカード(既に範囲内にあるが眠っているカード)の

私はあなたが別のカードを試しているのか、ただ一つだけ試しているのかはわかりません。そのカードが1枚の場合は、カードを範囲外に取り出してから再び範囲内に持っていなければならない場合があります。しかし、カードのデータを複数回読みたい場合は、範囲外にすることなく、 PICC_IsNewCardPresent()の代わりに PICC_WakeupA()を呼び出す必要があります。名前が示すように、あなたは眠っているカードを目覚めさせているし、新しいカードを完全には検出していない。また、以下のように loop()を構造化します:

void loop(){
  if (!mfrc522.PICC_IsNewCardPresent()) { //replace the condition with PICC_WakeupA()   
    return; //if you dont want the card to leave the reader's range
  }

  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }

 //all the code that should be executed if a card has been detected and its UID read

}

しかし、通常は HALT にカードを入れてすぐ次の繰り返しで目を覚ますことはほとんど意味がないので、一度にすべてのセクタの読み書きを行い、カードを保持してから待ちます新しいカードがフィールドに入るために;少なくともそれはほとんどのアプリケーションで望まれていることです。

1
追加された