RFIDの配線とArduinoスケッチ

使った部品、つなげたいパーツ

・Arduino Nano(互換製品)
・RFID-RC522(MFRC-RC522とも表記されているけれど、違いが判らないです)権利とか調査不足で分かっていないです。
参考http://www.orangetags.jp/words/mifare
・これらを5cm x 7cmのユニバーサル基板に。

配線した様子

参考

電子工作のヒント

ここで書かれていたユニバーサル基板に配線するとき、はんだ面と配線面を分けるという考え方があるということが嬉しかった。
まっさらから挑むときに常識となっていることも言葉で書き起こしてもらえるのってとても助かる。
(すでに常識ではなくなったことだとしても、情報をたどるうちに訂正されるから)

実際の配線

できるだけ配線がクロスしないようにと作ったつもりだが、どうしても一か所重なってしまうのがつらい。
チップの下に隠れるような配線は良いのかどうかということは判断つかないのも(誰か教えてほしい)
プリント基板にしたいと思ったりするけれど、クロスしているところとかどうするのかなーとか、
マイコン+RFIDのチップでものすごく効率的な回路設計もできるんだろうと思う。(参考にした「ちょいロックキー」ではそのようになっていた)

配線した後で、テスターにて導通テストをすべて行い、通っていることを確認したり。

何度か試作(失敗)した配線

結局これらの配線を基板に作った。
1つはショートしてしまってArduinoが焼き焦げてしまったり、ピンヘッダの付け方を間違えて使えなかったり、
5cm x 8cmの基板じゃないと乗らないと思い込んでいて、手に入りにくい基板上に配線してしまったり。

※最終的には右の緑色のユニバーサル基盤5cm x 7cmに配線した。

あと、何度も同じ配線をするために、自分のためのリファレンス(参照専用)基板を作ったりした。

Arduinoスケッチ

参考にしたのは、こちらのスケッチ。Zipでライブラリをインストールして、選ぶだけ
https://github.com/miguelbalboa/rfid/tree/master/examples

導入についてはこちらを全面的に参考にさせていただきました。
「Arduinoで複数のNFCタグを区別する」
https://qiita.com/yuji_miyano/items/f00f9e3f2edc8025b704

2018/3/23時点の動いているスケッチから

/* シリアル出力を抑制
 * --------------------------------------------------------------------------------------------------------------------
 * Example sketch/program showing how to read new NUID from a PICC to serial.
 * --------------------------------------------------------------------------------------------------------------------
 * This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
 * 
 * Example sketch/program showing how to the read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID
 * Reader on the Arduino SPI interface.
 * 
 * When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE
 * then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M). When
 * you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output
 * will show the type, and the NUID if a new card has been detected. Note: you may see "Timeout in communication" messages
 * when removing the PICC from reading distance too early.
 * 
 * @license Released into the public domain.
 * 
 * Typical pin layout used:
 * -----------------------------------------------------------------------------------------
 *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD   Uno/101       Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin           Pin       Pin        Pin              Pin
 * -----------------------------------------------------------------------------------------
 * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
 * SPI SS      SDA(SS)      10            53        D10        10               10
 * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
 */
 
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
#include <avr/sleep.h>
 
constexpr uint8_t RST_PIN = 9;     // Configurable, see typical pin layout above
constexpr uint8_t SS_PIN = 10;     // Configurable, see typical pin layout above
constexpr uint8_t SV_PIN = 3;     // Configurable, see typical pin layout above
 
MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class
 
int pos = 0;    // variable to store the servo position
Servo myservo;  // create servo object to control a servo
 
// 
//unsigned long opentime = 300000; // 5分
//unsigned long opentime   = 30000; // 30秒
unsigned long opentime   = 1800000; // 30分
unsigned long unlocktime = 0; // 開錠した時間
unsigned long checktime  = 0; // 経過秒数
unsigned long sleeptime  = 0; // 施錠後停止する時間
int           servodegree = 180; // 自動電源OFFのために電力調節
int           servodegree_pulse = 180; // 自動電源OFFのために電力調節 開錠時の一時角度
int           pulse_count = 0;   // 自動電源OFFのために電力調節
boolean       close_flag  = true;   // 閉めたことを記録 true = 閉めた。false = 開いた
 
void setup() { 
  //Serial.begin(9600); // デバッグ用
  SPI.begin(); // Init SPI bus
  rfid.PCD_Init(); // Init MFRC522 
 
  //Serial.println(F("This code scan the MIFARE Classsic NUID."));
  //Serial.print(F("Using the following key:"));
 
  myservo.attach(SV_PIN);      // attaches the servo
  myservo.write(servodegree);  // deglee 180 is lock
 
}
 
