Code writing for RFID controled pet doors project.

Hi,
I'm quite new player in arduino playground, and I come here, to get new ideas from more experienced people.
Now I'm working with RFID pet doors project, in my mind it should work like that - RFID reader receive the signal from the RFID tag, servo motor open doors for ten or more seconds, then check or there are no more RFID tag signals around reader, close the doors.

I have written the code which i think looks terrible. :smiley:

#include <SoftwareSerial.h>
#include <Servo.h>
#include <SPI.h>
SoftwareSerial RFID(2, 3); // RX and TX
 
int i;

Servo myservo;
void allow();
void setup()
{
  myservo.attach(3);
  RFID.begin(9600);    // start serial to RFID reader
  Serial.begin(9600);  // start serial to PC
  SPI.begin();
  myservo.write(90); 
}
 
void loop()
{
  if (RFID.available() > 0) 
  {
     i = RFID.read();
     Serial.print("found ");
     for (i = 0; i < 2; i++);
     {
      if (i > 0)
        {
          allow();
        }
     }
  }
}
void allow()
{
  Serial.println("open");
 myservo.write(180);
 delay(200);
 myservo.write(90);
 
 
}

now it receive the signal ant servo turning around again and again till the tag are near the reader, and then if reader did not receive tag signal any more, then servo stops. If this code would be realised on the real pet doors model, it will break the doors or servo.

So questions.

1 - where is the bigest mistakes in my code?
2 - how to write code that servo will react only in the first rfid tag signal and then start turning for some time? Because now it receive the signal and turn then again receive the signal and turn
3 - where should be writed doors closing code line?

I'm using modified servo for continuous rotating, rdm6300 125kHz rfid, and Arduino Uno Rev3.

Thanks, I'm waiting your answers.

If i make something wrong in this post, just tell me, i will modify it.

What board are you using?

Also, you don't seem to set an initial position for the servo, You then move it to 180 degrees, and wait for 200 milliseconds. Wow that's a fast cat, then close it...

Have you tested any of your code with a tag?

I also notice that you are not checking for which tag. I presume that it is only meant to open for your pets?

then check or there are no more RFID tag signals around reader

This indicates that you don't understand how an RFID reader works. An RFID reader will read a tag when it is presented, but it will NOT tell you when the tag goes away nor will it tell you if the tag is still there.

You need some other method, typically a ping sensor or PIR sensor to tell you whether the animal is still there.

I have written the code which i think looks terrible.

