Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Reddit arduino alarm (re-written) version 2.0
- April 30, 2019
- This version is changed somewhat.
- 1. This has serial.print() statements through it, to allow troubleshooting events. They can be disabled with the first variable declared.
- 2. All of the password-entry screens are the same in that the password is shown on the bottom line. The top three lines can be changed but the bottom line must be left empty.
- 3. This version does not leave the lasers on all the time. It only turns them on long enough to stabilize and then check the sensor.
- 4. This version checks the lasers on a time interval that does not use delay().
- 5. This version checks the keypad on a time interval that does not use delay().
- 6. There are a couple delay() commands used for splash screens but the times are short.
- */
- #include <LiquidCrystal.h> // includes the LiquidCrystal Library (standard Arduino library)
- #include <Keypad.h> // includes the Keypad Library (standard Arduino library)
- // Added variable:
- bool show_serial_messages = true; // This is a switch to enable or disable all the serial messages, for troubleshooting.
- // PIN NUMBERS
- int LaserEmitterWindow = 11;
- int LaserEmitterDoor = 13;
- //Assigning pin numbers to receivers
- int LaserDetectorWindow = 10;
- int LaserDetectorDoor = 12;
- //Assigning pin number to piezo buzzer
- int Buzzer = 46;
- // Below are two variables that tell how the alarm is activated.
- // There is a current and past version, in order to react to transitions between different states.
- int alarm_main_mode__current_state = 0;
- int alarm_main_mode__previous_state = 0;
- const int alarm_main_mode__not_activated = 0;
- const int alarm_main_mode__activated = 1; // This means activated in either [stay] or [away] mode.
- const int alarm_main_mode__alarm_triggered = 2; // 2 = alarm has been triggered.
- const int alarm_main_mode__change_password = 3; // This mode is only accessible from the alarm_main_mode__not_activated mode.
- int alarm_activation_type = 1; // This value is used to indicate what mode the alarm is activated in.
- const int alarm_activation_type__stay_mode = 1;
- const int alarm_activation_type__away_mode = 2;
- // When the alarm is triggered, there are two different stages that may occur (a countdown and sounding the beeper).
- // So another state variable is needed for that.
- int alarm_trigger_status = 1;
- const int alarm_trigger_status__countdown_mode = 1;
- const int alarm_trigger_status__sounding_mode = 2;
- // Below are variables to use for the 30-second countdown timer.
- bool countdown_timer_in_use = false; // This is a flag telling if the countdown timer is in use.
- int countdown_limit = 30; // This is the time in seconds for the count down timer.
- int countdown_counter = 0; // This is used for counting the seconds as they elapse.
- unsigned long countdown_beginOneSecond_time = 0;
- unsigned long countdown_currentOneSecond_time = 0;
- // This program doesn't leave the lasers on all the time. It only turns them on to check the beam, then turns them off again.
- // Semiconductor lasers tend to "bounce" when turning on, due to the cheap power regulators they usually use.
- // For this reason you want to turn them on and then wait a bit, about .1 seconds.
- // So the laser_state flag has a stage for 'turning on'.
- int laser_state = 0; // This is a single digit that tells what state the two lasers are in. Both lasers will use this one variable.
- const int laser_state__off ;// 0 = turned off
- const int laser_state__turning_on ;// 1 = powering up delay. (These lasers take a bit of time to reach a stable level).
- const int laser_state__on ;// 2 = laser is turned on. Read the value of the laser sensor(s).
- const int laser_state__blocked ;// 3 = either laser has been blocked, triggering the alarm. This value is necessary because after being triggered, neither laser is checked until the alarm is reset.
- // Below is the variables that will be used for waiting after the lasers are turned on.
- int laser_power_up_delay = 100; // This is a time delay, stated in milliseconds.
- unsigned long laser_startup_previous_time = 0; // used for laser start timing.
- unsigned long laser_startup_current_time = 0;
- int laser_triggered_state = 1; // This tells which laser was triggered to set off the alarm.
- const int laser_triggered_state__window = 1;
- const int laser_triggered_state__door = 2;
- // The original code had a section to handle if both lasers were triggered at once.
- // Note: since there is no possible way to check both sensors literally at the same time, the laser_triggered_state only holds values indicating the first laser that was blocked.
- // Since we want the lasers to trigger the first time they detect interference and not turn off when the beam is simply un-blocked,
- // we need to track their past and current states separately.
- // Since a digitalRead() call is performed on the laser sensors and the value stored, 1 = not blocked and 0 = blocked.
- int laser_window_sensor_previous_state = 1;
- int laser_window_sensor_current_state = 1;
- int laser_door_sensor_previous_state = 1;
- int laser_door_sensor_current_state = 1;
- const int laser_sensor_blocked = 0;
- const int laser_sensor_not_blocked = 1;
- // Checking the keypad inputs on every pass through the main loop uses a lot of processor time where it isn't needed, so this program doesn't do that.
- bool keypad_enabled = true; // This is used to enable and disable the keypad, to provide stating the interval that it is to be polled at.
- int keypad_check_interval = 250; // A time stated in milliseconds, that the keypad will be checked for presses.
- // (Note that this is different than the de-bounce time, that the Keypad library does already)
- // This is the time interval that the keypad is checked for presses at.
- unsigned long keypad_previous_time = 0; // used for keypad timing.
- unsigned long keypad_current_time = 0;
- bool lasers_enabled = true;
- int laser_check_interval = 1000; // This is the time interval (stated in milliseconds) that the lasers will be checked at.
- unsigned long laser_check_previous_time = 0; // used for laser check timing.
- unsigned long laser_check_current_time = 0;
- int password_mode = 0; // This is a state flag for the password. zero = not entered, 1 = current password entered, 2 = entering new password.
- const int password_mode__not_entered = 0;
- const int password_mode__current_password_is_entered = 1;
- const int password_mode__entering_new_password = 2;
- //String password = "1234"; // Used in enterPassword function as the current password to disable alarm or change password
- // Arduinos don't handle Strings real well, from a memory standpoint.
- // And the Keypad.h library function getChar() returns characters anyway, so I changed the passwords to arrays of chars.
- char password[] = {'1', '2', '3', '4'};
- int passwordLength = 4; // To allow variable-length passwords with a char array, the length must be tracked (this value is an actual count of chars).
- char enteredPassword[4]; // This is what will hold the entered password.
- int enteredPasswordLength = 0; // This value is an actual count of chars.
- int maximumPasswordLength = 4; // Maximum password length (an actual count of chars).
- int current_password_display_position = 0; // This is used to progressively count the password chars as they are entered.
- const byte ROWS = 4; //four rows
- const byte COLS = 4; //four columns
- //define the symbols on the buttons of the keypads
- char keyMap[ROWS][COLS] = {
- {'1', '2', '3', 'A'},
- {'4', '5', '6', 'B'},
- {'7', '8', '9', 'C'},
- {'*', '0', '#', 'D'}
- };
- byte rowPins[ROWS] = {18, 19, 20, 21}; //Row pinouts of the keypad
- byte colPins[COLS] = {14, 15, 16, 17}; //Column pinouts of the keypad
- Keypad myKeypad = Keypad( makeKeymap(keyMap), rowPins, colPins, ROWS, COLS);
- LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7)
- void setup() {
- Serial.begin (9600);
- unsigned int key_debounce = 50; // This is a time stated in milliseconds.
- myKeypad.setDebounceTime(key_debounce); // The keypad library defaults to 1 millisecond debounce (which makes sense from a code library standpoint) but is not real helpful IRL.
- lcd.begin(20, 4); //defines dimensions of lcd (20 columns by 4 rows)
- //Defines lasers and buzzer as outputs and receivers as inputs
- pinMode(LaserEmitterWindow, OUTPUT);
- pinMode(LaserDetectorWindow, INPUT);
- pinMode(LaserEmitterDoor, OUTPUT);
- pinMode(LaserDetectorDoor, INPUT);
- pinMode(Buzzer, OUTPUT);
- if (show_serial_messages == true) {
- // If you are using serial messages anyway, it is good to show a message when exiting the setup() function.
- // Errors can occur inside setup() causing it to crash and skip the rest of setup(), but the processor still proceeds on to run the rest of the code.
- // This can cause program errors that are rather mystifying, because they occur in the main loop, but aren't caused by anything in the main loop.
- // The message below will *usually* only show if setup() has been completed successfully.
- Serial.println("Exiting setup()");
- }
- }
- // It is not necessary to declare function prototypes in the Arduino IDE any more, if they are either on the main tab or on sub-tabs.
- // Note that all global variables must still be declared on the main tab.
- void loop() { //start of main loop
- // The lasers need to be checked in the main loop because the lasers change alarm_main_mode from [alarm activated] to [alarm triggered] when blocked.
- check_laser_status();
- // The keypad needs to be checked in the main loop because it performs the alarm_main_mode changes of [alarm not activated] and [alarm activated].
- check_keypad_status();
- // The countdown timer must be checked in the main loop because it is not part of the laser code or the keypad code.
- check_countdown_timer();
- } //end of main loop
- // Note: I had this done in separate tabs in the arduino IDE but none of the code sites allow posting grouped files.
- // So for this I coped and pasted it all into one file, but it is much more convenient to work with in tabs.
- // The triple lines of asterisks below are dividers for each 'tab'.
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // tab name = buzzer_functions
- /*
- This tab is just for the buzzer functions, even though there isn't a lot of them.
- */
- void turn_buzzer_on() {
- digitalWrite(Buzzer, HIGH);
- }
- void turn_buzzer_off() {
- digitalWrite(Buzzer, LOW);
- }
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // tab name = countdown_timer
- /*
- This is just the function to operate the 30-second countdown timer in [away] mode.
- (-this code is really a one-second timer that repeats 30 times-)
- */
- // Below are variables to use for the 30-second countdown timer.
- // bool countdown_timer_in_use = false; // This is a flag telling if the countdown timer is in use.
- // int countdown_limit = 30; // This is the time in seconds for the count down timer.
- // int countdown_counter = 0; // This is used for counting the seconds as they elapse.
- // unsigned long countdown_beginOneSecond_time = 0;
- // unsigned long countdown_currentOneSecond_time = 0;
- void reset_countdown_timer() {
- // All this does is reset the starting seconds value, so the LCD can display it.
- // This must be called before start_countdown_timer()
- countdown_counter = countdown_limit;
- }
- void start_countdown_timer() {
- // This starts the countdown timer running.
- countdown_timer_in_use = true;
- countdown_beginOneSecond_time = millis();
- }
- void check_countdown_timer() {
- countdown_currentOneSecond_time = millis();
- if (countdown_currentOneSecond_time >= countdown_beginOneSecond_time) {
- if (countdown_currentOneSecond_time >= (countdown_beginOneSecond_time + 1000)) {
- countdown_counter -= 1;
- lcd_message_update_countdown_timer_value();
- if (countdown_counter == 0) {
- countdown_timer_in_use = false;
- countdown_timer_expired();
- }
- }
- }
- else {
- countdown_beginOneSecond_time = millis(); // millis() rollover condition
- }
- }
- void countdown_timer_expired() {
- // This function is what gets called when the coutdown timer runs out.
- alarm_trigger_status = alarm_trigger_status__sounding_mode;
- turn_buzzer_on();
- }
- void stop_countdown_timer() {
- // The only thing needed to stop the timer is to change the value below.
- countdown_timer_in_use = false;
- }
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // tab name = keypad_functions
- /*
- This tab is only for functions relating to the keypad.
- References-----
- ASCII value of zero is 48
- ASCII value of 9 is 57
- Therefore you can obtain the int value of a digit char by subtracting 48 from it.
- A = 65
- B = 66
- C = 67
- D = 68
- # = 35
- (asterisk) = 42
- */
- void check_keypad_status() {
- // This function is just for detecting transitions between alarm_main_mode__ values.
- // All of the if() statements here require that alarm_main_mode__previous_state and alarm_main_mode__current_state are different values.
- // Toward the end of this function, alarm_main_mode__current_state is copied into alarm_main_mode__previous_state, so that these if() statements only execute once per transition.
- if (alarm_main_mode__previous_state == -1 && alarm_main_mode__current_state == alarm_main_mode__not_activated) {
- // Meeting these conditions means the arduino has powered up, and so the welcome screen needs to be shown.
- lcd_message_display_welcome_screen();
- }
- if (alarm_main_mode__previous_state == alarm_main_mode__activated && alarm_main_mode__current_state == alarm_main_mode__not_activated) {
- // transition from alarm=on to alarm=off.
- lcd_message_display_welcome_screen();
- }
- if (alarm_main_mode__previous_state == alarm_main_mode__not_activated && alarm_main_mode__current_state == alarm_main_mode__activated) {
- if (alarm_activation_type == alarm_activation_type__stay_mode) {
- lcd_message_alarm_activated_in_stay_mode();
- }
- if (alarm_activation_type == alarm_activation_type__away_mode) {
- lcd_message_alarm_activated_in_away_mode();
- }
- }
- if (alarm_main_mode__previous_state == alarm_main_mode__activated && alarm_main_mode__current_state == alarm_main_mode__alarm_triggered) {
- if (alarm_activation_type == alarm_activation_type__stay_mode) {
- // [stay] activation: immediately sound the alarm and change the LCD to password input mode.
- turn_buzzer_on();
- //lcd_message_change_to_password_input_mode(); // ???????????????????????????????????????????????????????????????????????????????? needs to change for sensor type
- lcd_message_display_trigger_and_prompt_for_password();
- alarm_trigger_status = alarm_trigger_status__sounding_mode;
- if (show_serial_messages == true) {
- Serial.println("Alarm triggered in stay mode");
- }
- }
- if (alarm_activation_type == alarm_activation_type__away_mode) {
- // [away] mode: change the LCD and keypad mode and start the 30-second timer.
- reset_countdown_timer();
- lcd_message_change_to_long_countdown_mode();
- alarm_trigger_status = alarm_trigger_status__countdown_mode;
- start_countdown_timer();
- if (show_serial_messages == true) {
- Serial.println("Alarm triggered in away mode");
- }
- }
- }
- if (alarm_main_mode__previous_state == alarm_main_mode__alarm_triggered && alarm_main_mode__current_state == alarm_main_mode__not_activated) {
- // transition from alarm=triggered to alarm=off.
- lcd_message_display_welcome_screen();
- }
- if (alarm_main_mode__previous_state == alarm_main_mode__change_password && alarm_main_mode__current_state == alarm_main_mode__not_activated) {
- // Meeting these conditions means that the mode is returning from changing the password.
- lcd_message_display_welcome_screen();
- }
- alarm_main_mode__previous_state = alarm_main_mode__current_state;
- if (keypad_enabled == true) {
- check_keypad_for_presses(); // This checks the keypad for input.
- start_keypad_delay_interval(); // This starts the delay timer to limit how much time is spend checking the keypad for input.
- }
- else {
- check_keypad_delay_timer(); // This checks the timer that re-enables the keypad after the set time interval has passed.
- }
- }
- void check_keypad_for_presses() {
- // This checks the keypad for input.
- // All of these conditions are steady-state conditions, not transitional conditions.
- // At this point keypad_alarm_main_mode_previous_state equals the value of keypad_alarm_main_mode_current_state, so only one of them needs to be checked here.
- //int alarm_main_mode = 0; // This is a single digit that tells how the alarm is activated.
- //const int alarm_main_mode__not_activated = 0;
- //const int alarm_main_mode__activated = 1; // This means activated in either [stay] or [away] mode.
- //const int alarm_main_mode__alarm_triggered = 2; // 2 = alarm has been triggered.
- //const int alarm_main_mode__change_password = 3; // This mode is only accessible from the alarm_main_mode__not_activated mode.
- char buttonPress = myKeypad.getKey();
- if (alarm_main_mode__current_state == alarm_main_mode__not_activated) {
- // The allowable inputs at this state [lcd_message_display_welcome_screen()] are A, B and C.
- if (keypad_char_is_A(buttonPress)) {
- // A = activate away
- alarm_main_mode__current_state = alarm_main_mode__activated;
- alarm_activation_type = alarm_activation_type__away_mode;
- if (show_serial_messages == true) {
- Serial.println("Activate alarm in away mode");
- }
- }
- if (keypad_char_is_B(buttonPress)) {
- // B = activate stay
- alarm_main_mode__current_state = alarm_main_mode__activated;
- alarm_activation_type = alarm_activation_type__stay_mode;
- if (show_serial_messages == true) {
- Serial.println("Activate alarm in stay mode");
- }
- }
- if (keypad_char_is_C(buttonPress)) {
- // C = change password
- alarm_main_mode__current_state = alarm_main_mode__change_password;
- reset_enteredPassword_array();
- lcd_message_change_password_enter_current_password();
- if (show_serial_messages == true) {
- Serial.println("Enter password change mode");
- }
- }
- }
- else if (alarm_main_mode__current_state == alarm_main_mode__activated) {
- // This means the alarm is activated but not triggered.
- // The only allowable input at this state is to enter the password to disable the alarm.
- enter_password_to_disable_or_reset_alarm(buttonPress);
- }
- else if (alarm_main_mode__current_state == alarm_main_mode__alarm_triggered) {
- // This means the alarm has been triggered.
- // The only allowable input at this state is to enter the password to disable the alarm.
- enter_password_to_disable_or_reset_alarm(buttonPress);
- }
- else if (alarm_main_mode__current_state == alarm_main_mode__change_password) {
- // This means the password is being changed.
- bool oldPasswordEntered = false;
- bool newPasswordEntered = false;
- if (password_mode == password_mode__not_entered) { // This means that the current password has not been entered.
- if (enteredPasswordLength < (maximumPasswordLength - 1)) {
- oldPasswordEntered = enter_password_character(buttonPress);
- lcd_display_show_entered_password_character();
- if (show_serial_messages == true) {
- Serial.println("Entering current password");
- }
- }
- if (oldPasswordEntered == true) {
- // If they are done entering the current password, compare it.
- compare_entered_password(); // This changes password_mode to 1 if the two passwords match.
- if (password_mode == password_mode__not_entered) {
- // You have failed
- reset_enteredPassword_array();
- lcd_message_change_password_current_entry_failed();
- }
- else if (password_mode = password_mode__current_password_is_entered) {
- // Show the screen to enter the new password.
- lcd_message_change_password_enter_new_password();
- }
- }
- }
- else if (password_mode == password_mode__current_password_is_entered) { // This means that the new password is being entered.
- if (enteredPasswordLength < (maximumPasswordLength - 1)) {
- newPasswordEntered = enter_password_character(buttonPress);
- lcd_display_show_entered_password_character();
- if (show_serial_messages == true) {
- Serial.println("Entering new password");
- }
- }
- if (newPasswordEntered == true) {
- // If they are done entering the new password, then copy it into the regular password array.
- // (first show the two passwords in the serial messages however)
- if (show_serial_messages == true) {
- Serial.println("Changing password");
- Serial.print("Old password = ");
- char tempChar;
- for (int x = 0; x < (passwordLength - 1); x++) {
- tempChar = password[x];
- Serial.print(tempChar);
- }
- Serial.print("New password = ");
- for (int x = 0; x < (passwordLength - 1); x++) {
- tempChar = enteredPassword[x];
- Serial.print(tempChar);
- }
- }
- change_old_password_to_new_password();
- alarm_main_mode__current_state = alarm_main_mode__not_activated;
- }
- }
- }
- }
- void enter_password_to_disable_or_reset_alarm(char buttonPress) {
- bool passwordEntered = false;
- if (password_mode == password_mode__not_entered) { // This means that the current password has not been entered.
- if (enteredPasswordLength < (maximumPasswordLength - 1)) {
- passwordEntered = enter_password_character(buttonPress);
- lcd_display_show_entered_password_character();
- if (show_serial_messages == true) {
- Serial.println("Entering current password to disable alarm");
- }
- }
- if (passwordEntered == true) {
- // If they are done entering the current password, compare it.
- compare_entered_password(); // This changes password_mode to 1 if the two passwords match.
- if (password_mode == password_mode__not_entered) {
- // You have failed
- reset_enteredPassword_array();
- lcd_message_show_alarm_armed_enter_password_screen();
- }
- else if (password_mode = password_mode__current_password_is_entered) {
- alarm_main_mode__current_state = alarm_main_mode__not_activated;
- turn_buzzer_off();
- lcd_message_display_welcome_screen();
- }
- }
- }
- }
- void start_keypad_delay_interval() {
- // This starts the delay timer to limit how much time is spend checking the keypad for input.
- keypad_enabled = false;
- keypad_previous_time = millis();
- }
- void check_keypad_delay_timer() {
- // This checks the timer that re-enables the keypad after the set time interval has passed.
- keypad_current_time = millis();
- if (keypad_current_time >= keypad_previous_time) {
- if (keypad_current_time >= (keypad_previous_time + keypad_check_interval)) {
- keypad_enabled = true;
- }
- }
- else {
- keypad_previous_time = millis(); // rollover condition
- }
- }
- int get_keypad_digit_value(char buttonPress) {
- // This function is for detirmining if a character returned from the keypad is a numeral or not.
- // If the char is a digit, this returns the digit value.
- // If the char is not a digit, this returns a value of -1.
- int returnValue = -1;
- // ASCII value of zero is 48
- // ASCII value of 9 is 57
- // Therefore you can obtain the int value of a digit char by subtracting 48 from it.
- if (buttonPress > 47 && buttonPress < 58) {
- // returnValue was initialized to -1 however, so only 47 is subtracted from it, so char[zero] results in [int] zero.
- returnValue = buttonPress - 47;
- }
- return returnValue;
- }
- bool keypad_char_is_A(char buttonValue) {
- // This function answers true if the character is A.
- bool answer = false;
- if (buttonValue == 65) {
- answer = true;
- }
- return answer;
- }
- bool keypad_char_is_B(char buttonValue) {
- // This function answers true if the character is B.
- bool answer = false;
- if (buttonValue == 66) {
- answer = true;
- }
- return answer;
- }
- bool keypad_char_is_C(char buttonValue) {
- // This function answers true if the character is C.
- bool answer = false;
- if (buttonValue == 67) {
- answer = true;
- }
- return answer;
- }
- bool keypad_char_is_D(char buttonValue) {
- // This function answers true if the character is D.
- bool answer = false;
- if (buttonValue == 68) {
- answer = true;
- }
- return answer;
- }
- bool keypad_char_is_poundSign(char buttonValue) {
- // This function answers true if the character is #.
- bool answer = false;
- if (buttonValue == 35) {
- answer = true;
- }
- return answer;
- }
- bool keypad_char_is_asterisk(char buttonValue) {
- // This function answers true if the character is *.
- bool answer = false;
- if (buttonValue == 42) {
- answer = true;
- }
- return answer;
- }
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // tab name = laser_functions
- /*
- This tab is only for functions related to the lasers themselves.
- */
- void check_laser_status() {
- if (alarm_main_mode__current_state == alarm_main_mode__activated) { // The lasers only get checked, if the alarm is activated and the alarm is not already triggered.
- if (lasers_enabled == true) {
- check_for_laser_interference(); // This function is the one that checks to see if either laser is blocked.
- reset_laser_delay_timer(); // This function sets lasers_enabled to false and starts the interval timer.
- }
- else {
- check_laser_delay_timer(); // This function checks the laser interval timer, and changes lasers_enabled back to true when enough time has passed.
- }
- }
- }
- void check_for_laser_interference() {
- // This function is the one that checks to see if either laser is blocked.
- switch (laser_state) {
- case 0:
- // Zero means laser_state__off
- // You can't use variables for cases in a switch-case statement (even variables declared as const)
- // #define might work but can cause other issues, so I didn't do that.
- digitalWrite(LaserEmitterWindow, HIGH); // Turn the lasers on.
- digitalWrite(LaserEmitterDoor, HIGH);
- laser_startup_previous_time = millis(); // Set the "previous" time value.
- laser_state = laser_state__turning_on; // Change to the next state.
- break;
- case 1:
- // 1 means laser_state__turning_on
- laser_startup_current_time = millis();
- if (laser_startup_previous_time >= laser_startup_current_time) {
- if (laser_startup_previous_time >= (laser_startup_current_time + laser_power_up_delay)) {
- laser_state = laser_state__on; // After the laser start-up delay has passed, change to the next state.
- }
- }
- else {
- laser_startup_current_time = millis(); // millis() rollover condition.
- }
- break;
- case 2:
- // 2 means laser_state__on
- laser_window_sensor_current_state = digitalRead(LaserDetectorWindow);
- if (laser_window_sensor_current_state = 0) {
- if (laser_window_sensor_previous_state = 1) {
- laser_state = laser_state__blocked;
- laser_triggered_state = laser_triggered_state__window;
- alarm_main_mode__current_state = alarm_main_mode__alarm_triggered;
- if (show_serial_messages == true) {
- Serial.println("Window laser triggered.");
- }
- }
- }
- laser_window_sensor_previous_state = laser_window_sensor_current_state;
- laser_door_sensor_current_state = digitalRead(LaserDetectorDoor);
- if (laser_door_sensor_current_state = 0) {
- if (laser_door_sensor_previous_state = 1) {
- laser_state = laser_state__blocked;
- laser_triggered_state = laser_triggered_state__door;
- alarm_main_mode__current_state = alarm_main_mode__alarm_triggered;
- if (show_serial_messages == true) {
- Serial.println("Door laser triggered.");
- }
- }
- }
- laser_door_sensor_previous_state = laser_door_sensor_current_state;
- // Turn both lasers off again:
- digitalWrite(LaserEmitterWindow, LOW);
- digitalWrite(LaserEmitterDoor, LOW);
- laser_state = laser_state__off; // Reset the laser state back to zero again.
- reset_laser_delay_timer(); // Reset the laser check interval back again.
- break;
- }
- }
- void reset_laser_delay_timer() {
- // This function sets lasers_enabled to false and starts the interval timer.
- lasers_enabled = false;
- laser_check_previous_time = millis();
- }
- void check_laser_delay_timer() {
- // This function checks the laser interval timer, and changes lasers_enabled back to true when enough time has passed.
- laser_check_current_time = millis();
- if (laser_check_previous_time >= laser_check_current_time) {
- if (laser_check_previous_time >= (laser_check_current_time + laser_check_interval)) {
- lasers_enabled = true;
- }
- }
- else {
- laser_check_current_time = millis(); // millis() rollover condition.
- }
- }
- void reset_lasers_after_triggering() {
- laser_state = laser_state__off; // This should be set to zero already, but anyway.
- laser_window_sensor_previous_state = laser_sensor_not_blocked;
- laser_window_sensor_current_state = laser_sensor_not_blocked;
- laser_door_sensor_previous_state = laser_sensor_not_blocked;
- laser_door_sensor_current_state = laser_sensor_not_blocked;
- }
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // tab name = lcd_message_displays
- /*
- This tab contains basic functions to clear one or all lines of the LCD.
- With these LCDs, the line doesn't get cleared unless you print spaces over the entire line.
- */
- void lcd_clear_all_lines() {
- lcd_clear_line1();
- lcd_clear_line2();
- lcd_clear_line3();
- lcd_clear_line4();
- }
- void lcd_clear_line1() {
- lcd.setCursor(0, 0);
- lcd.print(" "); // This is printing twenty spaces.
- }
- void lcd_clear_line2() {
- lcd.setCursor(0, 1);
- lcd.print(" "); // This is printing twenty spaces.
- }
- void lcd_clear_line3() {
- lcd.setCursor(0, 2);
- lcd.print(" "); // This is printing twenty spaces.
- }
- void lcd_clear_line4() {
- lcd.setCursor(0, 3);
- lcd.print(" "); // This is printing twenty spaces.
- }
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // tab name = lcd_message_displays
- /*
- This tab is just for the functions to show normal messages on the LCD.
- */
- void lcd_message_change_to_long_countdown_mode() {
- // This screen changes to the countdown mode and then starts the 30-second timer code.
- lcd_clear_all_lines();
- lcd.setCursor(0, 0);
- lcd.print("Alarm engaged in:");
- lcd.setCursor(0, 1);
- lcd_message_update_countdown_timer_value();
- lcd.setCursor(0, 2);
- lcd.print("Type PW to disable");
- lcd.setCursor(0, 3);
- lcd.print(">");
- }
- void lcd_message_update_countdown_timer_value() {
- // This function only prints the countdown_counter value to the LCD.
- lcd_clear_line2();
- lcd.setCursor(9, 1);
- lcd.print(countdown_counter);
- }
- void lcd_message_alarm_activated_in_stay_mode() {
- lcd_clear_all_lines();
- lcd.setCursor(0, 0);
- lcd.print("Alarm Activated!");
- lcd.setCursor(0, 1);
- lcd.print("Mode = [stay]");
- delay(2000);
- lcd_message_show_alarm_activated_final_message();
- }
- void lcd_message_alarm_activated_in_away_mode() {
- lcd_clear_all_lines();
- lcd.setCursor(0, 0);
- lcd.print("Alarm Activated!");
- lcd.setCursor(0, 1);
- lcd.print("Mode = [away]");
- delay(2000);
- lcd_message_show_alarm_activated_final_message();
- }
- void lcd_message_show_alarm_activated_final_message() {
- lcd_clear_all_lines();
- lcd.setCursor(0, 1);
- lcd.print(" *** ALARM *** ");
- lcd.setCursor(0, 2);
- lcd.print("Type PW to disable");
- lcd.setCursor(0, 3);
- lcd.print(">");
- }
- void lcd_message_display_trigger_and_prompt_for_password() {
- // This function displays a different screen depending on which laser was blocked.
- lcd_clear_all_lines();
- lcd.setCursor(0, 0);
- if (laser_triggered_state == laser_triggered_state__window) {
- lcd.print("Window - ALERT!");
- lcd.setCursor(0, 1);
- lcd.print("Door - Armed");
- }
- if (laser_triggered_state == laser_triggered_state__door) {
- lcd.print("Window - Armed");
- lcd.setCursor(0, 1);
- lcd.print("Door - ALERT!");
- }
- lcd.setCursor(0, 2);
- lcd.print("Type PW to disable");
- lcd.setCursor(0, 3);
- lcd.print(">");
- }
- void lcd_message_show_transition_to_alarm_armed() {
- // This shows a brief message for 2 seconds, before changing to lcd_message_show_alarm_armed_enter_password_screen()
- lcd_clear_all_lines();
- lcd.setCursor(0, 2);
- lcd.print("Window - Armed");
- lcd.setCursor(0, 3);
- lcd.print("Front Door - Armed");
- delay(2000);
- lcd_message_show_alarm_armed_enter_password_screen();
- }
- void lcd_message_show_alarm_armed_enter_password_screen() {
- // This is the normal message to show to enter the password, when the alarm is armed but not yet triggered.
- lcd_clear_all_lines();
- lcd.setCursor(0, 1);
- lcd.print("Type PW to disable");
- lcd.setCursor(0, 3);
- lcd.print(">");
- }
- void lcd_message_change_password_enter_current_password() {
- // This is the text that shows first, requiring the user to enter the current password correctly.
- // This gets called only once, to change to this screen.
- lcd_clear_all_lines();
- lcd.setCursor(0, 1);
- lcd.print("Current Password");
- lcd.setCursor(0, 3);
- lcd.print(">");
- }
- void lcd_display_show_entered_password_character() {
- // This function updates the currently-entered password as it is keyed in.
- // This gets called every time a new character is entered.
- // The password is always shown on the bottom line, for all the password-entry screens.
- lcd_clear_line4();
- lcd.setCursor(0, 3);
- lcd.print(">");
- char tempChar;
- int tempValue = enteredPasswordLength - 1;
- for (int x = 0; x < tempValue; x++) {
- lcd.setCursor((1 + x), 1);
- tempChar = enteredPassword[x];
- lcd.print(tempChar);
- }
- }
- void lcd_message_change_password_current_entry_failed() {
- // This message is shown if the entered password does not match.
- lcd_clear_all_lines();
- lcd.setCursor(0, 1);
- lcd.print("Wrong! Try Again");
- delay(2000);
- reset_enteredPassword_array();
- lcd_message_change_password_enter_current_password();
- }
- void lcd_message_change_password_enter_new_password() {
- // This is the text that shows second after the current password was entered correctly, allowing entering the new password.
- // This gets called only once, to change to this screen.
- lcd_clear_all_lines();
- lcd.setCursor(0, 1);
- lcd.print("Set New Password");
- lcd.setCursor(0, 3);
- lcd.print(">");
- }
- void lcd_message_display_welcome_screen() {
- lcd_clear_all_lines();
- lcd.setCursor(0, 0);
- lcd.print("***** Welcome *****");
- lcd.setCursor(0, 1);
- lcd.print("A - Activate Away");
- lcd.setCursor(0, 2);
- lcd.print("B - Activate Stay");
- lcd.setCursor(0, 3);
- lcd.print("C - Change Password");
- }
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- // tab name = password_functions
- /*
- This tab is only for the password-handling functions.
- char password[] = {'1', '2', '3', '4'}; // Since the Keypad.h library function getChar() returns characters, it is easiest to just store the password as an array of chars.
- char enteredPassword[4]; // This is what will hold the entered password.
- int lcd_screen_password_start_position = 5; // This is to allow the password to print after the text already placed on the line. See lcd_message_add_entered_password_char(int cPosition, int oneDigit) for use.
- int current_password_position = 0; // This is used to progressively count the password chars as they are entered.
- */
- void reset_enteredPassword_array() {
- // This just resets password_mode and the temporary password array to all-zero char values.
- password_mode = 0;
- enteredPasswordLength = 0;
- for (int x = 0; x < 4; x++) {
- enteredPassword[x] = 0;
- }
- }
- void reset_password_array() {
- // This just resets the regular password array to all-zero char values.
- passwordLength = 0;
- for (int x = 0; x < 4; x++) {
- password[x] = 0;
- }
- }
- bool enter_password_character(char buttonValue) {
- // This adds new characters into enteredPassword as they are entered.
- // This function allows any buttons as password characters except the asterisk, since that is the end-of-password marker.
- // The function returns false unless the added character is the asterisk.
- if (keypad_char_is_asterisk(buttonValue) == false) {
- if (enteredPasswordLength < (maximumPasswordLength - 1)) {
- enteredPassword[enteredPasswordLength] = buttonValue;
- enteredPasswordLength += 1;
- }
- return false;
- }
- else {
- // The user has entered the asterisk, that indicates the end of the password.
- return true;
- }
- }
- void compare_entered_password() {
- // This compares the entered password with the set one, and sets password_mode to 1 if they match.
- bool matchingValues = true;
- // First just compare the lengths to see if they match:
- if (passwordLength != enteredPasswordLength) {
- matchingValues = false;
- }
- // If the lengths of the two passwords were the same, then compare the chars in them:
- if (matchingValues == true) { // The character comparison must be skipped if the password lengths are not the same.
- for (int x = 0; x < (passwordLength - 1); x++) {
- if (password[x] != enteredPassword[x]) {
- matchingValues = false;
- }
- }
- }
- if (matchingValues == true ) {
- password_mode = password_mode__current_password_is_entered;
- }
- }
- void change_old_password_to_new_password() {
- // This changes the set password to the one entered.
- reset_password_array();
- for (int x = 0; x < (enteredPasswordLength - 1); x++) {
- password[x] = enteredPassword[x]; // copy the chars
- }
- passwordLength = enteredPasswordLength; // copy the length
- reset_enteredPassword_array();
- }
Add Comment
Please, Sign In to add comment