Page 1 of 1

Fingeravtryckläsare FPC1020 + Z-Wave till garagedörrsöppnare

Posted: 18 Mar 2019, 11:48
by MastrUsr
Hej!
Jag har arbetat en (för) lång tid för att få detta projektet i land och igår fick jag äntligen det att fungera!

Garagedörrsöppnaren har en plint som när den sluts cyklar mellan framåt och bakåt (och stopp). Jag har använt en Z-Uno med en FPC1020 för att öppna garaget. Det finns också några andra saker kopplade så som en fuktighets- och tempsensor.

Jag lyckades inte skriva om biblioteket (pekare...), så jag använde all nödvändig kod i huvudprogrammet istället :oops:. Jag har också gjort så att jag kan initiera en lägg till eller ta bort fingeravtryck via Z-Wave. Jag använder den med en Home Center 2.

Bilder av virtuella enheter i HC2

Code: Select all

#include "ZUNO_DHT.h"

//=======================================================================================================================
//Below is from the FPC1020 library
//=======================================================================================================================
#define DATA_START        0xf5  // Data start
#define DATA_END          0xf5  // Data end

#define CMD_ENROLL1       0x01  // Add fingerprint 1st
#define CMD_ENROLL2       0x02  // Add fingerprint 2nd
#define CMD_ENROLL3       0x03  // Add fingerprint 3rd
#define CMD_DELETE        0x04  // Delete assigned user
#define CMD_CLEAR         0x05  // Delete all users
#define CMD_USERNUMB      0x09  // Get number of users
#define CMD_IDENTIFY      0x0b  // Fingerprint matching 1:1
#define CMD_SEARCH        0x0c  // Fingerprint matching 1:N
#define CMD_USERID        0x2b  // Get User ID and User Permission

#define ACK_SUCCESS       0x00  // Operate success
#define ACK_FAIL          0x01  // Operate filed
#define ACK_FULL          0x04  // Fingerprint database is full
#define ACK_NOUSER        0x05  // User do not exist
#define ACK_USER_OCCUPIED 0x06  // User ID already exists
#define ACK_USER_EXIST    0x07  // Fingerprint already exists
#define ACK_TIMEOUT       0x08  // Acuquisition timeout

#define UART_BUF_LEN  8
#define BUF_N   8

unsigned char rBuf[192];           //Receive return data
byte tBuf[UART_BUF_LEN];           //Send commands or data
unsigned char g_ucUartRxEnd ;      //Receive return data end flag
unsigned char g_ucUartRxLen ;      //Receive return data length
unsigned char l_ucFPID = 1;        //User ID

unsigned int User_ID = 0;
unsigned char incomingNub;
unsigned int  matchUserID = 0;
unsigned char rtf = 0;

//=======================================================================================================================
//Above is from the library
//=======================================================================================================================

ZUNO_SETUP_CHANNELS(
  ZUNO_SWITCH_MULTILEVEL(fp_add_id_getter, fp_add_id_setter),     // 1. ID to save new figerprint
  ZUNO_SWITCH_MULTILEVEL(fp_read_id_getter, fp_read_id_setter),   // 2. Last read ID
  ZUNO_SWITCH_MULTILEVEL(command_getter, command_setter),         // 3. Command
  ZUNO_SWITCH_MULTILEVEL(port_status_getter, port_status_setter), // 4. Status of port
  ZUNO_SENSOR_MULTILEVEL_TEMPERATURE(getter_temperature),         // 5. Temp sensor
  ZUNO_SENSOR_MULTILEVEL_HUMIDITY(getter_humidity),               // 6. Humidity sensor
  ZUNO_SWITCH_MULTILEVEL(fpr_status_getter, fpr_status_setter),   // 7. Status of fingerprint reader
  ZUNO_SENSOR_BINARY_SMOKE(getter_smoke_sensor)                   // 8. Smoke sensor
);
//Z-Wave order
const int ID_TO_SAVE = 1;
const int LAST_READ_FP = 2;
const int COMMAND = 3;
const int GARAGE_PORT_STATUS = 4;
const int TEMPERATURE_SENSOR = 5;
const int HUMIDITY_SENSOR = 6;
const int FPR_STATUS = 7;
const int SMOKE_SENSOR = 8;

