Cat door visitor authorization RFID system

Long title that could be shorter? Indeed!

This is the start of my locking cat door, where only my cat should be able to get through.
The project includes

  • 1x Arduino Duemilanove
  • 1x 125KHz RFID module
  • 1x 125HKz RFID tag
  • 1x Cheap servo
  • 1x Cat door with a manual lock
  • 1 (or more)x Cat
  • 1x Reed switch
  • 1x Magnet

This is the first step… The code to handle the tag reading and move the servo.

My plan is to move the servo into the lock position when the program starts up. It will then update the servo for two seconds, to make sure it is in the right position. After the two seconds have passed, it will stop telling the servo to move to a position. This is both to save power, and it isn’t needed to tell the servo to move to the same position all the time when there are no load on it.

When a tag is hold over the reader it opens, if the tag is valid, and again updates the servo for two seconds and waits 5 seconds. When those 5 seconds is passed, it will start looking for the door, this is where the reed switch come in. The reed switch is mounted under the door, and the magnet holding the door shut will trigger it. This will tell the Arduino that the door is closed, and the servo can move back to the locking position.

But! When my cat goes through, he just lets the door fall (that bastard!!!) making it swing back and forth a few times before the magnet stops it. To make up for that, I made the Arduino check how long the reed switch have been activated. To move the servo back to the lock position, the door must have been closed for 1000 milliseconds, otherwise it will just wait until it is closed, and then return the servo to the lock position.

int DOOR_LOCKED = 0; // 0-180
int DOOR_UNLOCKED = 90; // 0-180
long interval = 5000; //How long the doorwill stay unlocked
const int doorReed = 2;     // the number of the pushbutton pin
const int ledPin = 13;     // the number of the led pin

boolean locked = true;
boolean led = false;

#include <SoftwareServo.h>
SoftwareServo myservo;  // create servo object to control a servo

#include <WString.h>
#include <NewSoftSerial.h>

NewSoftSerial RFID(5, 6);
String msg = String(60);
String ID = String(60);  //string to store allowed cards

long previousMillis = 0; //Store when the door got unlocked
long previousServo = 0; //Store when servo was last set
long previousLED = 0; //Store when servo was last set
long doorClosed = 0; //Store when servo was last set
String temp = "";

long runServo = 0; //Store when servo was started

boolean debug = true;

void setup()
{
  ID.append("3A008602358B");

  myservo.attach(7);  // attaches the servo on pin 4 to the servo object
  pinMode(doorReed, INPUT);
  pinMode(ledPin, OUTPUT);

  Serial.begin(9600);
  if (debug) Serial.println("Serial Ready");

  RFID.begin(9600);
  if (debug) Serial.println("RFID Ready");

  setServo(DOOR_LOCKED); //Move the servo to the locked position
}

char c;

void loop()
{
  if (!locked)
  {
    if(millis() - previousMillis < interval)
    {
      digitalWrite(ledPin, HIGH);
    }
    else
    {
      if (millis() - previousLED >= 1000)
      {
        previousLED = millis();
        if (!led)
        {
          digitalWrite(ledPin, HIGH);
          led = true;
        }
        else
        {
          digitalWrite(ledPin, LOW);
          led = false;
        }
      }
    }
  }
  else
  {
    digitalWrite(ledPin, LOW);
    led = false;
  }

  if (!locked && !digitalRead(doorReed))
  {
    doorClosed = millis();
  }

  if (!locked && digitalRead(doorReed)) //If it is unlocked, and the switch at the bottom at the door is pulled
  {
    if(millis() - previousMillis >= interval && millis() - doorClosed >= 1500) //Lock after being unlocked the amount of time defined by interval, and that the door has been closed for 1.5 seconds so it wont lock on a swing by
    {
      locked = true; //Change it back to locked
      setServo(DOOR_LOCKED); //Move the servo to the locked position
    }
  }

  while(RFID.available() > 0)
  {
    c=RFID.read();
    msg.append(c);
  }

  if (msg.length() >= 12)
  {
    verify(); //Validate the ID
  }

  msg=""; //Empty the message
  temp = ""; //Empty the string holding the ID temp

  if(millis() - previousServo > 50 && millis() - runServo < 2000) //Check if it is time to set the servo position again, but only for two seconds
  {
    previousServo = millis();
    SoftwareServo::refresh();
  }
}

void verify()
{
  int length = msg.length();
  for (int i=0; i <= length; i++) //Run through the string
  {
    if (byte(msg.charAt(i)) >= 32) //Check if the char is more, or 32 byte
    {
      temp.append(msg.charAt(i)); //Add it to the temp message holding the ID
    }
  }

  if (debug) Serial.println(temp);

  if(ID.contains(temp))
  {
    if (debug) Serial.println("> Access granted.");
    setServo(DOOR_UNLOCKED); //Move the servo to the unlocked position
    locked = false;
    previousMillis = millis();
  }
}

void setServo(int pos)
{
  runServo = millis();
  myservo.write(pos);
}

Hardware

The RFID tags

Blue one for Tom (my first cat)

Red for the new female (not got it yet)

Locking mechanism

Version 1.0

I am going to add a servo to keep the cats in at night too, for that I designed this little device.

This is going to be mounted under the cat door, and the little arm will then sving up to keep them in.

Version 1.1

Added so both ingoing and outgoing servo is mounted on the same, plus added 0.875mm thick double sided tape to hold the servo motors to the plate.

Leave a Reply