ESP32(ESP-WROOM-32)に RFID リーダーを繋ぐ

 おおよそ、月に1度くらいの頻度で携帯電話を自宅に置き忘れたまま出発してしまい、会社に着いてから「あ、忘れてきた!」ってことがおきます。


 事務所の電話じゃなくて直接携帯にかけてくるお客さんが多いのですが、何度かけても全く出ないって状態が続いて、いよいよ半ギレで「連絡が取れないんだけど・・・」って事務所の電話にかけてくる、というパターンがほとんど。
 「すみませんでした、実は携帯を・・・」って風になるのですが、電話をかけてくるお客さんは知れてるので、お互いが不幸にならないよう携帯を自宅に忘れてきたときには先にその旨を知らせておくようにしてますが、お客さんに不便をかけるし、自分自身にとっても大変に不便。


 携帯に RFID タグを取り付けて、エンジン始動時に付近にタグがなかったらアラーム出すようにしたらいいんじゃね?って思いつきましたので、早速試してみることにします。


 タグと言えば RFIDRFID と言えば 135kHz か 13.56MHz だよね?ってことで、とりあえず両方それぞれ Aliexrepss でポチったんですが、13.56MHz のほうが速攻で届きました。
 RFID-RC522 という青い基板のやつで、軽くググるDIY界 のデフォルトスタンダードぽい感じです。
 

 ってことで回路図。
(かなり前に買った OLED 付きの ESP32)


http://dl.ftrans.etr.jp/?5c312aff46544c2fbab818990983e6b2d867385f.png


 ESP8266 との組み合わせはネットで見つけましたが、ESP32 の例はあまり見つけることが出来ません。
 とはいえ、ArduinoIDE から ライブラリの追加 の中に Arduino RFID Library for MFRC522 が出てきたので、非互換の警告を無視して進めたものの、コンパイルも通るのに作動せず。
 どうも調べると ESP32 には SPI が3種類あって、VSPI/HSPI と呼称される2つがユーザーに開放されているとのこと。


 んで動かないライブラリのソースを調べると、デフォルトの SPI をそのまま使ってます。
 「デフォルトの SPI」とは ESP32 では VSPI のほうらしいのですが、あいにく OLED 付き ESP32 には VSPI のピンが生えていません!


 上の回路図も HSPI を使う前提でして、どうしても HSPI を使いたく本家ソースに手を入れて動くようにしたのですが、改めて 本家のソース を(Arduino IDE からでなく Github から直接)取得したら・・・


 HSPI にも対応してた!


 Arduino IDE のライブラリ追加 と Github とは連動している(全く同じものを見ている)と思い込んでいたのですが、Github のほうだけ更新されて Arduino IDE のリストには反映されてない、ってことが起きることを初めて知りましたよ。


 とウダウダ愚痴を言っても仕方ないので、HSPI を使う前提でソース貼っときます。
※別に Arduino RFID Library for MFRC522 もライブラリ追加しておくこと

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

#define OLED

#ifdef OLED
  #include <OLEDDisplay.h>
  #include <OLEDDisplayFonts.h>
  #include <SSD1306.h>
  #include <SSD1306Wire.h>
  SSD1306  display(0x3c, 5, 4);   // sda:5 scl:4
#endif

#define RST_PIN         16         // Configurable, see typical pin layout above
#define SS_PIN          15         // Configurable, see typical pin layout above

SPIClass hspi;
MFRC522 mfrc522(SS_PIN, RST_PIN, &hspi);  // Create MFRC522 instance

void setup() {
  Serial.begin(9600);
  while (!Serial);
  
  hspi.begin();
  mfrc522.PCD_Init();
  mfrc522.PCD_DumpVersionToSerial();
  mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);
  Serial.println(F("Scan PICC"));

#ifdef OLED
  display.init();
  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.clear();
  display.drawString(0, 0, F("Scan PICC"));
  display.display();
#endif  
}

void loop() {
  // Look for new cards
  if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  mfrc522.PICC_HaltA();

  char mes1[50];
  char mes2[50];
  sprintf(mes1, "Card UID: %02x %02x %02x %02x", mfrc522.uid.uidByte[0], mfrc522.uid.uidByte[1], mfrc522.uid.uidByte[2], mfrc522.uid.uidByte[3]);

  MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
  sprintf(mes2, "PICC type: %s", mfrc522.PICC_GetTypeName(piccType));

  Serial.println(mes1);
  Serial.println(mes2);

#ifdef OLED
  display.clear();
  display.drawString(0, 0, mes1);
  display.drawString(0, 12, mes2);
  display.display();
#endif
}

 ソース内で

MFRC522 mfrc522(SS_PIN, RST_PIN, &hspi);  // Create MFRC522 instance

って定義してますが、これは Arduino IDE → ライブラリ追加 ではサポートされていてません。
 コンパイルエラーが出たらライブラリを疑って下さい。


http://dl.ftrans.etr.jp/?67d5302e41c544329bd3843f6eb00490c35f4472.jpg http://dl.ftrans.etr.jp/?58e4308ace044fb7a383bda0d2516f07c3bbf2f9.jpg


 ちなみに、本家ソースを私が修正したときも、全く同じように引数3つ目に SPIClass を参照渡しできるようにしました。
 よって後に本家で最新を見つけたときにも ino は修正しないで済んだという・・・


(追記)
 当初の「携帯に RFID タグを取り付けて、エンジン始動時に付近にタグがなかったらアラーム出すようにしたらいいんじゃね?」の目論見ですが、タグを数センチの至近距離まで近づけないと反応しない、という運用性の悪さからお蔵入りとなりました。