//PINS
const int USE_COMPUTER_PIN = 0;
const int LID_PIN = 9;
const int RED_LED = 10;
const int GREEN_LED = 11;
const int OUTPUT_PIN1 = 12;
const int OUTPUT_PIN2 = 13;
const int OUTPUT_PIN3 = 14;
//const int DHTPIN = 15; THIS PIN IS USED BY THE DHT SENSOR
const int GARAGE_DOOR_SENSOR_BOT = 16;
const int GARAGE_DOOR_SENSOR_TOP = 17;
const int SMOKE_SENSOR_PIN = 18;
const int WHITE_LED = 19;
const int OUTPUT_HIGH_DURATION = 150;     //[ms]
const int MOTOR_DELAY = 400;   //[ms]

//Variables
bool lid;
bool done;
int mode = 0;
int garageDoorControlValue;
int garageDoorControlFlag;
int garageDoorState;
int garage_door_sensor_bot;
int garage_door_sensor_top;
bool garage_door_sensor_bot_last;
bool garage_door_sensor_top_last;
bool stoploop = false;          //
unsigned long startTime;        // For braking out of search-loop.
unsigned long interval = 1000;  //
int fpr_status;
bool using_computer = false;
bool smoke_sensor = TRUE;
bool smoke_sensor_last = TRUE;
bool reading_false;
int humidity;
int lastHumidity;
int temperature;
int lastTemperature;
unsigned long currentTime;
unsigned long previousTime;
unsigned long ZUnoReportReadCurrentTime = 0;
unsigned long ZUnoReportReadPreviousTime = 0;
unsigned long portMoveTimer;
unsigned long portMoveTimerPrevious;
bool enrolling;

DHT dht_sensor(15, DHT22);

void setup() {
  Serial.begin();
  Serial1.begin(19200);
  pinMode(LID_PIN, INPUT_PULLUP);
  pinMode(OUTPUT_PIN1, OUTPUT);
  pinMode(OUTPUT_PIN2, OUTPUT);
  pinMode(OUTPUT_PIN3, OUTPUT);
  pinMode(GREEN_LED, OUTPUT);
  pinMode(RED_LED, OUTPUT);
  pinMode(WHITE_LED, OUTPUT);
  pinMode(GARAGE_DOOR_SENSOR_BOT, INPUT_PULLUP);
  pinMode(GARAGE_DOOR_SENSOR_TOP, INPUT_PULLUP);
  pinMode(USE_COMPUTER_PIN, INPUT_PULLUP);
  pinMode(SMOKE_SENSOR_PIN, INPUT_PULLUP);
  dht_sensor.begin();

  Serial.println("Fingerprint Test!");

  garage_door_sensor_bot = digitalRead(GARAGE_DOOR_SENSOR_BOT);
  garage_door_sensor_top = digitalRead(GARAGE_DOOR_SENSOR_TOP);

  if (!garage_door_sensor_bot and !garage_door_sensor_top) {
    garageDoorState = 95;
    garage_door_sensor_bot_last = garage_door_sensor_bot;
    garage_door_sensor_top_last = garage_door_sensor_top;
  }
  else if (garage_door_sensor_bot and garage_door_sensor_top) {
    garageDoorState = 6;
    garage_door_sensor_bot_last = garage_door_sensor_bot;
    garage_door_sensor_top_last = garage_door_sensor_top;
  }
  else if (!garage_door_sensor_bot) {
    garageDoorState = 0;
    garage_door_sensor_bot_last = garage_door_sensor_bot;
  }
  else if (!garage_door_sensor_top) {
    garageDoorState = 5;
    garage_door_sensor_top_last = garage_door_sensor_top;
  }
  zunoSendReport(GARAGE_PORT_STATUS);
  fpr_status = 95;
  zunoSendReport(FPR_STATUS);
}

