Implemented zwave and rfid

This commit is contained in:
Christoffer Martinsson 2018-02-19 08:21:36 +01:00
parent a04eda0881
commit 4e7e685b84

View File

@ -1,6 +1,8 @@
#include <ZUNO_SERVO.h> #include <ZUNO_SERVO.h>
#include <EEPROM.h>
#define RFID Serial #define CONSOLE_SERIAL Serial
#define RFID_SERIAL Serial1
#define SERVO_PIN 12 #define SERVO_PIN 12
const int SERVO_ENABLE_PIN = 9; const int SERVO_ENABLE_PIN = 9;
@ -21,10 +23,16 @@ const int LED_UNLOCK_PIN = 6;
#define SERVO_CENTER 3 #define SERVO_CENTER 3
#define SOURCE_EXTERNAL 0 #define SOURCE_EXTERNAL 0
#define SOURCE_RFID 1 #define SOURCE_RFID_1 1
#define SOURCE_ZWAVE 2 #define SOURCE_RFID_2 2
#define SOURCE_BUTTONS 3 #define SOURCE_RFID_3 3
#define SOURCE_SYSTEM 4 #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 // Last saved LED value
byte currentLEDValue = 0; byte currentLEDValue = 0;
@ -32,140 +40,257 @@ unsigned long int rfid = 0;
#define SIGNAL_DEBOUNCE_CONSTANT 30 #define SIGNAL_DEBOUNCE_CONSTANT 30
bool sensor_lock = false; bool sensor_door_locked = false;
bool sensor_handle = false; bool sensor_handle_in_up_position = false;
bool sensor_disable = false; bool sensor_not_home_activated = false;
bool sensor_close = false; bool sensor_door_closed = false;
int sensor_lock_prev_state = HIGH; bool sensor_door_locked_changed = false;
int sensor_lock_current_state = LOW; bool sensor_door_closed_changed = false;
int sensor_lock_debounce = 0; bool sensor_not_home_activated_changed = false;
int sensor_handle_prev_state = HIGH;
int sensor_handle_current_state = LOW; int sensor_door_locked_prev_state = -1;
int sensor_handle_debounce = 0; int sensor_door_locked_current_state = LOW;
int sensor_disable_prev_state = HIGH; int sensor_door_locked_debounce = 0;
int sensor_disable_current_state = LOW; int sensor_handle_in_up_position_prev_state = -1;
int sensor_disable_debounce = 0; int sensor_handle_in_up_position_current_state = LOW;
int sensor_close_prev_state = HIGH; int sensor_handle_in_up_position_debounce = 0;
int sensor_close_current_state = LOW; int sensor_not_home_activated_prev_state = -1;
int sensor_close_debounce = 0; 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_lock = false;
bool btn_unlock = 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_current_state = LOW;
int btn_lock_debounce = 0; 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_current_state = LOW;
int btn_unlock_debounce = 0; int btn_unlock_debounce = 0;
int activity_flash = 0; int activity_flash = 0;
int servo_status = 0; int servo_status = 0;
int lock_status = 0;
int source_status = 0; int source_status = 0;
unsigned long current_timestamp = 0; unsigned long current_timestamp = 0;
unsigned long activity_timestamp = 0; unsigned long activity_timestamp = 0;
unsigned long servo_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); ServoController servo(12);
ZUNO_SETUP_SLEEPING_MODE(ZUNO_SLEEPING_MODE_ALWAYS_AWAKE);
// set up channel // set up channel
ZUNO_SETUP_CHANNELS(ZUNO_SWITCH_MULTILEVEL(getter, setter)); ZUNO_SETUP_CHANNELS(
ZUNO_SETUP_DEBUG_MODE(DEBUG_ON); 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){ void set_servo(int mode, int source){
if (sensor_handle == true && sensor_disable == false && sensor_close == true){ bool ok_to_lock_unlock = false;
if (mode == SERVO_LOCK){
servo.setValue(160+2); // Check sensor status if ok to lock/unlock
lock_status = SERVO_LOCK; if (sensor_handle_in_up_position == true && sensor_not_home_activated == false && sensor_door_closed == true && lock_disable == false){
} ok_to_lock_unlock = true;
else if (mode == SERVO_UNLOCK){ }
servo.setValue(20+2);
lock_status = SERVO_UNLOCK; // Set servo position
} if (mode == SERVO_LOCK && ok_to_lock_unlock && sensor_door_locked == false){
else if (mode == SERVO_CENTER){ servo.setValue(160+SERVO_TRIM);
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;
}
servo_status = mode; servo_status = mode;
source_status = source; 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(){ void update_buttons(){
sensor_lock_current_state = digitalRead(SENSOR_LOCK_PIN); sensor_door_locked_current_state = digitalRead(SENSOR_LOCK_PIN);
sensor_handle_current_state = digitalRead(SENSOR_HANDLE_PIN); sensor_handle_in_up_position_current_state = digitalRead(SENSOR_HANDLE_PIN);
sensor_disable_current_state = digitalRead(SENSOR_DISABLE_PIN); sensor_not_home_activated_current_state = digitalRead(SENSOR_DISABLE_PIN);
sensor_close_current_state = digitalRead(SENSOR_CLOSE_PIN); sensor_door_closed_current_state = digitalRead(SENSOR_CLOSE_PIN);
btn_lock_current_state = digitalRead(BTN_LOCK_PIN); btn_lock_current_state = digitalRead(BTN_LOCK_PIN);
btn_unlock_current_state = digitalRead(BTN_UNLOCK_PIN); btn_unlock_current_state = digitalRead(BTN_UNLOCK_PIN);
// Debounce // Debounce
if (sensor_lock_current_state != sensor_lock_prev_state) { if (sensor_door_locked_current_state != sensor_door_locked_prev_state) {
if (++sensor_lock_debounce == SIGNAL_DEBOUNCE_CONSTANT) { if (++sensor_door_locked_debounce == SIGNAL_DEBOUNCE_CONSTANT) {
if (sensor_lock_current_state == LOW) { if (sensor_door_locked_current_state == LOW) {
sensor_lock = false; sensor_door_locked = false;
} }
else{ else{
sensor_lock = true; sensor_door_locked = true;
} }
sensor_lock_prev_state = sensor_lock_current_state; sensor_door_locked_prev_state = sensor_door_locked_current_state;
sensor_lock_debounce = 0; sensor_door_locked_debounce = 0;
sensor_door_locked_changed = true;
} }
} else { } else {
sensor_lock_debounce = 0; sensor_door_locked_debounce = 0;
} }
if (sensor_handle_current_state != sensor_handle_prev_state) { if (sensor_handle_in_up_position_current_state != sensor_handle_in_up_position_prev_state) {
if (++sensor_handle_debounce == SIGNAL_DEBOUNCE_CONSTANT) { if (++sensor_handle_in_up_position_debounce == SIGNAL_DEBOUNCE_CONSTANT) {
if (sensor_handle_current_state == LOW) { if (sensor_handle_in_up_position_current_state == LOW) {
sensor_handle = true; sensor_handle_in_up_position = true;
} }
else{ else{
sensor_handle = false; sensor_handle_in_up_position = false;
} }
sensor_handle_prev_state = sensor_handle_current_state; sensor_handle_in_up_position_prev_state = sensor_handle_in_up_position_current_state;
sensor_handle_debounce = 0; sensor_handle_in_up_position_debounce = 0;
} }
} else { } else {
sensor_handle_debounce = 0; sensor_handle_in_up_position_debounce = 0;
} }
if (sensor_disable_current_state != sensor_disable_prev_state) { if (sensor_not_home_activated_current_state != sensor_not_home_activated_prev_state) {
if (++sensor_disable_debounce == SIGNAL_DEBOUNCE_CONSTANT) { if (++sensor_not_home_activated_debounce == SIGNAL_DEBOUNCE_CONSTANT) {
if (sensor_disable_current_state == LOW) { if (sensor_not_home_activated_current_state == LOW) {
sensor_disable = false; sensor_not_home_activated = false;
} }
else{ else{
sensor_disable = true; sensor_not_home_activated = true;
} }
sensor_disable_prev_state = sensor_disable_current_state; sensor_not_home_activated_prev_state = sensor_not_home_activated_current_state;
sensor_disable_debounce = 0; sensor_not_home_activated_debounce = 0;
sensor_not_home_activated_changed = true;
} }
} else { } else {
sensor_disable_debounce = 0; sensor_not_home_activated_debounce = 0;
} }
if (sensor_close_current_state != sensor_close_prev_state) { if (sensor_door_closed_current_state != sensor_door_closed_prev_state) {
if (++sensor_close_debounce == SIGNAL_DEBOUNCE_CONSTANT) { if (++sensor_door_closed_debounce == SIGNAL_DEBOUNCE_CONSTANT) {
if (sensor_close_current_state == LOW) { if (sensor_door_closed_current_state == LOW) {
sensor_close = false; sensor_door_closed = true;
} }
else{ else{
sensor_close = true; sensor_door_closed = false;
} }
sensor_close_prev_state = sensor_close_current_state; sensor_door_closed_prev_state = sensor_door_closed_current_state;
sensor_close_debounce = 0; sensor_door_closed_debounce = 0;
sensor_door_closed_changed = true;
} }
} else { } else {
sensor_close_debounce = 0; sensor_door_closed_debounce = 0;
} }
if (btn_lock_current_state != btn_lock_prev_state) { if (btn_lock_current_state != btn_lock_prev_state) {
if (++btn_lock_debounce == SIGNAL_DEBOUNCE_CONSTANT) { if (++btn_lock_debounce == SIGNAL_DEBOUNCE_CONSTANT) {
@ -197,7 +322,6 @@ void update_buttons(){
// the setup routine runs once when you press reset: // the setup routine runs once when you press reset:
void setup() { void setup() {
RFID.begin(9600);
pinMode(SENSOR_LOCK_PIN, INPUT_PULLUP); pinMode(SENSOR_LOCK_PIN, INPUT_PULLUP);
pinMode(SENSOR_HANDLE_PIN, INPUT_PULLUP); pinMode(SENSOR_HANDLE_PIN, INPUT_PULLUP);
@ -215,14 +339,18 @@ void setup() {
digitalWrite(SERVO_ENABLE_PIN, LOW); digitalWrite(SERVO_ENABLE_PIN, LOW);
set_servo(SERVO_CENTER, SOURCE_SYSTEM); set_servo(SERVO_CENTER, SOURCE_SYSTEM);
CONSOLE_SERIAL.begin(9600);
RFID_SERIAL.begin(9600);
} }
// the loop routine runs over and over again forever: // the loop routine runs over and over again forever:
void loop() { void loop() {
current_timestamp = millis(); current_timestamp = millis();
update_buttons();
// Update all buttons and sensors
update_buttons();
update_rfid();
// Check button status // Check button status
if (btn_lock == true){ if (btn_lock == true){
@ -235,7 +363,25 @@ void loop() {
btn_unlock = false; 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 (servo_status > SERVO_DISABLE) {
if (current_timestamp >= servo_timestamp) { if (current_timestamp >= servo_timestamp) {
if (servo_status < SERVO_CENTER) { 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 (servo_status == SERVO_LOCK){
if (current_timestamp >= activity_timestamp) { if (current_timestamp >= activity_timestamp) {
if (activity_flash == 0){ if (activity_flash == 0){
@ -263,6 +434,7 @@ void loop() {
activity_timestamp = current_timestamp + 50; activity_timestamp = current_timestamp + 50;
} }
} }
// Indicate that the door is being unlocked
else if (servo_status == SERVO_UNLOCK){ else if (servo_status == SERVO_UNLOCK){
if (current_timestamp >= activity_timestamp) { if (current_timestamp >= activity_timestamp) {
if (activity_flash == 0){ if (activity_flash == 0){
@ -279,22 +451,8 @@ void loop() {
} }
} }
else if (servo_status == SERVO_DISABLE){ else if (servo_status == SERVO_DISABLE){
if (sensor_close == false || sensor_handle == false){ // Indicate that the lock/unlock is disabled
if (current_timestamp >= activity_timestamp) { if (sensor_not_home_activated == true || lock_disable == true){
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){
if (current_timestamp >= activity_timestamp) { if (current_timestamp >= activity_timestamp) {
if (activity_flash == 0){ if (activity_flash == 0){
digitalWrite(LED_LOCK_PIN, HIGH); digitalWrite(LED_LOCK_PIN, HIGH);
@ -309,10 +467,28 @@ void loop() {
activity_timestamp = current_timestamp + 500; 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_LOCK_PIN, HIGH);
digitalWrite(LED_UNLOCK_PIN, LOW); digitalWrite(LED_UNLOCK_PIN, LOW);
} }
// Indicate that the door is unlocked
else{ else{
digitalWrite(LED_LOCK_PIN, LOW); digitalWrite(LED_LOCK_PIN, LOW);
digitalWrite(LED_UNLOCK_PIN, HIGH); 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) { byte getterLock(void) {
// return previously saved (in getter()) value return sensor_door_locked;
return currentLEDValue;
} }
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;
}