RFIDの識別にUIDを使おうと思いArduino側のEEPROMへの読み書きにて実装したこと
これは、最初に実装したスケッチなんだけれど、「さーて、開いたり閉じたりできたから、RFIDタグを複製するか」と次の段階に移ろうとしたらUID部分が複製不可能(高価なRFIDタグならできる)ということが分かったので没にしたもの。
EEPROMというのはArduinoが持っている領域で、プログラムを書き込むのとは違うところ。
読み書き込みできるスケッチを別途用意して、Arduinoの領域にOKなRFIDのUIDを書き込んでみた。
よく考えれば、UIDを書き換えるたびにArduinoのスケッチを書き換えないとだめなので、最初から実装に無理あったかも
/* シリアル出力を抑制
* --------------------------------------------------------------------------------------------------------------------
* 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 <EEPROM.h>
#include <Servo.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
struct MyObject {
byte field1;
byte field2;
byte field3;
byte field4;
};
MyObject customVar; //Variable to store custom object read from EEPROM.
//
int pos = 0; // variable to store the servo position
Servo myservo; // create servo object to control a servo
//
//unsigned long opentime = 300000; //
//unsigned long opentime = 30000; // 30秒
unsigned long opentime = 1800000; // 30分
unsigned long unlocktime = 0; // 開錠した時間
unsigned long checktime = 0; // 経過秒数
int servodegree = 180; // 自動電源OFFのために電力調節
int servodegree_pulse = 180; // 自動電源OFFのために電力調節 開錠時の一時角度
int pulse_count = 0; // 自動電源OFFのために電力調節
boolean close_flag = true; // 閉めたことを記録 true = 閉めた。false = 開いた
// Init array that will store new NUID
byte nuidPICC[4];
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:"));
int eeAddress = 0;
EEPROM.get(eeAddress, customVar);
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
}
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);
// 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;
}
if (rfid.uid.uidByte[0] != customVar.field1 ||
rfid.uid.uidByte[1] != customVar.field2 ||
rfid.uid.uidByte[2] != customVar.field3 ||
rfid.uid.uidByte[3] != customVar.field4 ) {
//
//Serial.println(F("A new card has been detected."));
//Serial.println(F("The NUID tag is:"));
//Serial.print(F("In hex: "));
//Serial.println();
}
else {
servodegree = 80;
myservo.write(servodegree); // deglee 90 is UNlock deglee 80 is UNlock sor Osoyoo SG90
unlocktime = millis() + opentime;
close_flag = false; // 開けたらfalse
//Serial.print(F("unlocktime:"));
//Serial.println(unlocktime);
}
// Halt PICC
rfid.PICC_HaltA();
// Stop encryption on PCD
rfid.PCD_StopCrypto1();
delay(1000); //change value if you want to read cards faster
} |
/* シリアル出力を抑制
* --------------------------------------------------------------------------------------------------------------------
* 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 <EEPROM.h>
#include <Servo.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
struct MyObject {
byte field1;
byte field2;
byte field3;
byte field4;
};
MyObject customVar; //Variable to store custom object read from EEPROM.
//
int pos = 0; // variable to store the servo position
Servo myservo; // create servo object to control a servo
//
//unsigned long opentime = 300000; //
//unsigned long opentime = 30000; // 30秒
unsigned long opentime = 1800000; // 30分
unsigned long unlocktime = 0; // 開錠した時間
unsigned long checktime = 0; // 経過秒数
int servodegree = 180; // 自動電源OFFのために電力調節
int servodegree_pulse = 180; // 自動電源OFFのために電力調節 開錠時の一時角度
int pulse_count = 0; // 自動電源OFFのために電力調節
boolean close_flag = true; // 閉めたことを記録 true = 閉めた。false = 開いた
// Init array that will store new NUID
byte nuidPICC[4];
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:"));
int eeAddress = 0;
EEPROM.get(eeAddress, customVar);
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
}
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);
// 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;
}
if (rfid.uid.uidByte[0] != customVar.field1 ||
rfid.uid.uidByte[1] != customVar.field2 ||
rfid.uid.uidByte[2] != customVar.field3 ||
rfid.uid.uidByte[3] != customVar.field4 ) {
//
//Serial.println(F("A new card has been detected."));
//Serial.println(F("The NUID tag is:"));
//Serial.print(F("In hex: "));
//Serial.println();
}
else {
servodegree = 80;
myservo.write(servodegree); // deglee 90 is UNlock deglee 80 is UNlock sor Osoyoo SG90
unlocktime = millis() + opentime;
close_flag = false; // 開けたらfalse
//Serial.print(F("unlocktime:"));
//Serial.println(unlocktime);
}
// Halt PICC
rfid.PICC_HaltA();
// Stop encryption on PCD
rfid.PCD_StopCrypto1();
delay(1000); //change value if you want to read cards faster
}
初期化するところでEEPROMから読み込み
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:"));
int eeAddress = 0;
EEPROM.get(eeAddress, customVar);
myservo.attach(SV_PIN); // attaches the servo
myservo.write(servodegree); // deglee 180 is lock
} |
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:"));
int eeAddress = 0;
EEPROM.get(eeAddress, customVar);
myservo.attach(SV_PIN); // attaches the servo
myservo.write(servodegree); // deglee 180 is lock
}
判定はこの部分。
if (rfid.uid.uidByte[0] != customVar.field1 ||
rfid.uid.uidByte[1] != customVar.field2 ||
rfid.uid.uidByte[2] != customVar.field3 ||
rfid.uid.uidByte[3] != customVar.field4 ) { |
if (rfid.uid.uidByte[0] != customVar.field1 ||
rfid.uid.uidByte[1] != customVar.field2 ||
rfid.uid.uidByte[2] != customVar.field3 ||
rfid.uid.uidByte[3] != customVar.field4 ) {
EEPROMを書き換えるスケッチ
/***
eeprom_put example.
This shows how to use the EEPROM.put() method.
Also, this sketch will pre-set the EEPROM data for the
example sketch eeprom_get.
Note, unlike the single byte version EEPROM.write(),
the put method will use update semantics. As in a byte
will only be written to the EEPROM if the data is actually
different.
Written by Christopher Andrews 2015
Released under MIT licence.
***/
#include <EEPROM.h>
struct MyObject {
byte field1;
byte field2;
byte field3;
byte field4;
};
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
int eeAddress = 0; //Location we want the data to be put.
/** Put is designed for use with custom structures also. **/
//Data to store.
MyObject customVar = {
0x90,
0xCF,
0x39,
0x83
};
EEPROM.put(eeAddress, customVar);
Serial.print("Written custom data type! \n\nView the example sketch eeprom_get to see how you can retrieve the values!");
}
void loop() {
/* Empty loop */
} |
/***
eeprom_put example.
This shows how to use the EEPROM.put() method.
Also, this sketch will pre-set the EEPROM data for the
example sketch eeprom_get.
Note, unlike the single byte version EEPROM.write(),
the put method will use update semantics. As in a byte
will only be written to the EEPROM if the data is actually
different.
Written by Christopher Andrews 2015
Released under MIT licence.
***/
#include <EEPROM.h>
struct MyObject {
byte field1;
byte field2;
byte field3;
byte field4;
};
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
int eeAddress = 0; //Location we want the data to be put.
/** Put is designed for use with custom structures also. **/
//Data to store.
MyObject customVar = {
0x90,
0xCF,
0x39,
0x83
};
EEPROM.put(eeAddress, customVar);
Serial.print("Written custom data type! \n\nView the example sketch eeprom_get to see how you can retrieve the values!");
}
void loop() {
/* Empty loop */
}
このMyObject customVarの値を書き換えて実行するというもの。
EEPROMを読みだすスケッチ
/***
eeprom_get example.
This shows how to use the EEPROM.get() method.
To pre-set the EEPROM data, run the example sketch eeprom_put.
This sketch will run without it, however, the values shown
will be shown from what ever is already on the EEPROM.
This may cause the serial object to print out a large string
of garbage if there is no null character inside one of the strings
loaded.
Written by Christopher Andrews 2015
Released under MIT licence.
***/
#include <EEPROM.h>
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Read float from EEPROM: ");
/***
As get also returns a reference to 'f', you can use it inline.
E.g: Serial.print( EEPROM.get( eeAddress, f ) );
***/
/***
Get can be used with custom structures too.
I have separated this into an extra function.
***/
secondTest(); //Run the next test.
}
struct MyObject {
byte field1;
byte field2;
byte field3;
byte field4;
};
void secondTest() {
int eeAddress = 0;
MyObject customVar; //Variable to store custom object read from EEPROM.
EEPROM.get(eeAddress, customVar);
Serial.println("Read custom object from EEPROM: ");
Serial.print(customVar.field1,HEX);
Serial.print(customVar.field2,HEX);
Serial.print(customVar.field3,HEX);
Serial.print(customVar.field4,HEX);
}
void loop() {
/* Empty loop */
} |
/***
eeprom_get example.
This shows how to use the EEPROM.get() method.
To pre-set the EEPROM data, run the example sketch eeprom_put.
This sketch will run without it, however, the values shown
will be shown from what ever is already on the EEPROM.
This may cause the serial object to print out a large string
of garbage if there is no null character inside one of the strings
loaded.
Written by Christopher Andrews 2015
Released under MIT licence.
***/
#include <EEPROM.h>
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Read float from EEPROM: ");
/***
As get also returns a reference to 'f', you can use it inline.
E.g: Serial.print( EEPROM.get( eeAddress, f ) );
***/
/***
Get can be used with custom structures too.
I have separated this into an extra function.
***/
secondTest(); //Run the next test.
}
struct MyObject {
byte field1;
byte field2;
byte field3;
byte field4;
};
void secondTest() {
int eeAddress = 0;
MyObject customVar; //Variable to store custom object read from EEPROM.
EEPROM.get(eeAddress, customVar);
Serial.println("Read custom object from EEPROM: ");
Serial.print(customVar.field1,HEX);
Serial.print(customVar.field2,HEX);
Serial.print(customVar.field3,HEX);
Serial.print(customVar.field4,HEX);
}
void loop() {
/* Empty loop */
}
説明いらないと思うけれど、EEPROMの領域を読みだすっていうもの。