void loop() {
  //delay(10);
  //  Serial.print("garageDoorState: ");
  //  Serial.println(garageDoorState);

  garage_door_sensor_bot = digitalRead(GARAGE_DOOR_SENSOR_BOT);
  garage_door_sensor_top = digitalRead(GARAGE_DOOR_SENSOR_TOP);
  smoke_sensor = digitalRead(SMOKE_SENSOR_PIN);
  lid = !digitalRead(LID_PIN);
  Serial.println(lid);
  if (!smoke_sensor) {
    if (smoke_sensor != smoke_sensor_last) {
      smoke_sensor_last = smoke_sensor;
      zunoSendReport(SMOKE_SENSOR);
    }
  }
  
  //  Serial.print("garage_door_sensor_bot: ");
  //  Serial.println(garage_door_sensor_bot);
  //  Serial.print("garage_door_sensor_top: ");
  //  Serial.println(garage_door_sensor_top);
  //  Serial.print("garage_door_sensor_bot_last: ");
  //  Serial.println(garage_door_sensor_bot_last);
  //  Serial.print("garage_door_sensor_top_last: ");
  //  Serial.println(garage_door_sensor_top_last);

  portMoveTimer = millis();
  if (portMoveTimer - portMoveTimerPrevious > 24000) {
    //   Serial.println("In port timer");
    if ((garageDoorState == 0 or garageDoorState == 5) and (garage_door_sensor_bot and garage_door_sensor_top)) {
      garageDoorState = 6;
      zunoSendReport(GARAGE_PORT_STATUS);
    }
    if (garageDoorState == 1) {
      garageDoorState = 2;
      zunoSendReport(GARAGE_PORT_STATUS);
    }
    if (garageDoorState == 3) {
      garageDoorState = 4;
      zunoSendReport(GARAGE_PORT_STATUS);
    }
  }

  if (!garage_door_sensor_bot and !garage_door_sensor_top) {
    garageDoorState = 95;
    garage_door_sensor_bot_last = !garage_door_sensor_bot;
    garage_door_sensor_top_last = !garage_door_sensor_top;
    zunoSendReport(GARAGE_PORT_STATUS);
  }
  else if (garage_door_sensor_bot != garage_door_sensor_bot_last) {
    garage_door_sensor_bot_last = garage_door_sensor_bot;
    if (!garage_door_sensor_bot) {
      garageDoorState = 0;
      //      garage_door_sensor_bot_last = garage_door_sensor_bot;
      zunoSendReport(GARAGE_PORT_STATUS);
    }
  }
  else if (garage_door_sensor_top != garage_door_sensor_top_last) {
    garage_door_sensor_top_last = garage_door_sensor_top;
    if (!garage_door_sensor_top) {
      garageDoorState = 5;
      //      garage_door_sensor_top_last = garage_door_sensor_top;
      zunoSendReport(GARAGE_PORT_STATUS);
    }
  }

  currentTime = millis();
  if ((currentTime - previousTime) >= 20000) {
    humidity = dht_sensor.readHumidity();
    temperature = dht_sensor.readTemperature();
    if (humidity != lastHumidity) {
      lastHumidity = humidity;
      zunoSendReport(HUMIDITY_SENSOR);
    }
    if (temperature != lastTemperature) {
      lastTemperature = temperature;
      zunoSendReport(TEMPERATURE_SENSOR);
    }
    previousTime = currentTime;
  }

  ZUnoReportReadCurrentTime = millis();
  if ((ZUnoReportReadCurrentTime - ZUnoReportReadPreviousTime) >= 10000 and fpr_status != 0) {
    fpr_status = 0;
    zunoSendReport(FPR_STATUS);
    //    Serial.println("FPR = 0 Sent");
  }


  if (lid) {
    done = false;
    enrolling = false;
    digitalWrite(WHITE_LED, LOW);
    delay(100);
    if (Serial1.available() > 0) {
      Search();
    }
  }
  else {
    digitalWrite(WHITE_LED, HIGH);
  }

  if (!lid and !using_computer) {      // Read fingerprint when lid opened.
    if (!done and !enrolling) {
      Serial.println("Match Fingerprint, please put your finger on the Sensor.");
      if (Search()) {
        Serial.print("Finger with ID ");
        Serial.print(l_ucFPID, DEC);
        Serial.println(" read!");

        digitalWrite(OUTPUT_PIN1, HIGH);
        digitalWrite(OUTPUT_PIN2, HIGH);
        digitalWrite(OUTPUT_PIN3, HIGH);
        digitalWrite(GREEN_LED, HIGH);
        delay(200);
        digitalWrite(OUTPUT_PIN1, LOW);
        digitalWrite(OUTPUT_PIN2, LOW);
        digitalWrite(OUTPUT_PIN3, LOW);
        digitalWrite(GREEN_LED, LOW);

        //        delay(20);
        done = true;
        zunoSendReport(LAST_READ_FP);
        fpr_status = 10;
        zunoSendReport(FPR_STATUS);
        ZUnoReportReadPreviousTime = ZUnoReportReadCurrentTime;
      }

      else if (!stoploop) {
        Serial.println("Failed! ");
        if (reading_false) {
          Serial.print("Reading false!");
          digitalWrite(RED_LED, HIGH);
          delay(75);
          digitalWrite(RED_LED, LOW);
          fpr_status = 11;
          zunoSendReport(FPR_STATUS);
          ZUnoReportReadPreviousTime = ZUnoReportReadCurrentTime;
        }
      }
    }
  }
  //  Serial.print("Mode: ");
  //  Serial.println(mode);
  //  Serial.print("ID: ");
  //  Serial.println(User_ID);

  if (mode == 1) {  // Add a New User.
    mode = 0;
    fpr_status = 1;
    zunoSendReport(FPR_STATUS);
    enrolling = true;
    Serial.println("Add Fingerprint, please put your finger on the Fingerprint Sensor.");
    rtf = Enroll(User_ID);
    Serial.print("rtf: ");
    Serial.println(rtf);
    if (rtf == 93) {
      Serial.print("Success, your User ID is: ");
      Serial.println( User_ID , DEC);
      fpr_status = 2;   //2 = Success, ID enrolled.
    }
    else if (rtf == 0x00) {
      Serial.println("Failed, please try again.");
      fpr_status = 3;   //3 = Failed, please try again.
    }
    else if ( rtf == ACK_USER_OCCUPIED) {
      Serial.println("Failed, this User ID alread exsits.");
      fpr_status = 4;   //4 = Failed, this User ID alread exsits.
    }
    else if ( rtf == ACK_USER_EXIST) {
      Serial.println("Failed, this fingerprint alread exsits.");
      fpr_status = 5;   //5 = Failed, this fingerprint alread exsits.
    }
    Serial.println(fpr_status);
    zunoSendReport(FPR_STATUS);
    delay(100);
    ZUnoReportReadPreviousTime = ZUnoReportReadCurrentTime;
  }

  if (mode == 2) {   // Delete Assigned User ID
    mode = 0;
    fpr_status = 0;
    if (Delete(User_ID)) {
      Serial.print("Delete Fingerprint with User ID ");
      Serial.print(User_ID);
      Serial.println(" succeeded!");
      fpr_status = 6;   //6 = Delete ID success!
    }
    else {
      Serial.print("Delete Fingerprint with User ID ");
      Serial.print(User_ID);
      Serial.println(" failed!");
      fpr_status = 7;   //7 = Delete ID failed!
    }
    zunoSendReport(FPR_STATUS);
    ZUnoReportReadPreviousTime = ZUnoReportReadCurrentTime;
    delay(100);
  }


  if (mode == 10) {
    Serial.print("Mode: 10");
    mode = 0;
    garageDoorControl(0);
  }
  else if (mode == 11) {
    Serial.print("Mode: 11");
    mode = 0;
    garageDoorControl(1);
  }

  else if (mode == 12) {
    Serial.print("Mode: 12");
    mode = 0;
    garageDoorControl(2);
  }


  //========================================================================================================================================================================

  if (!digitalRead(USE_COMPUTER_PIN)) {
    using_computer = true;
  }

  if (using_computer) {
    Serial.println("=================== Menu =====================");
    Serial.println("Add a New User ----------------- 1");
    Serial.println("Fingerprint Matching --------------- 2");
    Serial.println("Get User Number and Print All User ID ------ 3 ");
    Serial.println("Delete Assigned User --------- 4");
    Serial.println("Delete All User ---------- 5");
    Serial.println("Back to Z-wave control ---------- 6");
    Serial.println("=================== End ======================");

    unsigned char  COMPUTER_MODE = 0;

    while (Serial.available() <= 0) {
      delay(10);
    }

    COMPUTER_MODE = Serial.read() - 0x30;

    switch (COMPUTER_MODE) {
      case 0: {  // Null
          break;
        }

      case 1: {   // Fingerprint Input and Add a New User
          COMPUTER_MODE = 0;
          User_ID = 0;

          Serial.println("Please input the new user ID (0 ~ 99).");
          while (Serial.available() <= 0) {
            delay(10);
          }
          delay(50);
          User_ID = Serial.parseInt();

          Serial.println("Add Fingerprint, please put your finger on the Fingerprint Sensor.");
          rtf = Enroll(User_ID);

          if (rtf == TRUE) {
            Serial.print("Success, your User ID is: ");
            Serial.println( User_ID , DEC);
          }
          else if (rtf == FALSE) {
            Serial.println("Failed, please try again.");
          }
          else if ( rtf == ACK_USER_OCCUPIED) {
            Serial.println("Failed, this User ID alread exsits.");
          }
          else if ( rtf == ACK_USER_EXIST) {
            Serial.println("Failed, this fingerprint alread exsits.");
          }
          delay(2000);
          break;
        }

      case 2: {  // Fingerprint Matching
          COMPUTER_MODE = 0 ;
          Serial.println("Match Fingerprint, please put your finger on the Sensor.");

          if ( Search()) {
            Serial.print("Success, your User ID is: ");
            Serial.println( l_ucFPID, DEC);
          }

          else {
            Serial.println("Failed, please try again.");
          }
          delay(1000);
          break;
        }

      case 3: {   // Print all user ID
          COMPUTER_MODE = 0;
          if (PrintUserID()) {
            Serial.print("Number of Fingerprint User is: ");
            unsigned char UserNumb;
            UserNumb = (l_ucFPID - 2) / 3;

            Serial.println(UserNumb, DEC);
            Serial.println("Print all User ID's: ");

            for (char i = 0; i < UserNumb; i++) {
              Serial.println(rBuf[12 + i * 3], DEC);
            }
          }

          else {
            Serial.println("Print User ID Fail!");
          }
          delay(500);
          break;
        }

      case 4: {   // Delete Assigned User ID
          COMPUTER_MODE = 0;
          User_ID = 0;
          Serial.println("Please input the user ID (0 ~ 99) you want to delete.");
          while (Serial.available() <= 0) {
            delay(10);
          }
          delay(100);
          incomingNub = Serial.available();
          for (char i = incomingNub; i >= 1; i--) {
            User_ID = User_ID + (Serial.read() - 0x30) * pow(10, (i - 1));
          }

          if (Delete(User_ID)) {
            Serial.println("Delete Fingerprint User Success!");
          }
          else {
            Serial.println("Delete Fingerprint User Fail!");
          }
          delay(1000);
          break;
        }

      case 5: {  // Delete All User ID
          COMPUTER_MODE = 0;
          unsigned char DeleteFlag = 0;

          Serial.println("Delete All Users, Y / N ? ");

          while (Serial.available() <= 0) {
            delay(10);
          }

          DeleteFlag = Serial.read();
          Serial.print("DeleteFlag : ");
          Serial.println(DeleteFlag);
          if (DeleteFlag == 'Y' or DeleteFlag == 'y') { //Y=89, y=121
            if (Clear()) {
              Serial.println("Delete All Fingerprint User Success!");
            }
            else {
              Serial.println("Delete All Fingerprint User Failed");
            }
          }
          else {
            Serial.println("Delete All Fingerprint User Aborted");
          }
          delay(500);
          break;
        }

      case 6: {
          using_computer = false;
          break;
        }
    }
  }
}


