32
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ESP-WROOM-02とRFID-RC522で非接触Lチカ

Posted at

カードかざしたらピコーンと鳴らせてみたいと思ったのですが、鳴らすためのブザー用意するのも面倒だったので、カードかざしたらピカ!と光るLチカ(LEDをチカチカさせる)に挑戦してみました。

調査

カードかざしたら反応するモジュールはどれ?

Suicaの技術あたりから攻めるのがよさそうなので、「Suica 仕様」で検索すると、「非接触型IC」という言葉が出てきました。
「非接触型IC チップ」で検索してみると、どうも「RFID」という技術ということです。

電子工作絡みで検索する時、「自作」というキーワードを入れると鉄板です。
今回も「RFID 自作」で検索すると、それっぽいのがいっぱい出てきました。

電子工作系は、古いと2000年の歴史、ではなくて西暦2000年頃からの記事もあって、現在も手に入るのかどうかよくわからない内容もあります。金額と調達可能性、開発の簡単さ(本当の難易度は実際やってみないとわからないので、加工しなくていいかとか、部品点数が少ないかとかをみる)を考慮して、モジュールを選定します。

調査していくと、Arduinoと組み合わせてRFIDでLチカがそこそこ見つかりました。実績があるRFID-RC522モジュールがよさそうです。

参考URL

Wifiとも接続したいよ

Lチカできたら、その後はカードかざしたらインターネット接続して何かしたいよね、ということで将来を見据えてWifiモジュールで単体でArduinoとして使える、ESP-WROOM-02と組み合わせることにしました。

※今回の記事では、最終的にESP-WROOM-02上でLチカさせてますが、Wifiとして外部にHTTPリクエスト送ったりしていません。

どうESP-WROOM-02とRFID-RC522を接続するの?

物理的につなげても、両方のモジュールがお話できないといけません。RFID-RC522の通信仕様をみると、SPI/UART/I2Cと書いてあるのですが、SPI以外の通信方法が可能かどうかわからなかったので、SPIで通信することにしました。(サンプルもあるので)

SPI通信のピンを確認すると、SS/MOSI/MISO/SCKの4本が最低必要なようです。また使っているかどうかわからないのですが、リセット用の信号線もRFID-RC522に接続されているので用意します。

ESP-WROOM-02のブレークアウトボードのピン設定の詳細がいまいち確認できないのですが、どうもmikroBUS規格互換だということで、そちらを見るのがよさそうということに気づきました。(なので+5VのところがESP-WROOM-02では無効化されている)

参考URL

用意するもの

モジュール

※(リンク先はたぶん今回説明するのと同等品。購入時の参考まで)

その他(今回使用したもの)

  • ブレッドボード(長)
  • ブレッドボード用 ジャンパーワイヤ各種
  • USBケーブル(PCと接続できる端子と、AE-FT234Xと接続できる端子が両端にあるケーブル)
  • 発光ダイオード(赤) x 2 (電源確認用と、Lチカ用)
  • 1KΩ抵抗 x 2 (LED用 ※抵抗の値は発光ダイオードの許容範囲にあわせて適宜調整してください)
  • 0.1μF積層セラミックコンデンサ x 1 (パスコン用)
  • 出力DC3.3V スイッチング電源(AC100Vコンセントから安定的に電源取得するため)
  • スイッチング電源用DCジャック

開発環境

  • MacBook Air (OS X Yosemite)
  • Arduino IDE 1.6.5

