Hi everybody,
For my project I am attempting to make a cat flap that requires a RFID chip on the outside to open the flap, and a PIR sensor on the other side to open the flap. I am using a servo motor to pull the flap open and both sensors (RF Module and PIR) send signals to the servo to make it turn to a specific angle, wait 8 seconds to allow the cat through, and then turn back to the angle it was at before. I have got this to work with the PIR sensor, however I am having trouble with the RF Module. I am using the RDM630 from SeeedStudio.
For the RDM630 side of it, the servo is resting at 90 degrees, and it should turn to 0 degrees, wait for 8 seconds and then turn back. It does do this when the RFID chip is picked up by the antenna, however after it goes back to the strating position it runs through the whole process again, sometimes 2, often 3 and even more times before stopping. It should only run through once before stopping.
I will attach my code as I believe I have connected everything correctly and it must be a problem within the code.
#include <Servo.h>
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
LiquidCrystal lcd(12, 11, 5, 4, 10, 8);
unsigned long time;
int val2;
int ledState = 0;
const int RFrecieve = 2;
const int RFtransmit = 3;
SoftwareSerial rfidSerial (RFrecieve, RFtransmit);
int incomingByte = 0;
Servo myservo;
int RFID(){ //setting up the RFID function to be used in the void loop
byte i = 0;
byte val2 = 0;
byte code[6];
byte goodcode[11] = {0x30, 0x30, 0x30, 0x38, 0x39, 0x37, 0x32, 0x35, 0x37, 0x32};
byte checksum = 0;
byte bytesread = 0;
byte tempbyte = 0;
int result = 0;
if (rfidSerial.available()) {
result=1;
if((val2 = rfidSerial.read()) == 0x02) {
bytesread = 0;
Serial.println("Read it");
while(bytesread < 12) { //10 digit code and 2 digit checksum
if(rfidSerial.available()){
val2 = rfidSerial.read();
if((val2 == 0x0D) ||(val2 == 0x0A)||(val2 == 0x03)||(val2 == 0x02)) { //if header or stop bytes
break; //stop reading
}
//Ascii to hex conversion
if ((val2>='0') && (val2<='9')) {
val2 = val2 - '0';
} else if ((val2>='A') && (val2<='F')) {
val2 = 10 + val2 - 'A';
}
//Every two hex digits add byte to code:
if (bytesread & 1 == 1) {
//make some space for this hex digit by shifting previous hex digit with 4 bits to left
code[bytesread >> 1] = (val2 | (tempbyte <<4));
if (bytesread >> 1 !=5){ //if were at checksum byte
checksum^=code[bytesread >> 1]; //calculate checksum (XOR)
};
} else {
tempbyte = val2 ;//store first hex digit first
};
bytesread++; // ready to read next hex digit
}
}
//output to serial
if (bytesread == 12) { // if 12 digit read is complete
Serial.print("5-byte code: ");
for (i=0; i<5; i++) {
if (code[i] < 16) rfidSerial.print("0");
Serial.print(code[i], HEX);
Serial.print(" ");
}
Serial.println();
Serial.print("Checksum: ");
Serial.print(code[5], HEX);
Serial.println(code[5] == checksum ? " -- passed." : " -- error.");
if(code[5] == checksum)
result=1;
Serial.println();
}
bytesread = 0;;
}
}
return result;
}
//int counter = 0;
//int currentState = 0;
//int previousState = 0;
//int counter2 = 0;
//int currentState2 = 0;
//int previousState2 = 0;
//int servoval;
const int led = 13;
int motion = 6;
int val = 0;
int motionState = LOW;
//int pulse (1500);
//int Sol1State = 0;
//int Sol2State = 0;
//int RFsignal = 0;
//int RFState = LOW; //rest
//int motion = 0;
void setup() {
Serial.begin(9600);//serial comms between arduino and computer
rfidSerial.begin(9600);//softwareserial allows for one than one serial i/o
//Serial.println("RFID TEST");
// pinMode(Motor, OUTPUT);
pinMode (led, OUTPUT);
pinMode (motion, INPUT);
pinMode (RFrecieve, INPUT);
pinMode (RFtransmit, OUTPUT);
// digitalWrite(Motor, LOW);
digitalWrite(led, LOW);
lcd.begin(16, 2);
myservo.attach(9); //attaches the servo to pin 9 in setup rather than declaring as const int
myservo.write(90);
delay(2000);
}
void loop()
{
{
delay(140);
if (RFID()==1)
{
//servoval = digitalRead(RFID);
//servoval = map(servoval, 0, 1023, 0, 180);
myservo.write(0);
delay(8000);
myservo.write(90);
delay(1500);
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Cat inside");
delay(140);
}
}
//THIS LOOP IS FOR THE RF MODULE RDM630. ANY CODE WHICH IS // OUT IS NO LONGER NEEDED AND SHOULD BE IGNORED, HOWEVER I NEVER DELETE CODE UNTIL I HAVE THE FINAL PRODUCT WORKING I JUST // IT OUT
//else
//{
// digitalWrite(Motor, LOW);
//myservo.write(0);
//}
//} //FOR RF READER
{
val = digitalRead (motion);
if (val == HIGH)
{
myservo.write(180);
delay(8000);
myservo.write(90);
delay(1500);
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Cat outside");
} //THIS LOOP IS FOR THE PIR SENSOR. ANY CODE WHICH IS // OUT IS NO LONGER NEEDED AND SHOULD BE IGNORED, HOWEVER I NEVER DELETE CODE UNTIL I HAVE THE FINAL PRODUCT WORKING I JUST // IT OUT.
}
//else
//{
// digitalWrite (led, LOW);
//if (motionState == LOW)//PIR sensor (inside to outside) part
//Serial.println("PIR off");
//motionState = LOW;
}
// currentState2 = 0;
//if(currentState2 != previousState2)
//{
//if (currentState2 == 1)
//{
//counter2 = counter2 + 1;
//lcd.setCursor(0, 8);
//lcd.print(counter2);
//}
//}
//previousState2 = currentState2;
//delay(250);
//{
// Serial.print("Time: ");
//time = millis();
//lcd.setCursor(1, 0);
//lcd.print(time);
// delay(1000);
//}
//}
//}
I understand it is a lot of code to look through, but the loop is very simple there is just a lot before.
I would appreciate it if someone could have a look through this and help me out.
Thanks