void garageDoorControl(int garageDoorControlValue) {
  // garageDoorState: 0=nere, 1=kör upp, 2=körUppStopp, 3=kör ner, 4=körNerStopp, 5=Uppe.
  // garageDoorCalled: 1=upp, 2=ner, 0=stopp.
  Serial.print("Garage door garageDoorControlValue recieved : ");
  Serial.println(garageDoorControlValue);
  delay(OUTPUT_HIGH_DURATION);


  if (garageDoorControlValue == 1) {
    if (garageDoorState == 0) {
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      garageDoorState = 1;
    }
    else if (garageDoorState == 2) {
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      delay(MOTOR_DELAY);
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      garageDoorState = 1;
    }
    else if (garageDoorState == 3) {
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      delay(MOTOR_DELAY);
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      garageDoorState = 1;
    }
    else if (garageDoorState == 4) {
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      garageDoorState = 1;
    }
    else if (garageDoorState == 6) {
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      garageDoorState = 6;
    }
    portMoveTimerPrevious = millis();
  }

  else if (garageDoorControlValue == 2) {
    if (garageDoorState == 1) {
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      delay(MOTOR_DELAY);
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      garageDoorState = 3;
    }
    else if (garageDoorState == 2) {
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      garageDoorState = 3;
    }
    else if (garageDoorState == 4) {
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      delay(MOTOR_DELAY);
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      garageDoorState = 3;
    }
    else if (garageDoorState == 5) {
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      garageDoorState = 3;
    }
    else if (garageDoorState == 6) {
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      garageDoorState = 6;
    }
    portMoveTimerPrevious = millis();
  }

  else if (garageDoorControlValue == 0) {
    if (garageDoorState == 1) {
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      garageDoorState = 2;
    }
    else if (garageDoorState == 3) {
      digitalWrite(OUTPUT_PIN1, HIGH); digitalWrite(OUTPUT_PIN2, HIGH); digitalWrite(OUTPUT_PIN3, HIGH);
      delay(OUTPUT_HIGH_DURATION);
      digitalWrite(OUTPUT_PIN1, LOW); digitalWrite(OUTPUT_PIN2, LOW); digitalWrite(OUTPUT_PIN3, LOW);
      garageDoorState = 4;
    }
  }
  //  Serial.print("garageDoorState : ");
  //  Serial.println(garageDoorState);
  zunoSendReport(GARAGE_PORT_STATUS);

  garageDoorControlFlag = -1;
}