作業手順

  1. Arduino IDEにESP-WROOM-02の開発ボード追加を行います
  2. Arduino IDEにRC522のライブラリを追加します
    • MFRC522:githubから、一式をZIPダウンロードします。
    • Arduino IDEのメニューの「スケッチ」→「Add .ZIP Library..」から、ダウンロードしたファイルを選択します。
    • Arduino IDEのメニューの「ファイル」→「スケッチの例」の下の方に「MFRC522」という項目が追加されていたら追加完了です。
  3. ブレッドボード上に配線します
    • ESP-WROOM-02モジュールの下の空間を利用できると、配線がすっきりします
    • 発光ダイオードは向きがあるので注意
  4. USBケーブルでMacとAE-FT234Xを接続します
    • Arduino IDEのメニューの「ツール」から、ポートを「/dev/cu.usbserial~」にします。(環境によって~の後がいろいろ変わるようです)
  5. プログラムをコンパイルしてESP-WROOM-02に書き込みます。
    • ESP-WROOM-02側のモードを書き込みモードにしないと、Arduino IDEで書き込めない旨のエラー表示となります
    • USBからは電源供給せずに、3.3Vのスイッチング電源側から供給しますので、USBとは別にスイッチング電源を接続して通電状態としてください(少なくともESP-WROOM-02には電源が供給されていないと書き込めません)
    • MFRC522ライブラリをESP-WROOM-02デバイスで使おうとすると、コンパイル時に、「WARNING: library MFRC522 claims to run on [avr, STM32F1] architecture(s) and may be incompatible with your current board which runs on [esp8266] architecture(s).」といって、警告が出ます。出ますが、コンパイル通るし動くので無視しました。
  6. Arduino IDEがプログラム書き込んだ後、自動的にリセットされてESP-WROOM-02がフラッシュROMから立ち上がります。なので、そのままでも動きます。USBからのケーブルは抜きたい人は、一度電源切って、USB周りのケーブル抜いて、フラッシュROM起動モードにしてから再度電源ONにしてください。

ブレッドボードに全部載せた

左上の3本ぐらい明後日の方向に伸びているのが、AE-FT234Xにつながっています(小さすぎてUSBのケーブルの重さでブレッドボードから離れてしまうので、あえて外しています)

これはプログラムの書き込みとシリアルコンソールでのデバッグに使うだけなので、動作時はこの明後日の方向に伸びているケーブルは外しています。

ちなみに電源はスイッチングアダプタから直供給で、電源スイッチとかはないです。

IMG_0317.png

動かしてみた

実際に動かしてみました。RFID-RC522買ったらついてきたカードをかざすとカードが検出されます。

横方向に外れた場合にLEDが光らなくなる(カード未検出となる)のは理解しやすいですが、縦方向も10cm程度離すとLED光りませんでした。
esp-wroom-02_with_rfid_rc522_2_anime.gif

回路図

電子回路作ったら清書しましょうという教えに従い、作成しました。
回路図エディタBSch3V利用させて頂きました。とても使いやすいですね。
esp-wroom-02_with_rfid_rc522_2.PNG

プログラム(Arduino)

ESP-WROOM-02のフラッシュROMを書き込みモードにして、Arduino IDEから突っ込むプログラムは以下になります。

  • SSピンと、REESTピンは自由に変更可能です。変更可能なのですが、ESP-WROOM-02のGPIO15ピン使おうとすると、どうも挙動があやしいので、GPIO15ピンは使わない方がいいかもしれません。(ジャンパー設定で使っているからかもしれませんし、ESP-WROOM-02のリセット挙動に使うピンらしいのでそのせいかもしれません)
  • 先ほども書きましたが、WifiでIPアドレス取得しているだけで、HTTP通信とかしていません。ただ、IPアドレスは取得しているので、SSIDとパスワードは必要です(不要なら削ってください)
ESPWROOM02_RC522.ino
/*
 * ESP-WOORM-02とMFRC522を接続する
 * 2015/10/12
 * 
 * 配線(SPI通信):
 *  ESP-WROOM-02 : MFRC522
 *        GPIO 5 -> SDA(1) - ESP-WROOM-02側はSS_PINで定義
 *        GPIO14 -> SCK(2)
 *        GPIO13 -> MOSI(3)
 *        GPIO12 <- MISO(4)
 *                  RQ(5)   - 未使用
 *                  GND(6)  - GNDにつなぐ
 *        GPIO16 -> RST(7) - ESP-WROOM-02側はRST_PINで定義
 *                  3V3(8)  - 電源につなぐ
 * 
 * LED:   GPIO 4
 * 
 */
#include <SPI.h>
#include <MFRC522.h>
#include <ESP8266WiFi.h>

#define RST_PIN 16 // MFRC522用リセットピンGPIO NO
#define SS_PIN  5  // MFRC522用SS(SDA)ピンGPIO NO

MFRC522 mfrc522(SS_PIN, RST_PIN); // MFRC522のインスタンスを作成

#define CARD_PRESENT_PIN 4 // MFRC522にカードが検知されたら光らせるGPIO NO
bool cardset;     // MFRC522にカードが検知されているかどうか
int timeoutcount; // MFRC522からカードが連続で離れた回数を記録

