いつもChromeのタブを20-30ほど開いているばっしーです。
しかも会社の非力なWindows7 32bitマシンで・・・ツライとです・・・。
ネタが古いですね。失礼しました。
おかげで、大好きなAliexpressを開いていたタブがたまにメモリ不足で落ちてしまいます。こんちくしょー!
ってのは置いておいて。
先日、Aliで購入したRFIDユニットが届いたので、早速Arduinoで使ってみました。
とりあえずUIDを認識させたかったので、それがゴールです。
まずはRFIDユニット(RC522)を配線
Arduinoにはお気に入りのESP-EROOM-02(ESP8266)Deveropment Boardを使用します。
先人の知恵を色々とWeb徘徊して調べてみましたが、ちょっとわからない点が残りましたので後述します。
配線
以下の様にしました。
RC522 | === | 8266 |
SDA | === | GPIO 2 |
SCK | === | GPIO 14 |
MOSI | === | GPIO 13 |
MISO | === | GPIO 12 |
IRQ | === | N/A |
GND | === | GND |
RST | === | GPIO 16 |
3.3V | === | 3.3V |
不明点というのは、以下のソースコードを見ればわかるのですが、GPIOを定義しているのは、SDAとRSTの2つだけなんです。シリアル通信に使っていると思われる12~14をソースコードで定義していないんです。それなのになぜ通信ができるか不思議です…
ブレッドボード
RFIDユニットの他に、OLEDとLED、プッシュボタンを配置してみました。
これで8266のGPIOはすべて使い果たしてしまいました。
ソースコード
以下がソースコードです。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <ESP_Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 16
#define SS_PIN 2
#define COM_PIN 15
#define LED_PIN 0
int wait;
MFRC522 rfid(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
byte nuidPICC[4];
void setup() {
pinMode(LED_PIN,OUTPUT) ;
pinMode(COM_PIN,INPUT) ;
Wire.begin(5,4); // (SDA,SCL):ESP8266(IO_0)-OLED(SDA),(IO_1)-OLED(SCL)
display.begin(SSD1306_SWITCHCAPVCC, 0x78>>1); // OLED ADDRESS
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Scan KEY:");
display.display();
Serial.begin(9600);
SPI.begin(); // Init SPI bus
rfid.PCD_Init(); // Init MFRC522
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
Serial.println(F("This code scan the MIFARE Classsic NUID."));
Serial.print(F("Using the following key:"));
printHex(key.keyByte, MFRC522::MF_KEY_SIZE);
}
void loop() {
if ( ! rfid.PICC_IsNewCardPresent())
return;
if ( ! rfid.PICC_ReadCardSerial())
return;
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
Serial.println(rfid.PICC_GetTypeName(piccType));
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;
}
if (rfid.uid.uidByte[0] == nuidPICC[0] &&
rfid.uid.uidByte[1] == nuidPICC[1] &&
rfid.uid.uidByte[2] == nuidPICC[2] &&
rfid.uid.uidByte[3] == nuidPICC[3] ) {
Serial.println(F("This card is Corret!"));
for (byte i = 0; i < 4; i++) {
nuidPICC[i] = rfid.uid.uidByte[i];
}
Serial.println(F("The NUID tag is:"));
Serial.print(F("In hex: "));
printHex(rfid.uid.uidByte, rfid.uid.size);
Serial.println();
Serial.print(F("In dec: "));
printDec(rfid.uid.uidByte, rfid.uid.size);
Serial.println();
display.clearDisplay();
display.setCursor(0,0);
display.println("This card is Corret!");
display.display(); display.print("UID No:");
display.print(rfid.uid.uidByte[0],HEX);
display.print(" ");
display.print(rfid.uid.uidByte[1],HEX);
display.print(" ");
display.print(rfid.uid.uidByte[2],HEX);
display.print(" ");
display.println(rfid.uid.uidByte[3],HEX);
display.display();
digitalWrite(LED_PIN,HIGH) ; //LEDを点灯
}
else{
Serial.println(F("The NUID tag is:"));
Serial.print(F("In hex: "));
printHex(rfid.uid.uidByte, rfid.uid.size);
Serial.println();
Serial.print(F("In dec: "));
printDec(rfid.uid.uidByte, rfid.uid.size);
Serial.println();
display.clearDisplay();
display.setCursor(0,0);
display.print("UID No:");
display.print(rfid.uid.uidByte[0],HEX);
display.print(" ");
display.print(rfid.uid.uidByte[1],HEX);
display.print(" ");
display.print(rfid.uid.uidByte[2],HEX);
display.print(" ");
display.println(rfid.uid.uidByte[3],HEX);
display.display();
digitalWrite(LED_PIN,LOW); //LEDを消灯
wait = 0;
while(wait<2000){
if (digitalRead(COM_PIN) == HIGH) {//スイッチが押されているならKEY登録
for (byte i = 0; i < 4; i++) {
nuidPICC[i] = rfid.uid.uidByte[i];
}
display.println("Detected new card!");
display.display();
delay(2000);
display.clearDisplay();
display.setCursor(0,0);
display.println("Scan KEY:");
display.display();
break;
}
wait++;
delay(1);
if((wait/200)/2*2 == (wait/200)){
digitalWrite(LED_PIN,LOW); //LEDを消灯
}else{
digitalWrite(LED_PIN,HIGH); //LEDを点灯
}
}
}
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
}
void printHex(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
void printDec(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], DEC);
}
}
動作の模様
とりあえず完成したので、動作の様子を撮影してみました。
鍵を開ける動作をイメージして試作してみました。
RFIDを読み取るとUIDをOLEDに表示します。
LEDが点滅している間にボタンを押すとキーとして登録します。
キーの登録後はキーのRFIDを読み取るとLEDが点灯したままになり、開錠されたイメージとなります。
キー以外のRFIDを読み取るとLEDが点滅し、キー登録できる状態となります。
動画
コメント