byte fp_add_id_getter(void) {
  return User_ID;
}

void fp_add_id_setter(byte value) {
  if (value > 99) {
    // by Z-Wave specification, this value can't be more then 99
    value = 99;
  }
  User_ID = value;
}


byte fp_read_id_getter(void) {
  return l_ucFPID;
}
void fp_read_id_setter(byte value) {

}


byte command_getter(void) {
  return mode;
}
void command_setter(byte value) {
  mode = value;
}



byte port_status_getter(void) {
  return garageDoorState;
}
void port_status_setter(byte value) {

}


byte getter_temperature(void) {
  return temperature;
}

byte getter_humidity(void) {
  return humidity;
}


byte fpr_status_getter(void) {          //1 = Success, ID enrolled.                   //4 = Failed, this fingerprint alread exsits.
  return fpr_status;                    //2 = Failed, please try again.               //5 = Delete ID success!
}                                       //3 = Failed, this User ID alread exsits.     //6 = Delete ID failed!
void fpr_status_setter(byte value) {

}

byte getter_smoke_sensor(void) {
  return smoke_sensor;
}

























//=======================================================================================================================
//Below is from the library
//=======================================================================================================================
//Function:wait data packet send finish
unsigned char WaitFpData(void) {
  unsigned char rBuf_p = 0;
  stoploop = false;
  int count = 0;

  while (Serial1.available() <= 0 and count < 20) {
    delay(10);
    lid = digitalRead(LID_PIN);
    stoploop = true;
    if (!using_computer) {
      if (!enrolling) {
        count = count + 1;
        Serial.println(count);
      }
    }
    if (Serial1.available() > 0) {
      stoploop = false;
    }
  }

  if (!stoploop) {
    for (int i = 200; i > 0; i--) //wait response info
    {
      delay(20);
      rBuf[rBuf_p++] = Serial1.read();

      if (Serial1.available() == 0)
      {
        g_ucUartRxEnd = 1;
        g_ucUartRxLen = rBuf_p;
        break;
      }
    }
  }

  if (rBuf_p == 0) return 0x00;
  else return 0x01;
}

