From 4e7e685b84de0d222df89bbf5373ac02b8f383d1 Mon Sep 17 00:00:00 2001 From: Christoffer Martinsson Date: Mon, 19 Feb 2018 08:21:36 +0100 Subject: [PATCH] Implemented zwave and rfid --- zuno/zuno.ino | 530 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 422 insertions(+), 108 deletions(-) diff --git a/zuno/zuno.ino b/zuno/zuno.ino index cfa7da5..67a23dc 100644 --- a/zuno/zuno.ino +++ b/zuno/zuno.ino @@ -1,6 +1,8 @@ #include +#include -#define RFID Serial +#define CONSOLE_SERIAL Serial +#define RFID_SERIAL Serial1 #define SERVO_PIN 12 const int SERVO_ENABLE_PIN = 9; @@ -21,10 +23,16 @@ const int LED_UNLOCK_PIN = 6; #define SERVO_CENTER 3 #define SOURCE_EXTERNAL 0 -#define SOURCE_RFID 1 -#define SOURCE_ZWAVE 2 -#define SOURCE_BUTTONS 3 -#define SOURCE_SYSTEM 4 +#define SOURCE_RFID_1 1 +#define SOURCE_RFID_2 2 +#define SOURCE_RFID_3 3 +#define SOURCE_RFID_4 4 +#define SOURCE_RFID_5 5 +#define SOURCE_ZWAVE 6 +#define SOURCE_BUTTONS 7 +#define SOURCE_SYSTEM 8 + +#define SERVO_TRIM 2 // Last saved LED value byte currentLEDValue = 0; @@ -32,140 +40,257 @@ unsigned long int rfid = 0; #define SIGNAL_DEBOUNCE_CONSTANT 30 -bool sensor_lock = false; -bool sensor_handle = false; -bool sensor_disable = false; -bool sensor_close = false; +bool sensor_door_locked = false; +bool sensor_handle_in_up_position = false; +bool sensor_not_home_activated = false; +bool sensor_door_closed = false; -int sensor_lock_prev_state = HIGH; -int sensor_lock_current_state = LOW; -int sensor_lock_debounce = 0; -int sensor_handle_prev_state = HIGH; -int sensor_handle_current_state = LOW; -int sensor_handle_debounce = 0; -int sensor_disable_prev_state = HIGH; -int sensor_disable_current_state = LOW; -int sensor_disable_debounce = 0; -int sensor_close_prev_state = HIGH; -int sensor_close_current_state = LOW; -int sensor_close_debounce = 0; +bool sensor_door_locked_changed = false; +bool sensor_door_closed_changed = false; +bool sensor_not_home_activated_changed = false; + +int sensor_door_locked_prev_state = -1; +int sensor_door_locked_current_state = LOW; +int sensor_door_locked_debounce = 0; +int sensor_handle_in_up_position_prev_state = -1; +int sensor_handle_in_up_position_current_state = LOW; +int sensor_handle_in_up_position_debounce = 0; +int sensor_not_home_activated_prev_state = -1; +int sensor_not_home_activated_current_state = LOW; +int sensor_not_home_activated_debounce = 0; +int sensor_door_closed_prev_state = -1; +int sensor_door_closed_current_state = LOW; +int sensor_door_closed_debounce = 0; bool btn_lock = false; bool btn_unlock = false; -int btn_lock_prev_state = HIGH; +int btn_lock_prev_state = -1; int btn_lock_current_state = LOW; int btn_lock_debounce = 0; -int btn_unlock_prev_state = HIGH; +int btn_unlock_prev_state = -1; int btn_unlock_current_state = LOW; int btn_unlock_debounce = 0; int activity_flash = 0; int servo_status = 0; -int lock_status = 0; int source_status = 0; unsigned long current_timestamp = 0; unsigned long activity_timestamp = 0; unsigned long servo_timestamp = 0; +unsigned long rfid_timeout_timestamp = 0; + +bool lock_disable = false; + +#define RFID_PACKAGE_LENGHT 14 // nmbr of bytes in package +#define RFID_START_BYTE 0x02 // start byte +#define RFID_STOP_BYTE 0x03 // stop byte +#define RFID_TAG_BYTES 10 // number of bytes in package that represent the tag +#define RFID_TAGS 5 // Number of tags to be supported to store in EEPROM +#define EEPROM_CURRENT_TAG_ADDRESS 0 // Addres for storing current address in the tag memory +#define EEPROM_TAG_START_ADDRESS 1 // Start addres for storing RFID tags +int rfid_current_checksum = 0; +int rfid_package[RFID_PACKAGE_LENGHT]; +int rfid_package_pos = 0; +int rfid_tags[RFID_TAGS][RFID_TAG_BYTES]; +bool rfid_store_tag = false; +int rfid_store_tag_nbr = 0; +bool rfid_tag_1 = false; +bool rfid_tag_2 = false; +bool rfid_tag_3 = false; +bool rfid_tag_4 = false; +bool rfid_tag_5 = false; ServoController servo(12); +ZUNO_SETUP_SLEEPING_MODE(ZUNO_SLEEPING_MODE_ALWAYS_AWAKE); + // set up channel -ZUNO_SETUP_CHANNELS(ZUNO_SWITCH_MULTILEVEL(getter, setter)); -ZUNO_SETUP_DEBUG_MODE(DEBUG_ON); +ZUNO_SETUP_CHANNELS( + ZUNO_SWITCH_BINARY(getterLock, setterLock), + ZUNO_SWITCH_BINARY(getterLockDisable, setterLockDisable), + ZUNO_SWITCH_BINARY(getterRfidTag1, setterRfidTag1), + ZUNO_SWITCH_BINARY(getterRfidTag2, setterRfidTag2), + ZUNO_SWITCH_BINARY(getterRfidTag3, setterRfidTag3), + ZUNO_SWITCH_BINARY(getterRfidTag4, setterRfidTag4), + ZUNO_SWITCH_BINARY(getterRfidTag5, setterRfidTag5), + ZUNO_SENSOR_BINARY_DOOR_WINDOW(getterDoor) +); + +void update_rfid() { + int rfid_read = 0; + // Pass through BMC -> LCD communication + if (RFID_SERIAL.available()) { + while (RFID_SERIAL.available() > 0) { + rfid_read = RFID_SERIAL.read(); + + // Check for package start + if (rfid_read == RFID_START_BYTE) { + rfid_package_pos = 0; + } + // Check for package end + if (rfid_read == RFID_STOP_BYTE) { + if (rfid_store_tag == true) { + int rfid_eeprom_pos = rfid_store_tag_nbr * RFID_TAG_BYTES; + for (int i = 0; i < RFID_TAG_BYTES; i++) { + EEPROM.write(rfid_eeprom_pos, rfid_package[i + 1]); + rfid_eeprom_pos++; + } + + if (rfid_store_tag_nbr == 0){ + rfid_tag_1 = true; + } + else if (rfid_store_tag_nbr == 1){ + rfid_tag_2 = true; + } + else if (rfid_store_tag_nbr == 2){ + rfid_tag_3 = true; + } + else if (rfid_store_tag_nbr == 3){ + rfid_tag_4 = true; + } + else if (rfid_store_tag_nbr == 4){ + rfid_tag_5 = true; + } + + zunoSendReport(3 + rfid_store_tag_nbr); + + } else { + // Check for match of RFID tag + for (int i = 0; i < RFID_TAGS; i++) { + bool tag_ok = true; + for (int j = 0; j < RFID_TAG_BYTES; j++) { + if (rfid_package[j + 1] != rfid_tags[i][j]) { + tag_ok = false; + } + } + if (tag_ok == true) { + CONSOLE_SERIAL.println("RFID tag verified"); + if (sensor_door_locked){ + set_servo(SERVO_UNLOCK, i+1); + } + else{ + set_servo(SERVO_LOCK, i+1); + } + break; + } + } + } + } else { + rfid_package[rfid_package_pos] = rfid_read; + } + if (rfid_package_pos < RFID_PACKAGE_LENGHT - 1) { + rfid_package_pos++; + } + } + } +} void set_servo(int mode, int source){ - if (sensor_handle == true && sensor_disable == false && sensor_close == true){ - if (mode == SERVO_LOCK){ - servo.setValue(160+2); - lock_status = SERVO_LOCK; - } - else if (mode == SERVO_UNLOCK){ - servo.setValue(20+2); - lock_status = SERVO_UNLOCK; - } - else if (mode == SERVO_CENTER){ - servo.setValue(90+2); - } - if (mode == SERVO_DISABLE){ - digitalWrite(SERVO_ENABLE_PIN, LOW); - } - else{ - servo.begin(); - digitalWrite(SERVO_ENABLE_PIN, HIGH); - servo_timestamp = current_timestamp + 700; - } + bool ok_to_lock_unlock = false; + + // Check sensor status if ok to lock/unlock + if (sensor_handle_in_up_position == true && sensor_not_home_activated == false && sensor_door_closed == true && lock_disable == false){ + ok_to_lock_unlock = true; + } + + // Set servo position + if (mode == SERVO_LOCK && ok_to_lock_unlock && sensor_door_locked == false){ + servo.setValue(160+SERVO_TRIM); servo_status = mode; source_status = source; } + else if (mode == SERVO_UNLOCK && ok_to_lock_unlock && sensor_door_locked == true){ + servo.setValue(20+SERVO_TRIM); + servo_status = mode; + source_status = source; + } + else if (mode == SERVO_CENTER){ + servo.setValue(90+SERVO_TRIM); + servo_status = mode; + } + else if (mode == SERVO_DISABLE){ + digitalWrite(SERVO_ENABLE_PIN, LOW); + servo_status = mode; + } + + // Start servo + if (mode > SERVO_DISABLE){ + servo.begin(); + digitalWrite(SERVO_ENABLE_PIN, HIGH); + servo_timestamp = current_timestamp + 700; + } } void update_buttons(){ - sensor_lock_current_state = digitalRead(SENSOR_LOCK_PIN); - sensor_handle_current_state = digitalRead(SENSOR_HANDLE_PIN); - sensor_disable_current_state = digitalRead(SENSOR_DISABLE_PIN); - sensor_close_current_state = digitalRead(SENSOR_CLOSE_PIN); + sensor_door_locked_current_state = digitalRead(SENSOR_LOCK_PIN); + sensor_handle_in_up_position_current_state = digitalRead(SENSOR_HANDLE_PIN); + sensor_not_home_activated_current_state = digitalRead(SENSOR_DISABLE_PIN); + sensor_door_closed_current_state = digitalRead(SENSOR_CLOSE_PIN); btn_lock_current_state = digitalRead(BTN_LOCK_PIN); btn_unlock_current_state = digitalRead(BTN_UNLOCK_PIN); // Debounce - if (sensor_lock_current_state != sensor_lock_prev_state) { - if (++sensor_lock_debounce == SIGNAL_DEBOUNCE_CONSTANT) { - if (sensor_lock_current_state == LOW) { - sensor_lock = false; + if (sensor_door_locked_current_state != sensor_door_locked_prev_state) { + if (++sensor_door_locked_debounce == SIGNAL_DEBOUNCE_CONSTANT) { + if (sensor_door_locked_current_state == LOW) { + sensor_door_locked = false; } else{ - sensor_lock = true; + sensor_door_locked = true; } - sensor_lock_prev_state = sensor_lock_current_state; - sensor_lock_debounce = 0; + sensor_door_locked_prev_state = sensor_door_locked_current_state; + sensor_door_locked_debounce = 0; + sensor_door_locked_changed = true; } } else { - sensor_lock_debounce = 0; + sensor_door_locked_debounce = 0; } - if (sensor_handle_current_state != sensor_handle_prev_state) { - if (++sensor_handle_debounce == SIGNAL_DEBOUNCE_CONSTANT) { - if (sensor_handle_current_state == LOW) { - sensor_handle = true; + if (sensor_handle_in_up_position_current_state != sensor_handle_in_up_position_prev_state) { + if (++sensor_handle_in_up_position_debounce == SIGNAL_DEBOUNCE_CONSTANT) { + if (sensor_handle_in_up_position_current_state == LOW) { + sensor_handle_in_up_position = true; } else{ - sensor_handle = false; + sensor_handle_in_up_position = false; } - sensor_handle_prev_state = sensor_handle_current_state; - sensor_handle_debounce = 0; + sensor_handle_in_up_position_prev_state = sensor_handle_in_up_position_current_state; + sensor_handle_in_up_position_debounce = 0; } } else { - sensor_handle_debounce = 0; + sensor_handle_in_up_position_debounce = 0; } - if (sensor_disable_current_state != sensor_disable_prev_state) { - if (++sensor_disable_debounce == SIGNAL_DEBOUNCE_CONSTANT) { - if (sensor_disable_current_state == LOW) { - sensor_disable = false; + if (sensor_not_home_activated_current_state != sensor_not_home_activated_prev_state) { + if (++sensor_not_home_activated_debounce == SIGNAL_DEBOUNCE_CONSTANT) { + if (sensor_not_home_activated_current_state == LOW) { + sensor_not_home_activated = false; } else{ - sensor_disable = true; + sensor_not_home_activated = true; } - sensor_disable_prev_state = sensor_disable_current_state; - sensor_disable_debounce = 0; + sensor_not_home_activated_prev_state = sensor_not_home_activated_current_state; + sensor_not_home_activated_debounce = 0; + sensor_not_home_activated_changed = true; } } else { - sensor_disable_debounce = 0; + sensor_not_home_activated_debounce = 0; } - if (sensor_close_current_state != sensor_close_prev_state) { - if (++sensor_close_debounce == SIGNAL_DEBOUNCE_CONSTANT) { - if (sensor_close_current_state == LOW) { - sensor_close = false; + if (sensor_door_closed_current_state != sensor_door_closed_prev_state) { + if (++sensor_door_closed_debounce == SIGNAL_DEBOUNCE_CONSTANT) { + if (sensor_door_closed_current_state == LOW) { + sensor_door_closed = true; } else{ - sensor_close = true; + sensor_door_closed = false; } - sensor_close_prev_state = sensor_close_current_state; - sensor_close_debounce = 0; + sensor_door_closed_prev_state = sensor_door_closed_current_state; + sensor_door_closed_debounce = 0; + sensor_door_closed_changed = true; } } else { - sensor_close_debounce = 0; + sensor_door_closed_debounce = 0; } if (btn_lock_current_state != btn_lock_prev_state) { if (++btn_lock_debounce == SIGNAL_DEBOUNCE_CONSTANT) { @@ -197,7 +322,6 @@ void update_buttons(){ // the setup routine runs once when you press reset: void setup() { - RFID.begin(9600); pinMode(SENSOR_LOCK_PIN, INPUT_PULLUP); pinMode(SENSOR_HANDLE_PIN, INPUT_PULLUP); @@ -215,14 +339,18 @@ void setup() { digitalWrite(SERVO_ENABLE_PIN, LOW); set_servo(SERVO_CENTER, SOURCE_SYSTEM); + + CONSOLE_SERIAL.begin(9600); + RFID_SERIAL.begin(9600); } // the loop routine runs over and over again forever: void loop() { current_timestamp = millis(); - - update_buttons(); + // Update all buttons and sensors + update_buttons(); + update_rfid(); // Check button status if (btn_lock == true){ @@ -235,7 +363,25 @@ void loop() { btn_unlock = false; } - // Lock disable timeout + // Check if sensor changed and report to Z-Wave + if (sensor_door_locked_changed){ + sensor_door_locked_changed = false; + zunoSendReport(1); + } + + // Check if sensor changed and report to Z-Wave + if (sensor_not_home_activated_changed){ + sensor_not_home_activated_changed = false; + zunoSendReport(2); + } + + // Check if sensor changed and report to Z-Wave + if (sensor_door_closed_changed){ + sensor_door_closed_changed = false; + zunoSendReport(8); + } + + // Check if servo needs to be centered or turned off if (servo_status > SERVO_DISABLE) { if (current_timestamp >= servo_timestamp) { if (servo_status < SERVO_CENTER) { @@ -246,8 +392,33 @@ void loop() { } } + // Check if store RFID has timed out + if (rfid_store_tag) { + if (current_timestamp >= rfid_timeout_timestamp) { + + if (rfid_store_tag_nbr == 0){ + rfid_tag_1 = false; + } + else if (rfid_store_tag_nbr == 1){ + rfid_tag_2 = false; + } + else if (rfid_store_tag_nbr == 2){ + rfid_tag_3 = false; + } + else if (rfid_store_tag_nbr == 3){ + rfid_tag_4 = false; + } + else if (rfid_store_tag_nbr == 4){ + rfid_tag_5 = false; + } + + rfid_store_tag = false; + zunoSendReport(3 + rfid_store_tag_nbr); + + } + } - // LED display + // Indicate that the door is being locked if (servo_status == SERVO_LOCK){ if (current_timestamp >= activity_timestamp) { if (activity_flash == 0){ @@ -263,6 +434,7 @@ void loop() { activity_timestamp = current_timestamp + 50; } } + // Indicate that the door is being unlocked else if (servo_status == SERVO_UNLOCK){ if (current_timestamp >= activity_timestamp) { if (activity_flash == 0){ @@ -279,22 +451,8 @@ void loop() { } } else if (servo_status == SERVO_DISABLE){ - if (sensor_close == false || sensor_handle == false){ - if (current_timestamp >= activity_timestamp) { - if (activity_flash == 0){ - digitalWrite(LED_LOCK_PIN, LOW); - digitalWrite(LED_UNLOCK_PIN, HIGH); - activity_flash = 1; - } - else{ - digitalWrite(LED_LOCK_PIN, LOW); - digitalWrite(LED_UNLOCK_PIN, LOW); - activity_flash = 0; - } - activity_timestamp = current_timestamp + 500; - } - } - else if (sensor_disable == true){ + // Indicate that the lock/unlock is disabled + if (sensor_not_home_activated == true || lock_disable == true){ if (current_timestamp >= activity_timestamp) { if (activity_flash == 0){ digitalWrite(LED_LOCK_PIN, HIGH); @@ -309,10 +467,28 @@ void loop() { activity_timestamp = current_timestamp + 500; } } - else if (sensor_lock == true){ + // Indicate that the door is open + else if (sensor_door_closed == false || sensor_handle_in_up_position == false){ + if (current_timestamp >= activity_timestamp) { + if (activity_flash == 0){ + digitalWrite(LED_LOCK_PIN, LOW); + digitalWrite(LED_UNLOCK_PIN, HIGH); + activity_flash = 1; + } + else{ + digitalWrite(LED_LOCK_PIN, LOW); + digitalWrite(LED_UNLOCK_PIN, LOW); + activity_flash = 0; + } + activity_timestamp = current_timestamp + 500; + } + } + // Indicate that the door is locked + else if (sensor_door_locked == true){ digitalWrite(LED_LOCK_PIN, HIGH); digitalWrite(LED_UNLOCK_PIN, LOW); } + // Indicate that the door is unlocked else{ digitalWrite(LED_LOCK_PIN, LOW); digitalWrite(LED_UNLOCK_PIN, HIGH); @@ -320,10 +496,148 @@ void loop() { } } -void setter(byte value) { +void setterLock(byte value) { + if (value == 0){ + set_servo(SERVO_UNLOCK, SOURCE_ZWAVE); + } + else{ + set_servo(SERVO_LOCK, SOURCE_ZWAVE); + } } -byte getter(void) { - // return previously saved (in getter()) value - return currentLEDValue; +byte getterLock(void) { + return sensor_door_locked; } + +void setterLockDisable(byte value) { + if (value == 0){ + lock_disable = false; + } + else{ + lock_disable = true; + } +} + +byte getterLockDisable(void) { + if (lock_disable || sensor_not_home_activated){ + return true; + } + else{ + return false; + } +} + +byte getterDoor(void) { + return sensor_door_closed; +} + +void setterRfidTag1(byte value) { + if (value == 0){ + int rfid_eeprom_pos = 0 * RFID_TAG_BYTES; + for (int i = 0; i < RFID_TAG_BYTES; i++) { + EEPROM.write(rfid_eeprom_pos,0xFF); + rfid_eeprom_pos++; + } + rfid_tag_1 = false; + } + else{ + if (rfid_store_tag == false){ + rfid_store_tag_nbr = 0; + rfid_store_tag = true; + rfid_timeout_timestamp = current_timestamp + 10000; + } + } +} + +byte getterRfidTag1(void) { + return rfid_tag_1; +} + +void setterRfidTag2(byte value) { + if (value == 0){ + int rfid_eeprom_pos = 1 * RFID_TAG_BYTES; + for (int i = 0; i < RFID_TAG_BYTES; i++) { + EEPROM.write(rfid_eeprom_pos,0xFF); + rfid_eeprom_pos++; + } + rfid_tag_2 = false; + } + else{ + if (rfid_store_tag == false){ + rfid_store_tag_nbr = 1; + rfid_store_tag = true; + rfid_timeout_timestamp = current_timestamp + 10000; + } + } +} + +byte getterRfidTag2(void) { + return rfid_tag_2; +} + +void setterRfidTag3(byte value) { + if (value == 0){ + int rfid_eeprom_pos = 2 * RFID_TAG_BYTES; + for (int i = 0; i < RFID_TAG_BYTES; i++) { + EEPROM.write(rfid_eeprom_pos,0xFF); + rfid_eeprom_pos++; + } + rfid_tag_3 = false; + } + else{ + if (rfid_store_tag == false){ + rfid_store_tag_nbr = 2; + rfid_store_tag = true; + rfid_timeout_timestamp = current_timestamp + 10000; + } + } +} + +byte getterRfidTag3(void) { + return rfid_tag_3; +} + +void setterRfidTag4(byte value) { + if (value == 0){ + int rfid_eeprom_pos = 3 * RFID_TAG_BYTES; + for (int i = 0; i < RFID_TAG_BYTES; i++) { + EEPROM.write(rfid_eeprom_pos,0xFF); + rfid_eeprom_pos++; + } + rfid_tag_4 = false; + } + else{ + if (rfid_store_tag == false){ + rfid_store_tag_nbr = 3; + rfid_store_tag = true; + rfid_timeout_timestamp = current_timestamp + 10000; + } + } +} + +byte getterRfidTag4(void) { + return rfid_tag_4; +} + +void setterRfidTag5(byte value) { + if (value == 0){ + int rfid_eeprom_pos = 4 * RFID_TAG_BYTES; + for (int i = 0; i < RFID_TAG_BYTES; i++) { + EEPROM.write(rfid_eeprom_pos,0xFF); + rfid_eeprom_pos++; + } + rfid_tag_5 = false; + } + else{ + if (rfid_store_tag == false){ + rfid_store_tag_nbr = 4; + rfid_store_tag = true; + rfid_timeout_timestamp = current_timestamp + 10000; + } + } +} + +byte getterRfidTag5(void) { + return rfid_tag_5; +} +