// Source : http://tronixstuff.com/2013/11/19/arduino-tutorials-chapter-15-rfid/ // with just a mod to print the tag nb before "Accepted"/"Rejected" #include #include #include //Configuration const float SERVO_SPEED = 0.8; const float OPEN_ANGLE = 10.0; const float CLOSED_ANGLE = 160.0; //Pin definitions #define RED_LED 12 #define GREEN_LED 13 #define RFID_RX 2 #define RFID_TX 3 #define PROG_BUTTON 4 #define SERVO_CTRL 5 #define DOOR_BUTTON 6 #define IR_LED 7 #define IR_RECEIVE A0 // Others parameters #define SERVO_PWR_TIME 500 //time to stop powering servomotor after the end of move #define DOOR_OPENED_TIME 3000 #define IR_DETECTION_THRESHOLD 100 #define EMPTY_TAG {0,0,0,0,0,0,0,0,0,0,0,0,0,0} #define UNWRITTEN_TAG {255,255,255,255,255,255,255,255,255,255,255,255,255,255} //Globals declarations SoftwareSerial RFID(RFID_RX, RFID_TX); // RX and TX Servo door_servo; int data1 = 0; int tag_ok = -1; float servo_pos = OPEN_ANGLE; bool door_state = 0; // door opened ? bool door_move = false; // door moving ? long door_timer = 0; // timer to close the door long servo_timer = 0; //timer to stop powering servomotor long red_led_timer = 0; //byte tag1[14] = {2,52,54,48,48,57,49,48,57,56,48,53,69,3}; byte newtag[14] = EMPTY_TAG; // used for read comparisons const byte emptytag[14] = EMPTY_TAG; const byte unwrittentag[14] = UNWRITTEN_TAG; byte * readeepromtag(short tagnb=0) { // Read the n-th RFID tag in EEPROM //First check if the # of tag is out of the capacity of EEPROM //Return an null tag if so. if ((tagnb+1)*14 > EEPROM.length()) { Serial.print(F("Error: Tag Nb to high : ")); Serial.println(tagnb); byte tag[14] = EMPTY_TAG; return tag; } byte tag[14] = EMPTY_TAG; for (int i=0; i<14; i++) { tag[i]=EEPROM.read(i + tagnb*14); //delay(1); //small delay to avoid misreading } //Serial.print(F("Tag nb ")); //Serial.print(tagnb); //Serial.print(F(" : ")); //for (int z = 0; z < 14 ; z++) { // Serial.print(tag[z]); // Serial.print(","); //} //Serial.println(""); delay(2); //small delay to avoid misreading return tag; } int maxeepromtags() { // Return maximum number of tag that can be stored in EEPROM return EEPROM.length() / 14; } boolean comparetag(byte taga[14], byte tagb[14]) { // Compare two RFID tag int x = 0; for (int i = 0 ; i < 14 ; i++) { if (taga[i] == tagb[i]) x++; } return (x == 14); } int findtag(byte searchtag[14]) { //Find a given tag in EEPROM byte *tag; for (int i=0; i < maxeepromtags(); i++) { tag = readeepromtag(i); if (comparetag(tag, searchtag)) return i; } return -1; } void tagOK() { if (digitalRead(PROG_BUTTON)) { for (int z = 0; z < 14 ; z++) { Serial.print(newtag[z]); Serial.print("."); } Serial.println(F(" : Accepted")); if (!door_state) { Serial.println(F("Ouverture...")); door_state = 1; door_timer = millis() + DOOR_OPENED_TIME; } } else { delTag(newtag); } } void tagNoOK() { if (digitalRead(PROG_BUTTON)) { for (int z = 0; z < 14 ; z++) { Serial.print(newtag[z]); Serial.print("."); } Serial.println(F(" : Rejected")); digitalWrite(RED_LED, HIGH); //Light the red LED for 1s red_led_timer = millis() + 1000; } else { addNewTag(newtag); } } void readRFID() { tag_ok = 0; delay(100); // time for the data to come in from the serial buffer. //Check up to 3 times if rejected to avoid mistake for (byte i=0; i<3; i++) { // read tag numbers for (byte z = 0 ; z < 14 ; z++) // read the rest of the tag { data1 = RFID.read(); newtag[z] = data1; } RFID.flush(); // stops multiple reads // do the tag exist in EEPROM if (findtag(newtag) >= 0) tag_ok=1; if (tag_ok>0) break; } //Check if the tag is not an error before doing anything if (!comparetag(newtag, unwrittentag)) { // now do something based on tag type if (tag_ok > 0) tagOK(); else tagNoOK(); } // empty the data cache while (RFID.available()) { RFID.read(); } } void disableServo() { //Disable servomotor once they stop moving if (!door_move and servo_timer < millis() and door_servo.attached()) { door_servo.detach(); Serial.println(F("Servo disabled")); } } void updateDoor() { //Check if the need to move and move it //Apply door status if (door_state) { //Opening or open if (servo_pos <= OPEN_ANGLE) { //if door has to be open and already open, disable servomotor if (door_move) { //Opening Serial.println(F("Door : opened")); door_timer = millis() + DOOR_OPENED_TIME; servo_timer = millis() + SERVO_PWR_TIME; disableServo(); door_move = false; } } else { //Keep opening the door door_move = true; servo_pos -= SERVO_SPEED; door_servo.attach(SERVO_CTRL); door_servo.write(servo_pos); //Serial.print(F("Door : opening ")); //Serial.println(servo_pos); } //Check opened-door timer if (millis() < door_timer) { //Serial.print(F("Door timer :")); //Serial.println(door_timer - millis()); } else if (!door_move) { door_state = 0; } } else { if (servo_pos >= CLOSED_ANGLE) { //if door has to be open and already open, disable servomotor disableServo(); if (door_move) { Serial.println(F("Door : closed")); servo_timer = millis() + SERVO_PWR_TIME; disableServo(); door_move = false; } } else { //Keep closing the door door_move = true; servo_pos += SERVO_SPEED; door_servo.attach(SERVO_CTRL); door_servo.write(servo_pos); //Serial.print(F("Door : closing ")); //Serial.println(servo_pos); } } } void updateLED() { //Update the LEDs state if (door_state) { //Opening or open digitalWrite(GREEN_LED, HIGH); digitalWrite(RED_LED, LOW); } else { digitalWrite(GREEN_LED, LOW); digitalWrite(RED_LED, LOW); } //Check the redLED timer and turn ON or OFF the LED if (millis() < red_led_timer) { digitalWrite(RED_LED, HIGH); // Serial.print(F("Red LED timer : ")); // Serial.println(red_led_timer - millis()); } else digitalWrite(RED_LED, LOW); } void addNewTag(byte tag[14]) { Serial.print(F("Adding new tag to EEPROM : ")); for (int z = 0; z < 14 ; z++) Serial.print(tag[z]); Serial.println(""); //Find first empty or unwritten space in EEPROM int tagnb = findtag(emptytag); if (tagnb < 0){ Serial.println(F("No empty space found.")); tagnb = findtag(unwrittentag); if (tagnb < 0) { Serial.println(F("No unwritten space found either. Can't save more tag.")); for (int i=0; i<4; i++) { digitalWrite(RED_LED, HIGH); delay(500); digitalWrite(RED_LED, LOW); delay(500); } return -1; } } Serial.print(F("New tag number : ")); Serial.println(tagnb); Serial.print(F("Writing...")); for (int z = 0; z < 14 ; z++) { EEPROM.write(z+(tagnb*14), tag[z]); } Serial.print(F(" Checking...")); int tmp = findtag(tag); if (tmp != -1 and tmp == tagnb) { Serial.println("OK"); for (int i=0; i<3; i++) { digitalWrite(GREEN_LED, HIGH); delay(500); digitalWrite(GREEN_LED, LOW); delay(500); } } else { Serial.println("Failed"); for (int i=0; i<5; i++) { digitalWrite(RED_LED, HIGH); delay(500); digitalWrite(RED_LED, LOW); delay(500); } } } void delTag(byte tag[14]) { Serial.print(F("Deleting tag from EEPROM : ")); for (int z = 0; z < 14 ; z++) { Serial.print(tag[z]); } Serial.println(""); int tagnb = findtag(tag); Serial.print(F("Tag number ")); Serial.println(tagnb); Serial.print(F("Writing zeros...")); for (int z = 0; z < 14 ; z++) { EEPROM.write(z+(tagnb*14), 0); } Serial.print(F(" Checking...")); int tmptag = readeepromtag(tagnb); if (comparetag(tmptag, emptytag)) { Serial.println("OK"); digitalWrite(GREEN_LED, HIGH); delay(500); digitalWrite(GREEN_LED, LOW); delay(500); } else { Serial.println("Failed"); for (int i=0; i<5; i++) { digitalWrite(RED_LED, HIGH); delay(500); digitalWrite(RED_LED, LOW); delay(500); } } } boolean catIsHere() { int IR_ambient; // variable to store the IR coming from the ambient int value; // variable to store the IR values for (int i=0; i<5; i++) { digitalWrite(IR_LED, LOW); delay(1); IR_ambient = analogRead(IR_RECEIVE); digitalWrite(IR_LED, HIGH); delay(1); value += IR_ambient - analogRead(IR_RECEIVE); } Serial.println(value); digitalWrite(IR_LED, LOW); if (value < IR_DETECTION_THRESHOLD) { Serial.println(F("Chat présent")); return true; } Serial.println(F("Chat absent")); return false; } void setup() { // start serial to PC Serial.begin(115200); // start serial to RFID reader RFID.begin(9600); // empty the data cache while (RFID.available()) { RFID.read(); } // for status LEDs pinMode(GREEN_LED, OUTPUT); pinMode(RED_LED, OUTPUT); pinMode(IR_LED, OUTPUT); digitalWrite(IR_LED, LOW); //Mode for button and end-stop pinMode(PROG_BUTTON, INPUT_PULLUP); pinMode(DOOR_BUTTON, INPUT_PULLUP); Serial.print(F("EEPROM length : ")); Serial.print(EEPROM.length()); Serial.print(F(" bytes (")); Serial.print(maxeepromtags()); Serial.println(F(" tags)")); Serial.println(findtag(newtag)); Serial.println(findtag(unwrittentag)); //Positioning door while (!door_move) { updateDoor(); } door_state = 0; } void loop() { tag_ok = -1; if (!door_state and !door_move and RFID.available() > 0 ) { readRFID(); } if (!digitalRead(DOOR_BUTTON)) { Serial.println("Ouverture par l'utilisateur."); door_state = 1; door_servo.attach(SERVO_CTRL); door_servo.write(OPEN_ANGLE); delay(1000); while (digitalRead(DOOR_BUTTON)) { delay(50); } door_servo.write(CLOSED_ANGLE); delay(1000); Serial.println("Fermeture par l'utilisateur."); door_state = 0; } if (door_state and !door_move and catIsHere()) { door_timer = millis() + DOOR_OPENED_TIME; } updateDoor(); updateLED(); delay(10); }