// check sum
unsigned char CmdGenCHK(unsigned char wLen, unsigned char *ptr) {
  unsigned char i, temp = 0;

  for (i = 0; i < wLen; i++)
  {
    temp ^= *(ptr + i);
  }
  return temp;
}

// Send command
void UART_SendPackage(unsigned char wLen, unsigned char *ptr) {
  unsigned int i = 0, len = 0;

  tBuf[0] = DATA_START;     //command head
  for (i = 0; i < wLen; i++)     // data in packet
  {
    tBuf[1 + i] = *(ptr + i);
  }

  tBuf[wLen + 1] = CmdGenCHK(wLen, ptr);         //Generate checkout data
  tBuf[wLen + 2] = DATA_END;
  len = wLen + 3;

  g_ucUartRxEnd = 0;
  g_ucUartRxLen = len ;

  for (i = 0; i < len; i++) {
    Serial1.write(tBuf[i]);
  }

  // Serial.print((char *)tBuf);
  //  UartSend(tBuf,len);
}

// response info check, return various info
unsigned char Check_Package(unsigned char cmd) {
  unsigned char flag = 0x00;
  if (!WaitFpData()) return flag; //wait response info
  // p = 0 ;
  if (g_ucUartRxEnd) {
    g_ucUartRxEnd = 0;//clear data packet flag
    reading_false = true;
  }
  else {
    return flag;
  }
  //   if(rBuf[0] != DATA_START)return flag;
  //  if(rBuf[1] != cmd)return flag;
  //  if(rBuf[6] != CmdGenCHK(g_ucUartRxLen - 3, &rBuf[1]))return flag;

  switch (cmd)
  {
    case CMD_ENROLL1:
    case CMD_ENROLL2:
    case CMD_ENROLL3:
      if (ACK_SUCCESS == rBuf[4])flag = 0x01;
      else if (ACK_USER_EXIST == rBuf[4])
      {
        flag = ACK_USER_EXIST;
        delay(200);
      }
      else if (ACK_USER_OCCUPIED == rBuf[4])
      {
        flag  = ACK_USER_OCCUPIED;
        delay(200);
      }
      break;
    case CMD_DELETE:  //delete assigned user
      if (ACK_SUCCESS == rBuf[4])flag = 0x01;
      break;
    case CMD_CLEAR:    //delete all users
      if (ACK_SUCCESS == rBuf[4])flag = 0x01;
      break;
    case CMD_IDENTIFY:  //1:1 comparison
      if (ACK_SUCCESS == rBuf[4])flag = 0x01;
      break;
    case CMD_USERNUMB:  // get user number
      if (ACK_SUCCESS == rBuf[4])
      {
        flag = 0x01;
        l_ucFPID = rBuf[3];
      }
      break;
    case CMD_SEARCH:   //1:N comparison
      if ((1 == rBuf[4]) || (2 == rBuf[4]) || (3 == rBuf[4]))
      {
        flag = 0x01;
        l_ucFPID = rBuf[3];
        Serial.print("l_ucFPID : ");
        Serial.println(l_ucFPID);
      }
      break;

    case CMD_USERID: // Get user ID

      if (ACK_SUCCESS == rBuf[4])
      {
        flag = 0x01;
        l_ucFPID = rBuf[3];
      }

      break;
    //    Serial.println(6);

    default:
      break;
  }
  //    Serial.println(7);

  return flag;
}