You are quite right.

  if (RFID.available() > 0) 
  {
     i = RFID.read();
     Serial.print("found ");
     for (i = 0; i < 2; i++);
     {
      if (i > 0)
        {
          allow();
        }

Reading one byte from the tag, and then immediately throwing that value away makes no sense. The RFID tag value is many bytes long.

A for loop that iterates twice, and does something only on one of those iterations just plain looks stupid.\

Calling the function for no good reason, as your are now, will just result in a fat pet.

Actually, I guess that depends on exactly what the servo is controlling. Opening something for 2/10ths of a second is going to result in an animal biting you, unless that something simply dumps food for that period of time.

You WILL need to deal with the animal coming by and expecting to be fed as often as it comes by.

Ok, after I read the answers, I felt completely stupid, on arduino. :smiley:

ChilliTronix:
What board are you using?

Also, you don't seem to set an initial position for the servo, You then move it to 180 degrees, and wait for 200 milliseconds. Wow that's a fast cat, then close it...

Have you tested any of your code with a tag?

I also notice that you are not checking for which tag. I presume that it is only meant to open for your pets?

I'm using arduino uno rev3 board, and rdm6300 125khz rfid module. Servo is modified for continiuous rotation, 0 means rotate clocwise, 90 stoped, 180 counterclockwise. I used 200 miliseconds, because rfid module receives a lot of signals with one tag move near rfid receiver antenna, and with every signal servo turns 200ms, this delay it is only for testing. Code are tested with tag. Which tag it is not necessary for me, now.

This indicates that you don't understand how an RFID reader works. An RFID reader will read a tag when it is presented, but it will NOT tell you when the tag goes away nor will it tell you if the tag is still there.

You need some other method, typically a ping sensor or PIR sensor to tell you whether the animal is still there.

It will be doors only for walking inside and outside, not a automated pet feeder, so i think it would be possible to make project without ping or pir sensor. rfid receive a signal open the doors, when doors fully opened starting time delay, after time delay ends, doors starts to closing, but if rfid receive signal, doors stops closing, and it opens again and also again starting time delay. I understand that rfid will not tell when tag goes away, system just close the doors, and waiting next signal. Is it right like i'm thinking? and it would be possible to realize? So i think my writed code are completely rubbish, and i should start from zero.

I used 200 miliseconds, because rfid module receives a lot of signals with one tag move near rfid receiver antenna

Which RFID reader do you have? It is unusual for an RFID reader to send the same tag over and over. The tag, though, is NOT a single byte, as your code assumed.

So i think my writed code are completely rubbish, and i should start from zero.

Well, now, there's something we can agree on. Start with reading a complete tag. Understand what "a complete tag" means.

Then, you do NOT want to open the door for just any tag. Only the tag(s) that belong to your pet(s) should trigger the door to open.

Start with finding some simple code that will read the whole tag. There are some around I found with google a long time ago.

Read a tag and get it over a serial monitor. Record the tag that you want to respond to (I presume that you don't want the door open for any pet) and then once you can read a tag, you can compare it to the desired one, and if it matches, operate the servo.

May I also suggest using a regular servo rather than continuous since you want the door open or closed. However, that may require a very powerful servo.

PaulS:
Reading one byte from the tag, and then immediately throwing that value away makes no sense. The RFID tag value is many bytes long.

This also leaves the unread bytes in the buffer to appear as false positive readings on later itterations of the loop.

ok, guys, i decide to make this project a little differently, and use dc motors, i found suitable code and I changed code that alow it to work with L293D bridge, but now i trying to introduce HC-SR04 range sensor, and i made something wrong. So maybe someone could help me with this code and try to explain where is the mistake? In the original code was used Sharp GP2D120 IR sensor, so now i want to introduce HC-SR04 in its place.

Edited:
algorithm looks like that. There are two opening/closing modes, manual and automatic, these modes are controled by the swithc. if automatic, dc starts turning and opening doors till doors push 1 button (opened doors sensor), then if closed doors button LOW range sensor cheking pet, if there are no pets, after few seconds doors starts to closing till push 2 button (closed doors sensor). if in opened doors range sensor capture pet, DC do not receiv the signal to start doors closing. In manual mode if pushed 3 button (manual open/close button) dc starts till doors push the 1 button, then push 3 button again and starting doors closing.

Now model works like without range sensor, just open doors till push 1 button, then after few seconds close the doors tll push 2 button, and loop repeats.

const int trigPin=13;
const int echoPin=12;
const int DOORSENSOR_OPEN=5;//input
const int DOORSENSOR_CLOSED=6;//input
const int MANUALMODE_pin=7;//input
const int MANUALOPEN_pin=8;//input
const int OPEN=1;
const int CLOSE=0;
int door_state;
int val;       // variable to store the value coming from the IR sensor
int motorpin1 = 3;                  //define digital output pin no.
int motorpin2 = 4;
//IR emitter is always on (5V)




void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Motor test!");
  digitalWrite(14, LOW);
  digitalWrite(15, LOW);
  digitalWrite(16, LOW);
  digitalWrite(17, LOW);
  pinMode(motorpin1,OUTPUT);        
  pinMode(motorpin2,OUTPUT);
  door_state=CLOSE;
}

void loop() {
  
  if(digitalRead(MANUALMODE_pin)==HIGH) //switch set to manual
  {
    delay(10);
    if(digitalRead(MANUALMODE_pin)==HIGH)//debouncing, switch really set to manual
    {
      if(digitalRead(MANUALOPEN_pin)==HIGH) //toggle button is pressed
      {
        delay(10);
        if(digitalRead(MANUALOPEN_pin)==HIGH)//debouncing, toggle button is really pressed
        {  
          if(door_state==OPEN)  
          {
            Serial.println("trying to close now ...");
            MoveTray(CLOSE);//close the door
          }
          else if(door_state==CLOSE)  
          {
            Serial.println("trying to open now ...");
            MoveTray(OPEN);//close the door
          }          
        }
      }
    }
  }
  else if(digitalRead(MANUALMODE_pin)==LOW) //switch is set to automatic
  {  
    delay(10);
    if(digitalRead(MANUALMODE_pin)==LOW) //debouncing, switch really set to automatic
    {
      if(door_state==OPEN)  
      {
      Serial.println("trying to close now ...");
      MoveTray(CLOSE);//close the door
      }
      else if(door_state==CLOSE)  
      {
      Serial.println("trying to open now ...");
      MoveTray(OPEN);//close the door
      }      
      delay(1000);
    }
  }
}   


void MoveTray(int openclose)
    {
    long duration, distance;
    digitalWrite(trigPin, LOW);  // Added this line
  delayMicroseconds(2); // Added this line
  digitalWrite(trigPin, HIGH);
//  delayMicroseconds(1000); - Removed this line
  delayMicroseconds(10); // Added this line
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
    
    int cat_alert;
  cat_alert=0;  
    if(openclose==CLOSE) //close the door!
      {
    digitalWrite(motorpin1,LOW);  // sukimas atgal
    digitalWrite(motorpin2,HIGH); 
//      while ( (digitalRead(DOORSENSOR_CLOSED)==LOW) &&  (analogRead(IR_pin)<200) ); //while the door is not entirely closed and there is no cat
      while ( (digitalRead(DOORSENSOR_CLOSED)==LOW) && cat_alert==0)
         {if(distance > 20)
           {delay(20);
           if(distance > 20)
             {
             cat_alert=1;  
             digitalWrite(motorpin1,LOW);  // stabdymas
             digitalWrite(motorpin2,LOW); 
             openclose=OPEN;
             }
           }
         }  
      
       //while the door is not entirely closed and there is no cat
        if(cat_alert==0)
          {
        digitalWrite(motorpin1,LOW);  // stabdymas
        digitalWrite(motorpin2,LOW); 
        door_state=CLOSE;
        Serial.println("it's closed.");
          }
        
      }
    
    if(openclose==OPEN) //open the door!
      { 
       digitalWrite(motorpin1,HIGH);      // sukimas i prieki
       digitalWrite(motorpin2,LOW); 
      while ((digitalRead(DOORSENSOR_OPEN)==LOW) ); //while the door is not entirely open 
      digitalWrite(motorpin1,LOW);  // stabdymas
      digitalWrite(motorpin2,LOW); 
    door_state=OPEN;
    Serial.println("it's open.");
    }
}

original code source: http://www.writtensound.com/arduino/dc_motor_with_stoppers_and_buttons_and_IR.pde
http://www.instructables.com/id/RFID-pet-feeder/?ALLSTEPS

So maybe someone could help me with this code and try to explain where is the mistake?

The mistake is that you posted code without explaining what it actually does, what you want it to do, and how those two differ, if they do.

PaulS:
The mistake is that you posted code without explaining what it actually does, what you want it to do, and how those two differ, if they do.

oh, you right, i forgot to write algorithm. there are two opening/closing modes, manual and automatic, these modes are controled by the swithc. if automatic, dc starts turning and opening doors till doors push 1 button (opened doors sensor), then if closed doors button LOW range sensor cheking pet, if there are no pets, after few seconds doors starts to closing till push 2 button (closed doors sensor). if in opened doors range sensor capture pet, DC do not receiv the signal to start doors closing. In manual mode if pushed 3 button (manual open/close button) dc starts till doors push the 1 button, then push 3 button again and starting doors closing.

I hope it possible to understood how the program should work. if not, just say it, i will try to explain better.

         {if(distance > 20)
           {delay(20);
           if(distance > 20)
             {

If the value in distance was 42, how is it supposed to change while you twiddle your thumbs?

I gave
up on reading
your code. I
was getting
seasick
with it
jumping
all over
the place.

There is an item on the Tools menu, Auto Format, that you need to learn about.

PaulS:
If the value in distance was 42, how is it supposed to change while you twiddle your thumbs?

I gave
up on reading
your code. I
was getting
seasick
with it
jumping
all over
the place.

There is an item on the Tools menu, Auto Format, that you need to learn about.

Ok, this part i'm understand perfectly :smiley: next time i will format code, thanks for this note.

PaulS:
If the value in distance was 42, how is it supposed to change while you twiddle your thumbs?

but this part still not clear for me. I'm sorry if my lack of knowledge irritates You. Distance value in my code are wrong?

duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;

I dont understand this part of code, why 29.1? why this value was used in original code?

but this part still not clear for me. I'm sorry if my lack of knowledge irritates You. Distance value in my code are wrong?

No. It is checking the same value twice, with the expectation that it might have changed, that is wrong. If the value in the variable was greater than 20 the first time, it won't have changed because you twiddled your thumbs for a while. So, the second if statement is useless.

why 29.1?

Because that's how far sound travels in one millisecond.

ok, so if I will write code like that:

int cat_alert;
  cat_alert=0;  
  if(openclose==CLOSE) //close the door!
  {
    digitalWrite(motorpin1,LOW);  // sukimas atgal
    digitalWrite(motorpin2,HIGH); 
    //      while ( (digitalRead(DOORSENSOR_CLOSED)==LOW) &&  (analogRead(IR_pin)<200) ); //while the door is not entirely closed and there is no cat
    while ( (digitalRead(DOORSENSOR_CLOSED)==LOW) && cat_alert==0)
    {
      if(distance < 5)

      {
        //delay(20);
        
          Serial.println("sensor working");
        {
          cat_alert=1;  
          digitalWrite(motorpin1,LOW);  // stabdymas
          digitalWrite(motorpin2,LOW); 
          openclose=OPEN;
        }
      }
    }  

    //while the door is not entirely closed and there is no cat
    if(cat_alert==0)
    {
      digitalWrite(motorpin1,LOW);  // stabdymas
      digitalWrite(motorpin2,LOW); 
      door_state=CLOSE;
      Serial.println("it's closed.");
    }

  }

  if(openclose==OPEN) //open the door!
  { 
    digitalWrite(motorpin1,HIGH);      // sukimas i prieki
    digitalWrite(motorpin2,LOW); 
    while ((digitalRead(DOORSENSOR_OPEN)==LOW) ); //while the door is not entirely open 
    digitalWrite(motorpin1,LOW);  // stabdymas
    digitalWrite(motorpin2,LOW); 
    door_state=OPEN;
    Serial.println("it's open.");
  }
}

it should work like that: if doors are opened, then sensor chek or there are no cats in distance < 5, and if there ar something then in port monitor show note "sensor working" and stop DC motor, when cat moves away gates starts to close. Am i righ?

but there are still some mistake, because if sensor feels that cat is near, in port monitor it shows sensor working but DC still runing and trying to closethe doors, also 2 button (closed doors sensor) not working only opened doors sensor work normaly.

By the way, thanks for Your help!

It's very hard to read your code with commented out code, useless curly braces, piss-poor indentation, etc.

Get rid of all commented out code. Get rid of useless curly braces, like these:

          Serial.println("sensor working");
        {
          cat_alert=1;  
          digitalWrite(motorpin1,LOW);  // stabdymas
          digitalWrite(motorpin2,LOW); 
          openclose=OPEN;
        }

Use Tools + Auto Format to fix the indenting, and post your code again.

I know its hard to understand when You can't see working model, and when code are not clear. Should i modify something more?

const int trigPin=13;
const int echoPin=12;
const int DOORSENSOR_OPEN=5;    //input
const int DOORSENSOR_CLOSED=6;    //input
const int MANUALMODE_pin=7;    //input
const int MANUALOPEN_pin=8;    //input
const int OPEN=1;
const int CLOSE=0;
int door_state;
int val;                 // variable to store the value coming from the IR sensor
int motorpin1 = 3;       //define digital output pin no.
int motorpin2 = 4;





void setup() {
  Serial.begin(9600);    // set up Serial library at 9600 bps
  Serial.println("Motor test!");
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  pinMode(motorpin1,OUTPUT);        
  pinMode(motorpin2,OUTPUT);
  door_state=CLOSE;
}

void loop() {

  if(digitalRead(MANUALMODE_pin)==HIGH)    //switch set to manual
  {
    delay(10);
    if(digitalRead(MANUALMODE_pin)==HIGH)    //debouncing, switch really set to manual
    {
      if(digitalRead(MANUALOPEN_pin)==HIGH)    //toggle button is pressed
      {
        delay(10);
        if(digitalRead(MANUALOPEN_pin)==HIGH)  //debouncing, toggle button is really pressed
        {  
          if(door_state==OPEN)  
          {
            Serial.println("trying to close now ...");
            MoveTray(CLOSE);    //close the door
          }
          else if(door_state==CLOSE)  
          {
            Serial.println("trying to open now ...");
            MoveTray(OPEN);    //close the door
          }          
        }
      }
    }
  }
  else if(digitalRead(MANUALMODE_pin)==LOW)    //switch is set to automatic
  {  
    delay(10);
    if(digitalRead(MANUALMODE_pin)==LOW)    //debouncing, switch really set to automatic
    {
      if(door_state==OPEN)  
      {
        Serial.println("trying to close now ...");
        MoveTray(CLOSE);    //close the door
      }
      else if(door_state==CLOSE)  
      {
        Serial.println("trying to open now ...");
        MoveTray(OPEN);    //close the door
      }      
      delay(1000);
    }
  }
}   


void MoveTray(int openclose)
{
  long duration, distance;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;

  int cat_alert;
  cat_alert=0;  
  if(openclose==CLOSE)    //close the door!
  {
    digitalWrite(motorpin1,LOW);    // turn DC backward
    digitalWrite(motorpin2,HIGH); 
    while ( (digitalRead(DOORSENSOR_CLOSED)==LOW) && cat_alert==0)
    {
      if(distance < 5)
        Serial.println("sensor working");
      cat_alert=1;  
      digitalWrite(motorpin1,LOW);    // stop DC
      digitalWrite(motorpin2,LOW); 
      openclose=OPEN;
    }  
    if(cat_alert==0)
    {
      digitalWrite(motorpin1,LOW);    // stop DC
      digitalWrite(motorpin2,LOW); 
      door_state=CLOSE;
      Serial.println("it's closed.");
    }

  }
  if(openclose==OPEN)    //open the door!
  { 
    digitalWrite(motorpin1,HIGH);    // turn DC forward
    digitalWrite(motorpin2,LOW); 
    while ((digitalRead(DOORSENSOR_OPEN)==LOW) );    //while the door is not entirely open 
    digitalWrite(motorpin1,LOW);    // stop DC
    digitalWrite(motorpin2,LOW); 
    door_state=OPEN;
    Serial.println("it's open.");
  }
}
            MoveTray(CLOSE);    //close the door
            MoveTray(OPEN);    //close the door

What, exactly, does OPEN mean to you?

  if(digitalRead(MANUALMODE_pin)==HIGH)    //switch set to manual
  else if(digitalRead(MANUALMODE_pin)==LOW)    //switch is set to automatic

Are you planning to add code to deal with the other possible return values from digitalRead()? What other modes do you plan to support? TICKLED? MASHED? FONDLED?

If the pin isn't HIGH, it MUST be LOW. The else if should (again) be JUST an else.

  int cat_alert;
  cat_alert=0;

Is this somehow more understandable to you than

  int cat_alert = 0;

?

You read the distance to something (what isn't clear), and then decide whether there is a cat present or not, in a very confusing way. Once you start closing the door, you never again check for the presence of a cat.

Finally, openclose is a dumb name for a boolean variable. doorOpen might be true if the door is open, or false when the door is closed. Does openclose equal true mean that the door is either open or closed, while openclose equal false mean that the door is neither open or closed?

And last, but not least, what does your serial output show, and what, exactly, is the problem?

What, exactly, does OPEN mean to you?

This one good. :smiley:

Ok, I understand Your notes. At least I think that I understand. :smiley: But it is more code style and grama mistakes, yes i will correct, but there are something wrong made in code structure.

You read the distance to something (what isn't clear), and then decide whether there is a cat present or not, in a very confusing way. Once you start closing the door, you never again check for the presence of a cat.

Do you think that it would be better to write code in some another way? In future i i will try to introduce RFID in this code, in my vision it should work like that - RFID opens the doors, sensor checks cat in some range an will not let doors to close till cat is near.

And last, but not least, what does your serial output show, and what, exactly, is the problem?

Problem is that sensor not working properly. it should not let dc turning for doors closing if there are something in front of sensor.

now model ignore sensor, opens doors and starts to closing, no mater if there are something in front of sensor.