const char* ssid = "xxxxxxxx";         // ESP-WROOM-02用 Wifi SSID(各自設定してください)
const char* password = "xxxxxxxxxxxx"; // ESP-WROOM-02用 Wifi パスワード(各自設定してください)

void setup() {
  // UART接続初期化
  Serial.begin(115200); // UARTの通信速度を変更したい場合はこちらを変更
  delay(10);

  // カード検出用のGPIO初期化
  pinMode(CARD_PRESENT_PIN, OUTPUT);
  digitalWrite(CARD_PRESENT_PIN, LOW);

  // MFRC522用変数初期化
  cardset = false;
  timeoutcount = 0;

  // MFRC522のスケッチのDumpInfoを参考にした。ref) https://github.com/miguelbalboa/rfid
  SPI.begin();          // SPI初期化
  mfrc522.PCD_Init();   // MFRC522初期化
  ShowReaderDetails();  // MFRC522 Card Readerのバージョンを返す。00かFFなら配線間違いの可能性
  
  // とりあえずWifiにつなぐ
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  
  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  // カードの検出
  if ( !mfrc522.PICC_IsNewCardPresent()) {
    // 検出されなかった場合の処理
    if (cardset) {
      // すでにカードが検出されていた場合で、連続4回未検出になったらLEDをLOWにする
      // 検出後、タイムアウトと検出を繰り返すのでその対策 
      if (timeoutcount > 4) {
        digitalWrite(CARD_PRESENT_PIN, LOW);
        Serial.println("LED LOW");
        cardset = false;
        timeoutcount = 0;
      } else {
        // 4回以内なら連続未検出回数を増やす
        timeoutcount++;
      }
    }
    delay(5);
    return;
  }

  // カードが初めてor改めてセットされた場合、LEDをHIGHにする
  if (!cardset) {
    digitalWrite(CARD_PRESENT_PIN, HIGH);
    Serial.println("LED HIGH");
    cardset = true;
  }
  timeoutcount = 0;
  delay(100);
}

 // MFRC522のスケッチのDumpInfoのまま。ref) https://github.com/miguelbalboa/rfid
 // LICENSE:https://github.com/miguelbalboa/rfid/blob/master/UNLICENSE
void ShowReaderDetails() {
  // Get the MFRC522 software version
  byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
  Serial.print(F("MFRC522 Software Version: 0x"));
  Serial.print(v, HEX);
  if (v == 0x91)
    Serial.print(F(" = v1.0"));
  else if (v == 0x92)
    Serial.print(F(" = v2.0"));
  else
    Serial.print(F(" (unknown)"));
  Serial.println("");
  // When 0x00 or 0xFF is returned, communication probably failed
  if ((v == 0x00) || (v == 0xFF)) {
    Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
  }
}

免責事項

回路図どおり、プログラムどおりに作っても動かなかったらごめんなさい。無保証です。

おまけ

今回「動かしてみた」で使った動画は、デジタルカメラの動画モードで撮影→ffmpegで変換してアニメーションGIFとして作成しました。GUIで編集するよりも手軽で綺麗なアニメーションGIFが作れました。

  1. 入力動画を横320、縦は入力動画のアスペクト比に合わせて縮小
    • $ ffmpeg -i input_origin.MP4 -vf scale=320:-1:flags=lanczos -strict -2 -y input_mini.mp4
  2. 今回の動画で抽出したい部分を抽出するため、開始16秒から4秒間分だけ出力する
    • $ ffmpeg -i input_mini.mp4 -ss 16 -t 4 -strict -2 -y input_mini_16_4.mp4
  3. 最適化されたパレット画像を生成(fpsを10に設定)
    • `$ ffmpeg -i input_mini_16_4.mp4 -vf fps=10,palettegen=stats_mode=diff -y mp4_palette.png'
  4. パレット画像を利用してアニメーションGIFを生成(fpsを10に設定)
    • $ ffmpeg -i input_mini_16_4.mp4 -i mp4_palette.png -lavfi fps=10,paletteuse -y output.gif

動画フォーマットは圧縮が効いているのですが、アニメーションGIFにするとファイルサイズが肥大化するので、1Mbyte以内に収めようと思うと、5秒程度が限界ですね。

参考URL

32
35
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?