// Fingerprint indentify 1:N
unsigned char Search(void) {
  unsigned char buf[BUF_N];

  *buf = CMD_SEARCH;          //1:N comparison
  *(buf + 1) = 0x00;
  *(buf + 2) = 0x00;
  *(buf + 3) = 0x00;
  *(buf + 4) = 0x00;
  //  Serial.println(1);
  UART_SendPackage(5, buf);
  //    Serial.println(2);
  return Check_Package(CMD_SEARCH);
}

// Fingerprint indentify 1:1
void FP_Identify(unsigned int u_id) {
  unsigned char buf[BUF_N];

  *buf = CMD_IDENTIFY;
  *(buf + 1) = u_id >> 8;
  *(buf + 2) = u_id & 0xff;
  *(buf + 3) = 0x00;
  *(buf + 4) = 0x00;
  UART_SendPackage(5, buf);
}

//   Add new user Step 1
void Enroll_Step1(unsigned int u_id) {
  unsigned char buf[BUF_N];

  *buf = CMD_ENROLL1;
  *(buf + 1) = u_id >> 8;
  *(buf + 2) = u_id & 0xff;
  *(buf + 3) = 1;
  *(buf + 4) = 0x00;

  UART_SendPackage(5, buf);
}

//   Add new user Step 2
void Enroll_Step2(unsigned int u_id) {
  unsigned char buf[BUF_N];

  *buf = CMD_ENROLL2;
  *(buf + 1) = u_id >> 8;
  *(buf + 2) = u_id & 0xff;
  *(buf + 3) = 1;
  *(buf + 4) = 0x00;

  UART_SendPackage(5, buf);
}

