diff --git a/code/cat_on_diet_feeder/cat_on_diet_feeder.ino b/code/cat_on_diet_feeder/cat_on_diet_feeder.ino index e74d74a..5cee195 100644 --- a/code/cat_on_diet_feeder/cat_on_diet_feeder.ino +++ b/code/cat_on_diet_feeder/cat_on_diet_feeder.ino @@ -9,6 +9,9 @@ const float SERVO_SPEED = 1.8; const float OPEN_ANGLE = 10.0; const float CLOSED_ANGLE = 160.0; +const float SERVO_PWR_TIME 500 //time to stop powering servomotor after the end of move +const float DOOR_OPENED_TIME 3000 //time to keep door open after last dectection on IR sensor +const float IR_DETECTION_THRESHOLD 100 //IR dectection threshold //Pin definitions #define RED_LED 12 @@ -21,36 +24,30 @@ const float CLOSED_ANGLE = 160.0; #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 +// SPECIAL TAG DEFINITIONS #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} +const byte emptytag[14] = EMPTY_TAG; +const byte unwrittentag[14] = UNWRITTEN_TAG; //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 ? +bool door_open = 0; // door opened ? +bool door_moving = 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()) { @@ -60,11 +57,10 @@ byte * readeepromtag(short tagnb=0) { return tag; } byte tag[14] = EMPTY_TAG; - for (int i=0; i<14; i++) - { + 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(" : ")); @@ -73,7 +69,7 @@ byte * readeepromtag(short tagnb=0) { // Serial.print(","); //} //Serial.println(""); - + delay(2); //small delay to avoid misreading return tag; } @@ -94,39 +90,47 @@ boolean comparetag(byte taga[14], byte tagb[14]) { } int findtag(byte searchtag[14]) { - //Find a given tag in EEPROM - + //Find a given tag in EEPROM and return tag rank or -1 if not found + byte *tag; - - for (int i=0; i < maxeepromtags(); i++) - { + + for (int i=0; i < maxeepromtags(); i++) { tag = readeepromtag(i); - if (comparetag(tag, searchtag)) return i; + if (comparetag(tag, searchtag)) { + return i; + } } return -1; } void tagOK() { + // Actions when an known tag is read : Open the door or deleted the tag + // if the prog button is pressed + if (digitalRead(PROG_BUTTON)) + // Prog button is not pressed : open the door { 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; + if (!door_open) { + Serial.println(F("Opening...")); + door_open = 1; door_timer = millis() + DOOR_OPENED_TIME; } } else + //if prog button is pressed : delete the tag from the EEPROM { delTag(newtag); } } void tagNoOK() { + // Actions when an known tag is read : light the red LED for 1 sec or + // add the tag to the EEPROM if the prog button is pressed if (digitalRead(PROG_BUTTON)) { for (int z = 0; z < 14 ; z++) { Serial.print(newtag[z]); @@ -142,11 +146,12 @@ void tagNoOK() { } } -void readRFID() { +void readRFID() { + // Read data from RFID & check if the tag is known (i.e. in EEPROM) 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 + + //Check up to 3 times if rejected to avoid mistakes for (byte i=0; i<3; i++) { // read tag numbers for (byte z = 0 ; z < 14 ; z++) // read the rest of the tag @@ -156,18 +161,26 @@ void readRFID() { } RFID.flush(); // stops multiple reads - // do the tag exist in EEPROM - if (findtag(newtag) >= 0) tag_ok=1; - if (tag_ok>0) break; + // 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(); + if (tag_ok > 0) { + tagOK(); + } + else { + tagNoOK(); + } } - + // empty the data cache while (RFID.available()) { RFID.read(); @@ -176,46 +189,43 @@ void readRFID() { void disableServo() { //Disable servomotor once they stop moving - if (!door_move and servo_timer < millis() and door_servo.attached()) { + if (!door_moving and servo_timer < millis() and door_servo.attached()) { door_servo.detach(); Serial.println(F("Servo disabled")); } } void updateSerial() { - //Désactive la connexion au lecteur RFID quand la - //trappe est en mouvement ou ouverte pour éviter les - // parasite - if (RFID and (door_state or door_move)) { + //Diconnect UART from RFID module when door is not closed to avoid unwanted + // small movements + if (RFID and (door_open or door_moving)) { RFID.end(); } else { - //Active la connexion au lecteur RFID quand la - //trappe est fermée et immobile RFID.begin(9600); } } void updateDoor() { - //Check if the need to move and move it + //Check if the door need to move and move it //Apply door status - if (door_state) { + if (door_open) { //Opening or open if (servo_pos <= OPEN_ANGLE) { //if door has to be open and already open, disable servomotor - if (door_move) { + if (door_moving) { //Opening - Serial.println(F("Door : opened")); + Serial.println(F("Door : open")); door_timer = millis() + DOOR_OPENED_TIME; servo_timer = millis() + SERVO_PWR_TIME; disableServo(); - door_move = false; + door_moving = false; } } else { //Keep opening the door - door_move = true; + door_moving = true; servo_pos -= SERVO_SPEED; door_servo.attach(SERVO_CTRL); door_servo.write(servo_pos); @@ -228,25 +238,25 @@ void updateDoor() { //Serial.print(F("Door timer :")); //Serial.println(door_timer - millis()); } - else if (!door_move) + else if (!door_moving) { - door_state = 0; + door_open = 0; } } else { if (servo_pos >= CLOSED_ANGLE) { //if door has to be open and already open, disable servomotor disableServo(); - if (door_move) { + if (door_moving) { Serial.println(F("Door : closed")); servo_timer = millis() + SERVO_PWR_TIME; disableServo(); - door_move = false; + door_moving = false; } } else { //Keep closing the door - door_move = true; + door_moving = true; servo_pos += SERVO_SPEED; door_servo.attach(SERVO_CTRL); door_servo.write(servo_pos); @@ -258,7 +268,7 @@ void updateDoor() { void updateLED() { //Update the LEDs state - if (door_state) { + if (door_open) { //Opening or open digitalWrite(GREEN_LED, HIGH); digitalWrite(RED_LED, LOW); @@ -267,8 +277,8 @@ void updateLED() { digitalWrite(GREEN_LED, LOW); digitalWrite(RED_LED, LOW); } - - //Check the redLED timer and turn ON or OFF the LED + + //Check the red LED timer and turn ON or OFF the LED if (millis() < red_led_timer) { digitalWrite(RED_LED, HIGH); // Serial.print(F("Red LED timer : ")); @@ -278,6 +288,7 @@ void updateLED() { } void addNewTag(byte tag[14]) { + //Add a new RFID tag to the known tags in EEPROM Serial.print(F("Adding new tag to EEPROM : ")); for (int z = 0; z < 14 ; z++) Serial.print(tag[z]); Serial.println(""); @@ -289,6 +300,8 @@ void addNewTag(byte tag[14]) { tagnb = findtag(unwrittentag); if (tagnb < 0) { Serial.println(F("No unwritten space found either. Can't save more tag.")); + //If there is not enough space in EEPROM to add the tag : blink the red LED + // and stop for (int i=0; i<4; i++) { digitalWrite(RED_LED, HIGH); delay(500); @@ -299,15 +312,19 @@ void addNewTag(byte tag[14]) { } } + //Write the ne teg in EEPROM 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]); } + + //Check the written tag Serial.print(F(" Checking...")); int tmp = findtag(tag); if (tmp != -1 and tmp == tagnb) { + //if OK : blink the green LED Serial.println("OK"); for (int i=0; i<3; i++) { digitalWrite(GREEN_LED, HIGH); @@ -317,6 +334,7 @@ void addNewTag(byte tag[14]) { } } else { + //if something's got wrong blink the RED led Serial.println("Failed"); for (int i=0; i<5; i++) { digitalWrite(RED_LED, HIGH); @@ -328,6 +346,7 @@ void addNewTag(byte tag[14]) { } void delTag(byte tag[14]) { + //Delete a RFID tag from the known tags in EEPROM Serial.print(F("Deleting tag from EEPROM : ")); for (int z = 0; z < 14 ; z++) { Serial.print(tag[z]); @@ -338,10 +357,13 @@ void delTag(byte tag[14]) { Serial.print(F("Tag number ")); Serial.println(tagnb); + //Write zeros in the place of the tag Serial.print(F("Writing zeros...")); for (int z = 0; z < 14 ; z++) { EEPROM.write(z+(tagnb*14), 0); } + + //Check if the tag is realy deleted Serial.print(F(" Checking...")); int tmptag = readeepromtag(tagnb); if (comparetag(tmptag, emptytag)) { @@ -362,42 +384,45 @@ void delTag(byte tag[14]) { } } -boolean catIsHere() { - int IR_ambient; // variable to store the IR coming from the ambient +boolean IR_detection() { + //Detected if a cat is here with infrared barrier + + int IR_ambient; // variable to store the IR coming from the ambient int value; // variable to store the IR values + // detect 5 times in a row for (int i=0; i<5; i++) { digitalWrite(IR_LED, LOW); delay(1); + //read ambiant IR reception before activating the IR LED to avoid parasites 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; - + Serial.println(F("Cat is here...")); + return true; + } + Serial.println(F("No cat !")); + return false; } void setup() { -// start serial to PC +// 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 + + // Pin mode for the LEDs pinMode(GREEN_LED, OUTPUT); pinMode(RED_LED, OUTPUT); pinMode(IR_LED, OUTPUT); @@ -414,12 +439,12 @@ void setup() { Serial.println(F(" tags)")); Serial.println(findtag(newtag)); Serial.println(findtag(unwrittentag)); - - //Positioning door - while (!door_move) { + + //Initialize door position + while (!door_moving) { updateDoor(); } - door_state = 0; + door_open = 0; } void loop() { @@ -433,7 +458,7 @@ void loop() { //Ouverture manuelle if (!digitalRead(DOOR_BUTTON)) { Serial.println("Ouverture par l'utilisateur."); - door_state = 1; + door_open = 1; door_servo.attach(SERVO_CTRL); door_servo.write(OPEN_ANGLE); delay(1000); @@ -443,16 +468,19 @@ void loop() { door_servo.write(CLOSED_ANGLE); delay(1000); Serial.println("Fermeture par l'utilisateur."); - door_state = 0; + door_open = 0; } - if (door_state and !door_move and catIsHere()) { + // Maintien de l'ouverture pour le delais DOOR_OPENED_TIME si présence + // détecté par capteur IR + if (door_open and !door_moving and IR_detection()) { door_timer = millis() + DOOR_OPENED_TIME; } + //Diverses mises à jour régulières updateSerial(); updateDoor(); updateLED(); - + delay(10); }