void loop() {
 
  MFRC522::MIFARE_Key key; 
 
  // 開いて一定時間で自動施錠
  checktime = millis();
  if (unlocktime != 0 && unlocktime < checktime ){
      //Serial.println(unlocktime);
      //Serial.println(checktime);
      servodegree = 180;
      myservo.write(servodegree);       // deglee 180 is lock
      close_flag  = true; // 閉めたら1      
      sleeptime = unlocktime + 60000;
  }
 
  // 自動施錠した後に一定時間でスリープする
  if (sleeptime != 0 && sleeptime < checktime ){
    //Serial.println(checktime);
    //delay(3000);
    ADCSRA &= ~(1 << ADEN); // ADENビットをクリアしてADCを停止(120μA節約)
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); // パワーダウンモード
    sleep_enable();
    sleep_mode(); // ここでスリープに入る
  }
 
  // 電源を入れただけで、開錠しないまま一定時間過ぎたらスリープする。
  // 何も無かった場合、最終行のdelay 1000で1秒待機なので、300秒=5分の計算
  if(sleeptime == 0 && unlocktime == 0 && pulse_count > 300){
    ADCSRA &= ~(1 << ADEN); // ADENビットをクリアしてADCを停止(120μA節約)
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); // パワーダウンモード
    sleep_enable();
    sleep_mode(); // ここでスリープに入る
  }
 
  // 何もせずに周回した回数のカウンター
  pulse_count = pulse_count + 1;
  //Serial.println(servodegree_pulse);
 
  // 一定時間でサーボモータに電力消費を促す(0.2s * 20 = 4秒)
  if ( ! rfid.PICC_IsNewCardPresent() || ! rfid.PICC_ReadCardSerial()){
    delay(200);
    if ( pulse_count > 20 && close_flag == false){
      servodegree_pulse = 75;
      myservo.write(servodegree_pulse);
      pulse_count = 0;
      delay(500);
    } else {
      myservo.write(servodegree);
      delay(500);
    }
    return;
 }
 
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
 
  // 認証用
  // Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
 
  byte block;
  MFRC522::StatusCode status;
  byte len;
 
  // Check is the PICC of Classic MIFARE type
  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&  
    piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
    piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
    //Serial.println(F("Your tag is not of type MIFARE Classic."));
    return;
  }
 
  block = 1;
  //Serial.println(F("Authenticating using key A..."));
  status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(rfid.uid));
  if (status != MFRC522::STATUS_OK) {
    //Serial.print(F("PCD_Authenticate() failed: "));
    //Serial.println(rfid.GetStatusCodeName(status));
    return;
  }
  // else Serial.println(F("PCD_Authenticate() success: "));
 
  // RFIDの1blockを読み取るために大きい配列を定義。16+2
  byte buffer_read[18];
  char buffer_char[18];
  status = rfid.MIFARE_Read(block, buffer_read, &len);
  if (status != MFRC522::STATUS_OK) {
    //Serial.print(F("Reading failed: "));
    //Serial.println(rfid.GetStatusCodeName(status));
    return;
  }
 
  // byte型をchar型に変換してStringインスタンス作成
  strcpy((char *)buffer_char,buffer_read);
  String get_string = String(buffer_char);
 
  // 7文字を読み取って判定。OKならばサーボモータを回す。
  if(get_string.substring(0,7) == "SimSim "){
    servodegree = 80;
    myservo.write(servodegree); // deglee 90 is UNlock deglee 80 is UNlock sor Osoyoo SG90
    unlocktime = millis() + opentime;
    close_flag  = false; // 開けたらfalse
    sleeptime  = 0; // 開いたらリセット
    //Serial.print(F("unlocktime:"));
    //Serial.println(unlocktime);
  }
  //Serial.print(get_string.substring(0,7));
  //Serial.println(F("END"));
 
  // Halt PICC
  rfid.PICC_HaltA();
 
  // Stop encryption on PCD
  rfid.PCD_StopCrypto1();
 
  delay(1000); //change value if you want to read cards faster
 
}

勉強した順番に記載していこうかなと思ったけれど、まずは動くものを見たほうが良いかと思って、校正変更。

■詳細な解説

これもページを作り次第リンクを追加していく。

RFIDのサンプルで苦労したこと

別の投稿記事に変更。先人のサンプルの調査をしただけだったんで。
RFIDのサンプルスケッチでの発見

■実装を見送った技術、失敗録