//   Add new user Step 1
void Enroll_Step3(unsigned int u_id) {
  unsigned char buf[BUF_N];

  *buf = CMD_ENROLL3;
  *(buf + 1) = u_id >> 8;
  *(buf + 2) = u_id & 0xff;
  *(buf + 3) = 1;
  *(buf + 4) = 0x00;

  UART_SendPackage(5, buf);
}

//   Add a new user
unsigned char Enroll(unsigned int u_id) {
  unsigned char  rtflag;
  Enroll_Step1(u_id);
  rtflag = Check_Package(CMD_ENROLL1);
  Serial.println("Get data1");
  if (rtflag != 0x01)  return rtflag;
  delay(100);


  Enroll_Step2(u_id);
  rtflag = Check_Package(CMD_ENROLL2);
  Serial.println("Get data2");
  if (rtflag != 0x01)return rtflag;
  delay(100);


  Enroll_Step3(u_id);
  rtflag = Check_Package(CMD_ENROLL3);
  Serial.println("Get data3");
  if (rtflag != 0x01)return rtflag;
  delay(100);

}

//   Delete all of the users
unsigned char Clear(void) {
  unsigned char buf[BUF_N];

  *buf = CMD_CLEAR;
  *(buf + 1) = 0x00;
  *(buf + 2) = 0x00;
  *(buf + 3) = 0x00;
  *(buf + 4) = 0x00;

  UART_SendPackage(5, buf);
  return Check_Package(CMD_CLEAR);
}

//   Delete assigned user
unsigned char Delete(unsigned int u_id) {
  unsigned char buf[BUF_N];
  *buf = CMD_DELETE;
  *(buf + 1) = u_id >> 8;
  *(buf + 2) = u_id & 0xff;
  *(buf + 3) = 0x00;
  *(buf + 4) = 0x00;
  UART_SendPackage(5, buf);
  return Check_Package(CMD_DELETE);
}

//   Get user ID number
unsigned char Read(void) {
  unsigned char buf[BUF_N];
  *buf = CMD_USERNUMB;
  *(buf + 1) = 0x00;
  *(buf + 2) = 0x00;
  *(buf + 3) = 0x00;
  *(buf + 4) = 0x00;
  UART_SendPackage(5, buf);
  return Check_Package(CMD_USERNUMB);
}

//   Get user ID number
unsigned char PrintUserID(void) {
  unsigned char buf[BUF_N];
  *buf = CMD_USERID;
  *(buf + 1) = 0x00;
  *(buf + 2) = 0x00;
  *(buf + 3) = 0x00;
  *(buf + 4) = 0x00;
  UART_SendPackage(5, buf);
  return Check_Package(CMD_USERID);
}