How to use multiple MFRC522 devices on Wio Terminal
Wio Terminal で複数のMFRC522 を制御する
前提知識
かなり大雑把ですが、用語と意味の別を紹介しておきます。これらの語はサンプルプログラムのコメントやプログラムに現れます。本記事で載せるプログラムにも、
-
:PICC Proximity Integrated Circuit Card
カードやIC タグのことIC -
:PCD Proximity Coupling Device
カードのデータを読書きする機器IC

中央の基板が
引用:https://amzn.asia/d/dszK7YW
-
:RFID Radio Frequency IDentification
技術概念そのもの -
:UID Unique IDentifier
重複しない一意の識別番号 -
:NUID Non Unique IDentifier
重複し得る識別番号
だけでは足りない場合に使うらしいUID
回路

一つでもそれなりの配線になるものを二つ使おうとしているだけあって、配線が煩雑になります。勿論、もっと配線を簡略化することもできますが、できるだけ見通しが良くなるよう、わざと変な配線図にしています。
図の中にWio Terminalがない?

引用:https://ht-deko.com/arduino/wio_terminal.html
配線図に使っているのは丁字の
製品によって色や形状が異なり、佳品には塀のようなものが付いています。コネクターを挿すに当たっては親切な作りです。

引用:https://amzn.asia/d/bXha1l2

引用:https://amzn.asia/d/fZKcPLe

引用:https://amzn.asia/d/8pKova1
しかし

引用:https://akizukidenshi.com/catalog/g/g108889/
但し秋月電子のこちらは半田付けが必要です。面倒なら、上に並べたような佳品を破壊するのが楽でしょう。
とは言え図でも最早よくわからないので、表にもしておきます。
|
|
||
|---|---|---|
GPIO8 |
SDA |
- |
GPIO16 |
- | SDA |
GPIO11 |
SCK |
SCK |
GPIO10 |
MOSI |
MOSI |
GPIO9 |
MISO |
MISO |
GPIO24 |
IRQ |
IRQ |
GND |
GND |
GND |
GPIO25 |
RST |
RST |
3V3 |
3.3V |
3.3V |
プログラム
事前にMFRC522をダウンロードします。

結論から言えば、サンプルプログラムそのままの流れでは正しく動きませんでした。
#include <SPI.h>
#include <MFRC522.h>
// Interrupt Request
constexpr uint16_t IRQ_PIN = BCM24;
// PCD count
constexpr uint16_t PCD_COUNT = 2;
// Reset
constexpr uint16_t RST_PIN_1 = BCM25;
constexpr uint16_t RST_PIN_2 = BCM25; // = same as RST_PIN_1
const byte RESETS[PCD_COUNT] = {RST_PIN_1, RST_PIN_2};
// Slave Select (Serial Data)
constexpr uint16_t SS_PIN_1 = PIN_SPI_SS; // BCM8
constexpr uint16_t SS_PIN_2 = BCM16;
const byte SLAVE_SELECTIONS[PCD_COUNT] = {SS_PIN_1, SS_PIN_2};
const byte SLAVE_SELECTIONS_WITH_DEFAULT[PCD_COUNT] = {PIN_SPI_SS, SS_PIN_2};
// MFRC522 instance
MFRC522 g_aMfrc522[PCD_COUNT];
// dump a byte array to the serial monitor
void dump_byte_array(byte* pBBuffer, uint8_t u8BufferSize);
void dump_byte_array(byte* pBBuffer, uint8_t u8BufferSize) {
for (uint8_t i = 0; i < u8BufferSize; i++) {
Serial.print(pBBuffer[i] < 0x10 ? " 0" : " ");
Serial.print(pBBuffer[i], HEX);
}
Serial.println(); // line feed
}
void setup() {
Serial.begin(115200);
while (!Serial);
SPI.begin();
for (uint8_t i = 0; i < PCD_COUNT; i++) {
g_aMfrc522[i].PCD_Init(SLAVE_SELECTIONS_WITH_DEFAULT[i], RST_PIN_1);
// ここで待機しないと片方しか動かない
delay(100);
}
Serial.println(F("[INFO]\tRC522 Multi-PCD Sample"));
}
void loop() {
for (uint8_t i = 0; i < PCD_COUNT; i++) {
if ( g_aMfrc522[i].PICC_IsNewCardPresent() && g_aMfrc522[i].PICC_ReadCardSerial() ) {
Serial.print(F("[INFO]\tPCD ")); Serial.print(i); Serial.println(F(" detected new card."));
Serial.print(F("[DEBUG]\tUID: ")); dump_byte_array(g_aMfrc522[i].uid.uidByte, g_aMfrc522[i].uid.size);
MFRC522::PICC_Type piccType = g_aMfrc522[i].PICC_GetType(g_aMfrc522[i].uid.sak);
Serial.print(F("[DEBUG]\tType: ")); Serial.println(g_aMfrc522[i].PICC_GetTypeName(piccType));
g_aMfrc522[i].PICC_HaltA();
g_aMfrc522[i].PCD_StopCrypto1();
}
delay(50);
}
}
複数のMFRC522::PCD_Init()を複数回実行します。この時サンプルプログラムでは、delay()を入れることなく実行しています。
しかしMFRC522::PCD_Init()の間にdelay()を挿んだところ、安定して動作するようになりました。
動作の様子
念のためPCD 0とあるのが一つ目、PCD 1とあるのが二つ目です。
[INFO] RC522 Multi-PCD Sample
[INFO] PCD 0 detected new card.
[DEBUG] UID: ■■ ■■ ■■ ■■
[DEBUG] Type: MIFARE 1KB
[INFO] PCD 1 detected new card.
[DEBUG] UID: ■■ ■■ ■■ ■■
[DEBUG] Type: MIFARE 1KB
[INFO] PCD 0 detected new card.
[DEBUG] UID: ■■ ■■ ■■ ■■
[DEBUG] Type: MIFARE 1KB
[INFO] PCD 1 detected new card.
[DEBUG] UID: ■■ ■■ ■■ ■■
[DEBUG] Type: MIFARE 1KB
[INFO] PCD 0 detected new card.
[DEBUG] UID: ■■ ■■ ■■ ■■
[DEBUG] Type: MIFARE 1KB
[INFO] PCD 1 detected new card.
[DEBUG] UID: ×× ×× ×× ××
[DEBUG] Type: MIFARE 1KB
[INFO] PCD 0 detected new card.
[DEBUG] UID: ■■ ■■ ■■ ■■
[DEBUG] Type: MIFARE 1KB
以上、二つの
Discussion