From 18702567c3a24e83d19236c8f88b9afd9278d0db Mon Sep 17 00:00:00 2001 From: Lexzach <53662039+Lexzach@users.noreply.github.com> Date: Sat, 8 Oct 2022 22:18:30 -0400 Subject: [PATCH] started optimizing code --- facp/src/main.cpp | 470 ++++++++---------- instructions/antigneous_tech_instructions.odt | Bin 905920 -> 905432 bytes 2 files changed, 194 insertions(+), 276 deletions(-) diff --git a/facp/src/main.cpp b/facp/src/main.cpp index 35e0a2b..b774b84 100644 --- a/facp/src/main.cpp +++ b/facp/src/main.cpp @@ -23,13 +23,12 @@ int EEPROMBuild = 4; //----------------------------------------------------------------------------- RUNTIME VARIABLES bool fullAlarm = false; //bool to control if this is a full alarm that requres a panel reset to clear bool silenced = false; -bool keyInserted = false; //if the control panel has a key inserted -bool readyLedStatus = false; //ready led status (this variable is for the trouble response code) +bool panelUnlocked = false; //if the control panel has a key inserted bool horn = false; //bool to control if the horns are active bool strobe = false; //bool to control if the strobes are active bool trouble = false; //bool to control if the panel is in trouble -bool troubleAck = false; //bool to control if the trouble is acknowledged -bool configMenu = false; //determine if the control panel is in the configuration menu +bool troubleAcked = false; //bool to control if the trouble is acknowledged +bool inConfigMenu = false; //determine if the control panel is in the configuration menu //---------------------------- Variables that are *always* true if a button is held down at all bool resetPressed = false; @@ -43,7 +42,7 @@ bool silenceStillPressed = false; bool drillStillPressed = false; //---------------------------- -bool possibleAlarm = false; //panel receieved 0 from pull station ciruit and is now investigating +bool runVerification = false; //panel receieved 0 from pull station ciruit and is now investigating bool walkTest = false; //is the system in walk test bool silentWalkTest = false; bool backlightOn = true; @@ -55,8 +54,8 @@ bool secondStage = false; //if the panel is in second stage int characters[] = {32,45,46,47,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90}; //characters allowed on name int panelNameList[16]; int clearTimer = 0; //timer for keeping track of button holding for clearing character in the name editor -int verification = 0; //number to keep track of ms for verification -int drill = 0; //number to keep track of ms for drill +int verificationTimer = 0; //number to keep track of ms for verification +int drillTimer = 0; //number to keep track of ms for drill int buttonCheckTimer = 0; //add a slight delay to avoid double-clicking buttons int keyCheckTimer = 0; int troubleTimer = 0; //ms for trouble @@ -77,13 +76,13 @@ String configBottom; String currentConfigTop; //configuration menu strings for current lcd display String currentConfigBottom; bool keyRequired = false; //determine if key switch is required to operate buttons -bool isVerification = true; //is verification turned on +bool verificationEnabled = true; //is verification turned on bool eolResistor = true; //is the EOL resistor enabled bool preAlarm = false; //use pre-alarm? bool smokeDetectorVerification = false; //should smoke detectors activate first stage bool smokeDetectorCurrentlyInVerification = false; //Is a smoke detector currently in verification? bool audibleSilence = true; -bool twoWire = false; //does the panel use 2 wire for alarms +bool useTwoWire = false; //does the panel use 2 wire for alarms int twoWireTimer = 0; //timer for 2 wire alarms int smokeDetectorTimeout = 60000; //how long to wait before toggling smoke detectors back on int smokeDetectorPostRestartTimer = 0; //variable to keep track of the 60 seconds post-power up that the panel watches the smoke detector @@ -93,7 +92,7 @@ int firstStageTime = 300000; //time in minutes that first stage should last int firstStageTimer = 0; //timer to keep track of current first stage int codeWheel = 0; //which alarm pattern to use, code-3 default int strobeSync = 0; //strobe sync is not on by default 0 - none | 1 - System Sensor | 2 - Wheelock | 3 - Gentex | 4 - Simplex -int strobeSyncTiming = 0; //strobe sync timer +int strobeSyncTimer = 0; //strobe sync timer float verificationTime = 2500; int panelHomescreen = 0; int lcdTimeout = 0; @@ -362,9 +361,9 @@ void setup() { } //----------------------------- Panel security variable if (EEPROM.read(9) == 1){ - isVerification = true; + verificationEnabled = true; } else { - isVerification = false; + verificationEnabled = false; } if (EEPROM.read(73) == 1){ eolResistor = true; @@ -392,9 +391,9 @@ void setup() { keylessSilence = false; } if (EEPROM.read(30) == 1){ - twoWire = true; + useTwoWire = true; } else { - twoWire = false; + useTwoWire = false; } smokeDetectorTimeout = EEPROM.read(77)*5000; smokeDetectorPostRestartVerificationTime = EEPROM.read(28)*5000; @@ -420,12 +419,11 @@ void setup() { delay(100); Serial.println("Config loaded"); digitalWrite(readyLed, HIGH); //power on ready LED on startup - readyLedStatus = true; updateLockStatus = true; if (digitalRead(keySwitchPin) == HIGH and keyRequired == true){ //check the key status on startup - keyInserted = true; + panelUnlocked = true; } else { - keyInserted = false; + panelUnlocked = false; } digitalWrite(silenceLed, LOW); digitalWrite(alarmLed, LOW); @@ -445,7 +443,6 @@ void setup() { lcd.setCursor(0,1); lcd.print("SYSTEM NORMAL"); digitalWrite(readyLed, HIGH); - readyLedStatus = true; digitalWrite(smokeDetectorRelay, LOW); //turn on smoke relay } lastPulse = millis(); //start last pulse @@ -492,7 +489,7 @@ void activateNAC(){ strobe = true; fullAlarm = true; silenced = false; - configMenu = false; + inConfigMenu = false; codeWheelTimer = 0; if (zoneAlarm == 4 or preAlarm == false){ secondStage = true; //entirely skip first stage if it is a drill or if prealarm is turned off @@ -501,27 +498,26 @@ void activateNAC(){ } tone(); digitalWrite(readyLed, HIGH); - readyLedStatus = true; digitalWrite(alarmLed, HIGH); digitalWrite(silenceLed, LOW); } void checkKey(){ if (digitalRead(keySwitchPin) == HIGH){ - if (keyInserted == false and keyRequired == true){ - keyInserted = true; + if (panelUnlocked == false and keyRequired == true){ + panelUnlocked = true; updateLockStatus = true; } } else { - if (keyInserted == true and keyRequired == true){ - keyInserted = false; + if (panelUnlocked == true and keyRequired == true){ + panelUnlocked = false; drillPressed=false; silencePressed=false; //make sure all buttons are registered as depressed after key is removed resetPressed=false; drillStillPressed=false; resetStillPressed=false; silenceStillPressed=false; - drill = 0; + drillTimer = 0; updateLockStatus = true; } } @@ -530,12 +526,12 @@ void checkKey(){ //----------------------------------------------------------------------------- CHECK ACTIVATION DEVICES [!THIS CODE MUST WORK!] void checkDevices(){ if (walkTest == false){ - if (possibleAlarm == false and fullAlarm == false and (analogRead(zone1Pin) == 0 or analogRead(zone2Pin) == 0)){ //reading a single zero flags as a possible alarm - possibleAlarm = true; + if (runVerification == false and fullAlarm == false and (analogRead(zone1Pin) == 0 or analogRead(zone2Pin) == 0)){ //reading a single zero flags as a possible alarm + runVerification = true; } - if (possibleAlarm == true and fullAlarm == false){ //only execute if the panel flags a possible alarm and there isn't currently a full alarm - if (verification >= verificationTime or isVerification == false){ //execute the following code if verification surpasses the configured verification time OR verification is disabled + if (runVerification == true and fullAlarm == false){ //only execute if the panel flags a possible alarm and there isn't currently a full alarm + if (verificationTimer >= verificationTime or verificationEnabled == false){ //execute the following code if verification surpasses the configured verification time OR verification is disabled if (analogRead(zone1Pin) == 0 or analogRead(zone2Pin) == 0){ //check once again if any zeros are read if (smokeDetectorVerification == false or smokeDetectorCurrentlyInVerification == true){ //if smoke detector verification is disabled, or a smoke detector has tripped *after* verification, activate NACs if (analogRead(zone1Pin) == 0 and analogRead(zone2Pin) == 0){ //read the pins once more to check which zone is in alarm @@ -546,8 +542,8 @@ void checkDevices(){ zoneAlarm = 1; //z1 } activateNAC(); - possibleAlarm = false; //dismiss the possible alarm after activating the NACs - verification = 0; + runVerification = false; //dismiss the possible alarm after activating the NACs + verificationTimer = 0; } else if (smokeDetectorVerification == true and smokeDetectorCurrentlyInVerification == false){ //if smoke detector verifcaion is turned on, run this instead smokeDetectorOn(false); //turn off the smoke detector relay delay(100); //wait for 100 ms @@ -561,24 +557,24 @@ void checkDevices(){ } activateNAC(); smokeDetectorOn(true); //re-enable the smoke detector relay after determining that a pull station was pulled. - possibleAlarm = false; - verification = 0; + runVerification = false; + verificationTimer = 0; } else { //if the signal *does not* persists after disabling the smoke detector relay, it was a smoke detector, run verification. smokeDetectorPostRestartTimer = 0; smokeDetectorCurrentlyInVerification = true; //tell the smokeDetector() function to run code smokeDetectorTimer = 0; //reset the smoke detector timer currentScreen = -1; //update the screen to allow the displaying of smoke detector verification digitalWrite(alarmLed, HIGH); //LED indicator - possibleAlarm = false; - verification = 0; + runVerification = false; + verificationTimer = 0; } } } else { //if no zeros are read after verification, dismiss possible alarm - possibleAlarm = false; - verification = 0; + runVerification = false; + verificationTimer = 0; } } else { - verification++; + verificationTimer++; } } } else if (walkTest == true){ @@ -653,18 +649,16 @@ void checkDevices(){ //----------------------------------------------------------------------------- TROUBLE RESPONSE void troubleCheck(){ - if (trouble == true and fullAlarm == false and walkTest == false){ + if (trouble and not fullAlarm and not walkTest){ if (troubleLedTimer >= 200){ - if (readyLedStatus == true){ + if (digitalRead(readyLed)){ digitalWrite(readyLed, LOW); - readyLedStatus = false; - if (troubleAck==false){ + if (not troubleAcked){ noTone(); } } else { digitalWrite(readyLed, HIGH); - readyLedStatus = true; - if (troubleAck==false){ + if (not troubleAcked){ tone(); } } @@ -711,22 +705,21 @@ void checkButtons(){ } if (digitalRead(silenceButtonPin) == HIGH){ //---------------------------------------------------------SILENCE BUTTON - if (horn == true){ //if horns are not silenced, silence the horns + if (horn){ //if horns are not silenced, silence the horns digitalWrite(silenceLed, HIGH); digitalWrite(alarmLed, LOW); digitalWrite(readyLed, LOW); - readyLedStatus = false; horn = false; - if (audibleSilence == false){ + if (not audibleSilence){ strobe = false; } silenced=true; noTone(); - } else if (horn == false and strobe == false and trouble == true and silencePressed == false and troubleAck==false){ - troubleAck = true; + } else if (not fullAlarm and trouble and not silencePressed and not troubleAcked){ + troubleAcked = true; noTone(); - } else if (horn == false and strobe == false and fullAlarm == false and silencePressed == false and configMenu == false){ - configMenu = true; + } else if (not fullAlarm and not silencePressed and not inConfigMenu){ + inConfigMenu = true; resetStillPressed = true; //make sure the menu doesn't close out as soon as someone opens it silenceStillPressed = true; drillStillPressed = true; @@ -743,19 +736,19 @@ void checkButtons(){ silencePressed = false; } - if (digitalRead(drillButtonPin) == HIGH and horn != true and silenced != true and fullAlarm == false){ //------------------------------------------DRILL BUTTON - if (drill >= 237){ + if (digitalRead(drillButtonPin) == HIGH and not horn and not silenced and not fullAlarm){ //------------------------------------------DRILL BUTTON + if (drillTimer >= 237){ zoneAlarm = 4; activateNAC(); } else { - drill++; + drillTimer++; } drillPressed = true; } else { - drill = 0; + drillTimer = 0; drillPressed = false; } - if (digitalRead(drillButtonPin) == HIGH and fullAlarm == true and secondStage == false){ + if (digitalRead(drillButtonPin) == HIGH and not fullAlarm and not secondStage){ secondStage = true; currentScreen = -1; } @@ -769,21 +762,21 @@ void alarm(){ if (strobeSync == 0){ strobeOn(true); } else if (strobeSync == 1 or strobeSync == 2){ - if (strobeSyncTiming >= 1000){ - strobeSyncTiming=0; - } else if (strobeSyncTiming >= 975){ + if (strobeSyncTimer >= 1000){ + strobeSyncTimer=0; + } else if (strobeSyncTimer >= 975){ strobeOn(false); - } else if (strobeSyncTiming <= 10){ + } else if (strobeSyncTimer <= 10){ strobeOn(true); } - strobeSyncTiming++; + strobeSyncTimer++; } }else{ strobeOn(false); - strobeSyncTiming = 0; + strobeSyncTimer = 0; } - if (horn == true and twoWire == false){ - if (preAlarm == false or secondStage == true){ //yes, preAlarm == false is redundant but in the case that second stage == false, but pre-alarm is off, the full alarm will still sound + if (horn and not useTwoWire){ + if (not preAlarm or secondStage){ //yes, preAlarm == false is redundant but in the case that second stage == false, but pre-alarm is off, the full alarm will still sound if (codeWheel == 0){ if (codeWheelTimer == 0){ //---------- temporal code 3 @@ -875,7 +868,7 @@ void alarm(){ } codeWheelTimer++; - } else if (preAlarm == true and secondStage == false){ + } else if (preAlarm and not secondStage){ if (codeWheelTimer == 0){ hornOn(true); } else if (codeWheelTimer == 75){ @@ -892,8 +885,8 @@ void alarm(){ currentScreen = -1; } } - } else if (twoWire == true){ //-------------------------------- DO MORE TESTING WITH THIS!!!! - if (horn == true and (preAlarm == false or secondStage == true)){ + } else if (useTwoWire){ //-------------------------------- DO MORE TESTING WITH THIS!!!! + if (horn and (not preAlarm or secondStage)){ if (twoWireTimer >= 1000){ twoWireTimer = 0; } else if (twoWireTimer >= 975){ @@ -902,7 +895,7 @@ void alarm(){ hornOn(true); } twoWireTimer++; - } else if (horn == false and silenced == true){ + } else if (not horn and silenced and audibleSilence){ if (twoWireTimer >= 1000){ twoWireTimer = 0; } else if (twoWireTimer >= 965){ @@ -911,7 +904,7 @@ void alarm(){ hornOn(true); } twoWireTimer++; - } else if (preAlarm == true and secondStage == false){ + } else if (horn and preAlarm and not secondStage){ if (codeWheelTimer == 0){ hornOn(true); } else if (codeWheelTimer == 75){ @@ -933,16 +926,16 @@ void alarm(){ codeWheelTimer = 0; twoWireTimer = 0; } - if (fullAlarm == true){ + if (fullAlarm){ alarmLedTimer++; if (alarmLedTimer >= 750){ - if (digitalRead(alarmLed) == false){ - if (silenced == true){ + if (not digitalRead(alarmLed)){ + if (silenced){ tone(); } digitalWrite(alarmLed, HIGH); } else { - if (silenced == true){ + if (silenced){ noTone(); } digitalWrite(alarmLed, LOW); @@ -954,11 +947,11 @@ void alarm(){ //----------------------------------------------------------------------------- NAC ACTIVATION void lcdUpdate(){ - if (trouble==false and fullAlarm==false and horn==false and strobe==false and walkTest == false and currentScreen != 0 and drill == 0){ + if (not trouble and not fullAlarm and not walkTest and currentScreen != 0 and drillTimer == 0){ lcd.noAutoscroll(); lcd.clear(); lcd.setCursor(2,0); - if (smokeDetectorCurrentlyInVerification == true){ + if (smokeDetectorCurrentlyInVerification){ lcd.print("Smoke Verif."); } else { lcd.print("System Normal"); @@ -971,10 +964,10 @@ void lcdUpdate(){ } currentScreen = 0; updateLockStatus = true; - } else if (fullAlarm == true and silenced == false and currentScreen != 3){ + } else if (fullAlarm and not silenced and currentScreen != 3){ lcd.clear(); lcd.setCursor(1,0); - if (secondStage == true){ //print pre-alarm if it is first stage + if (secondStage){ //print pre-alarm if it is first stage lcd.print("* FIRE ALARM *"); } else { lcd.print("* PRE ALARM *"); @@ -991,7 +984,7 @@ void lcdUpdate(){ } currentScreen = 3; updateLockStatus = true; - } else if (silenced == true and currentScreen != 4){ + } else if (silenced and currentScreen != 4){ lcd.clear(); lcd.setCursor(1,0); lcd.print("-- SILENCED --"); @@ -1005,11 +998,9 @@ void lcdUpdate(){ } else if (zoneAlarm == 4){ lcd.print("Fire Drill"); } - // lcd.setCursor(2,1); - // lcd.print("Zone 1"); currentScreen = 4; updateLockStatus = true; - } else if (walkTest == true and currentScreen != 5) { + } else if (walkTest and currentScreen != 5) { lcd.clear(); lcd.setCursor(1,0); lcd.print("* Supervisory *"); @@ -1018,15 +1009,14 @@ void lcdUpdate(){ currentScreen = 5; updateLockStatus = true; digitalWrite(readyLed, LOW); //ready led off for walk test - readyLedStatus = false; - } else if (drillPressed == true and fullAlarm == false and horn == false and strobe == false and walkTest == false and currentScreen != 6) { + } else if (drillPressed and not fullAlarm and not walkTest and currentScreen != 6) { lcd.clear(); lcd.setCursor(0,0); lcd.print("CONTINUE HOLDING"); lcd.setCursor(1,1); lcd.print("TO START DRILL"); currentScreen = 6; - } else if (trouble==true and fullAlarm == false and drillPressed == false and walkTest == false and currentScreen != 1){ + } else if (trouble and not fullAlarm and not drillPressed and not walkTest and currentScreen != 1){ lcd.clear(); lcd.setCursor(2,0); lcd.print("* Trouble *"); @@ -1046,16 +1036,32 @@ void lcdUpdate(){ currentScreen = 1; updateLockStatus = true; } - if (updateLockStatus == true and configMenu == false and keyRequired == true){ + if (updateLockStatus and not inConfigMenu and keyRequired){ lcd.setCursor(0,0); - if (keyInserted == false){ - lcd.write(byte(0)); - } else { + if (panelUnlocked){ lcd.print(" "); + } else { + lcd.write(byte(0)); } updateLockStatus = false; } } + +void configLCDUpdate(int cursor, String top, String bottom, bool replaceTop = false, bool replaceBottom = false){ // new cursor position, top lcd text, bottom lcd text, does the top text need a check or cross, does the bottom text need a check or cross + configTop = top; + configBottom = bottom; + cursorPosition = cursor; + + if (replaceTop == true){ + configTop.replace("1","*"); + configTop.replace("0","$"); + } + if (replaceBottom == true){ + configBottom.replace("1","*"); + configBottom.replace("0","$"); + } +} + void config(){ char *main[] = {"Testing","Settings"}; //menu 0 char *mainTesting[] = {"Walk Test","Silent Wlk Test","Strobe Test"}; //menu 1 @@ -1090,66 +1096,49 @@ void config(){ } //----------------------------------------------------------------------------- MAIN MENU if (configPage == 0){ - if (resetPressed == true and resetStillPressed == false){ + if (resetPressed and not resetStillPressed){ if (cursorPosition == 0){ //main screen - cursorPosition = 1; - configTop = (String)main[1]; - configBottom = (String)main[0]; + configLCDUpdate(1, (String)main[1], (String)main[0]); } else if (cursorPosition == 1){ - cursorPosition = 0; - configTop = (String)main[0]; - configBottom = (String)main[1]; + configLCDUpdate(0, (String)main[0], (String)main[1]); } - } else if (silencePressed == true and silenceStillPressed == false){ + } else if (silencePressed and not silenceStillPressed){ silencePressed = true; - configMenu = false; + inConfigMenu = false; currentScreen=-1; - } else if (drillPressed == true and drillStillPressed == false){ + } else if (drillPressed and not drillStillPressed){ if (cursorPosition == 0){ //cursor over testing configPage = 1; //change screen to testing - cursorPosition = 0; - configTop = (String)mainTesting[0]; - configBottom = (String)mainTesting[1]; + configLCDUpdate(0, (String)mainTesting[0], (String)mainTesting[1]); } else if (cursorPosition == 1){ //cursor over settings configPage = 2; //change screen to settings - cursorPosition = 0; - configTop = (String)mainSettings[0]; - configBottom = (String)mainSettings[1]; + configLCDUpdate(0, (String)mainSettings[0], (String)mainSettings[1]); } } //----------------------------------------------------------------------------- MAIN MENU //----------------------------------------------------------------------------- TESTING } else if (configPage == 1){ - if (resetPressed == true and resetStillPressed == false and strobe != true){ + if (resetPressed and not resetStillPressed and not strobe){ if (cursorPosition == 0){ - cursorPosition = 1; - configTop = (String)mainTesting[1]; - configBottom = (String)mainTesting[2]; + configLCDUpdate(1, (String)mainTesting[1], (String)mainTesting[2]); } else if (cursorPosition == 1) { - cursorPosition = 2; - configTop = (String)mainTesting[2]; - configBottom = (String)mainTesting[0]; + configLCDUpdate(2, (String)mainTesting[2], (String)mainTesting[0]); } else if (cursorPosition == 2) { - cursorPosition = 0; - configTop = (String)mainTesting[0]; - configBottom = (String)mainTesting[1]; + configLCDUpdate(0, (String)mainTesting[0], (String)mainTesting[1]); } - } else if (silencePressed == true and silenceStillPressed == false){ + } else if (silencePressed and not silenceStillPressed){ configPage = 0; - cursorPosition = 0; - configTop = (String)main[0]; - configBottom = (String)main[1]; + configLCDUpdate(0, (String)main[0], (String)main[1]); strobe = false; smokeDetectorOn(true); digitalWrite(readyLed,HIGH); - readyLedStatus = true; - } else if (drillPressed == true and drillStillPressed == false){ + } else if (drillPressed == true and not drillStillPressed){ if (cursorPosition == 0){ walkTest = true; silentWalkTest = false; silencePressed = true; - configMenu = false; + inConfigMenu = false; currentScreen=-1; zone1Count = 0; zone2Count = 0; @@ -1157,23 +1146,21 @@ void config(){ walkTest = true; silentWalkTest = true; silencePressed = true; - configMenu = false; + inConfigMenu = false; currentScreen=-1; zone1Count = 0; zone2Count = 0; } else if (cursorPosition == 2) { - if (strobe == false){ + if (not strobe){ strobe = true; smokeDetectorOn(false); //prevent (specifically cheap IR) smoke detectors from tripping from the strobe digitalWrite(readyLed,LOW); - readyLedStatus = false; - configTop = (String)mainTesting[2]+" *"; + configLCDUpdate(2, (String)mainTesting[2]+" *", (String)mainTesting[0]); } else { strobe = false; smokeDetectorOn(true); digitalWrite(readyLed,HIGH); - readyLedStatus = true; - configTop = (String)mainTesting[2]; + configLCDUpdate(2, (String)mainTesting[2], (String)mainTesting[0]); } } } @@ -1181,144 +1168,93 @@ void config(){ //----------------------------------------------------------------------------- SETTINGS } else if (configPage == 2){ - if (resetPressed == true and resetStillPressed == false){ + if (resetPressed and not resetStillPressed){ if (cursorPosition == 0){ //main screen - cursorPosition = 1; - configTop = (String)mainSettings[1]; - configBottom = (String)mainSettings[0]; + configLCDUpdate(1, (String)mainSettings[1], (String)mainSettings[0]); } else if (cursorPosition == 1){ - cursorPosition = 0; - configTop = (String)mainSettings[0]; - configBottom = (String)mainSettings[1]; + configLCDUpdate(0, (String)mainSettings[0], (String)mainSettings[1]); } } else if (silencePressed == true and silenceStillPressed == false){ configPage = 0; - cursorPosition = 1; - configTop = (String)main[1]; - configBottom = (String)main[0]; - } else if (drillPressed == true and drillStillPressed == false){ + configLCDUpdate(1, (String)main[1], (String)main[0]); + } else if (drillPressed and not drillStillPressed){ if (cursorPosition == 0){ configPage = 3; //change screen to facp settings - cursorPosition = 0; - if (twoWire == false){ - configTop = (String)mainSettingsFireAlarmSettings[0]; + if (useTwoWire){ + configLCDUpdate(0, (String)mainSettingsFireAlarmSettings[0] + " off", (String)mainSettingsFireAlarmSettings[1]); } else { - configTop = (String)mainSettingsFireAlarmSettings[0] + " off"; + configLCDUpdate(0, (String)mainSettingsFireAlarmSettings[0], (String)mainSettingsFireAlarmSettings[1]); } - configBottom = (String)mainSettingsFireAlarmSettings[1]; } else if (cursorPosition == 1){ configPage = 8; //change screen to facp settings - cursorPosition = 0; - configTop = (String)mainPanelSettings[0]; - configBottom = (String)mainPanelSettings[1]; + configLCDUpdate(0, (String)mainPanelSettings[0], (String)mainPanelSettings[1]); } } //----------------------------------------------------------------------------- SETTINGS //----------------------------------------------------------------------------- SETTINGS > FIRE ALARM } else if (configPage == 3){ - if (resetPressed == true and resetStillPressed == false){ + if (resetPressed and not resetStillPressed){ if (cursorPosition == 0){ - cursorPosition = 1; - configTop = (String)mainSettingsFireAlarmSettings[1]; - configBottom = (String)mainSettingsFireAlarmSettings[2]; + configLCDUpdate(1, (String)mainSettingsFireAlarmSettings[1], (String)mainSettingsFireAlarmSettings[2]); } else if (cursorPosition == 1) { - cursorPosition = 2; - configTop = (String)mainSettingsFireAlarmSettings[2]; - configBottom = (String)mainSettingsFireAlarmSettings[3]+audibleSilence; - configBottom.replace("1","*"); - configBottom.replace("0","$"); + configLCDUpdate(2, (String)mainSettingsFireAlarmSettings[2], (String)mainSettingsFireAlarmSettings[3]+audibleSilence, false, true); } else if (cursorPosition == 2) { - cursorPosition = 3; - configTop = (String)mainSettingsFireAlarmSettings[3]+audibleSilence; - if (keyRequiredVisual == true){ - configBottom = (String)mainSettingsFireAlarmSettings[4]+keylessSilence; + if (keyRequiredVisual){ + configLCDUpdate(3, (String)mainSettingsFireAlarmSettings[3]+audibleSilence, (String)mainSettingsFireAlarmSettings[4]+keylessSilence, true, true); } else { - configBottom = (String)mainSettingsFireAlarmSettings[4]+"off"; + configLCDUpdate(3, (String)mainSettingsFireAlarmSettings[3]+audibleSilence, (String)mainSettingsFireAlarmSettings[4]+keylessSilence+"off", true, false); } - configTop.replace("1","*"); - configTop.replace("0","$"); - configBottom.replace("1","*"); - configBottom.replace("0","$"); } else if (cursorPosition == 3){ - cursorPosition = 4; - if (keyRequiredVisual == true){ - configTop = (String)mainSettingsFireAlarmSettings[4]+keylessSilence; + if (keyRequiredVisual){ + configLCDUpdate(4, (String)mainSettingsFireAlarmSettings[4]+keylessSilence, (String)mainSettingsFireAlarmSettings[5], true, false); } else { - configTop = (String)mainSettingsFireAlarmSettings[4]+"off"; + configLCDUpdate(4, (String)mainSettingsFireAlarmSettings[4]+"off", (String)mainSettingsFireAlarmSettings[5], false, false); } - configBottom = (String)mainSettingsFireAlarmSettings[5]; - configTop.replace("1","*"); - configTop.replace("0","$"); } else if (cursorPosition == 4) { - cursorPosition = 5; - configTop = (String)mainSettingsFireAlarmSettings[5]; - configBottom = (String)mainSettingsFireAlarmSettings[6]+twoWire; - configBottom.replace("1","*"); - configBottom.replace("0","$"); + configLCDUpdate(5, (String)mainSettingsFireAlarmSettings[5], (String)mainSettingsFireAlarmSettings[6]+useTwoWire, false, true); } else if (cursorPosition == 5){ - cursorPosition = 6; - configTop = (String)mainSettingsFireAlarmSettings[6]+twoWire; - if (twoWire == false){ - configBottom = (String)mainSettingsFireAlarmSettings[0]; + if (useTwoWire){ + configLCDUpdate(6, (String)mainSettingsFireAlarmSettings[6]+useTwoWire, (String)mainSettingsFireAlarmSettings[0]+"off", true, false); } else { - configBottom = (String)mainSettingsFireAlarmSettings[0] + " off"; + configLCDUpdate(6, (String)mainSettingsFireAlarmSettings[6]+useTwoWire, (String)mainSettingsFireAlarmSettings[0], true, false); } - configTop.replace("1","*"); - configTop.replace("0","$"); } else if (cursorPosition == 6){ - cursorPosition = 0; - if (twoWire == false){ - configTop = (String)mainSettingsFireAlarmSettings[0]; + if (useTwoWire){ + configLCDUpdate(0, (String)mainSettingsFireAlarmSettings[0] + " off", (String)mainSettingsFireAlarmSettings[1]); } else { - configTop = (String)mainSettingsFireAlarmSettings[0] + " off"; + configLCDUpdate(0, (String)mainSettingsFireAlarmSettings[0], (String)mainSettingsFireAlarmSettings[1]); } - configBottom = (String)mainSettingsFireAlarmSettings[1]; } - } else if (silencePressed == true and silenceStillPressed == false){ + } else if (silencePressed and not silenceStillPressed){ configPage = 2; - cursorPosition = 0; - configTop = (String)mainSettings[0]; - configBottom = (String)mainSettings[1]; - } else if (drillPressed == true and drillStillPressed == false){ - if (cursorPosition == 0 and twoWire == false){ + configLCDUpdate(0, (String)mainSettings[0], (String)mainSettings[1]); + } else if (drillPressed and not drillStillPressed){ + if (cursorPosition == 0 and not useTwoWire){ configPage = 5; - cursorPosition = 0; - if (codeWheel == 0){ - configTop = (String)mainSettingsFireAlarmSettingsCoding[0] + "*"; + configLCDUpdate(0, (String)mainSettingsFireAlarmSettingsCoding[0] + "*", (String)mainSettingsFireAlarmSettingsCoding[1]); + } else if (codeWheel == 1){ + configLCDUpdate(0, (String)mainSettingsFireAlarmSettingsCoding[0], (String)mainSettingsFireAlarmSettingsCoding[1] + "*"); } else { - configTop = (String)mainSettingsFireAlarmSettingsCoding[0]; - } - if (codeWheel == 1){ - configBottom = (String)mainSettingsFireAlarmSettingsCoding[1] + "*"; - } else { - configBottom = (String)mainSettingsFireAlarmSettingsCoding[1]; + configLCDUpdate(0, (String)mainSettingsFireAlarmSettingsCoding[0], (String)mainSettingsFireAlarmSettingsCoding[1]); } } else if (cursorPosition == 1) { configPage = 4; - cursorPosition = 0; - configTop = (String)mainSettingsVerificationSettings[0] + isVerification; - if (isVerification == false){ - configBottom = (String)mainSettingsVerificationSettings[1] + "off"; + if (verificationEnabled){ + configLCDUpdate(0, (String)mainSettingsVerificationSettings[0] + verificationEnabled, (String)mainSettingsVerificationSettings[1] + (verificationTime/1000)+"s", true, false); } else { - configBottom = (String)mainSettingsVerificationSettings[1] + (verificationTime/1000)+"s"; + configLCDUpdate(0, (String)mainSettingsVerificationSettings[0] + verificationEnabled, (String)mainSettingsVerificationSettings[1] + "off", true, false); } - configTop.replace("1","*"); - configTop.replace("0","$"); } else if (cursorPosition == 2) { configPage = 6; - cursorPosition = 0; - configTop = (String)mainSettingsFireAlarmSettingsPreAlarmSettings[0]+preAlarm; - if (preAlarm == true){ - configBottom = (String)mainSettingsFireAlarmSettingsPreAlarmSettings[1] + (firstStageTime/60000) + "m"; + if (preAlarm){ + configLCDUpdate(0, (String)mainSettingsFireAlarmSettingsPreAlarmSettings[0]+preAlarm, (String)mainSettingsFireAlarmSettingsPreAlarmSettings[1] + (firstStageTime/60000) + "m", true, false); } else { - configBottom = (String)mainSettingsFireAlarmSettingsPreAlarmSettings[1] + "off"; + configLCDUpdate(0, (String)mainSettingsFireAlarmSettingsPreAlarmSettings[0]+preAlarm, (String)mainSettingsFireAlarmSettingsPreAlarmSettings[1] + "off", true, false); } - configTop.replace("1","*"); - configTop.replace("0","$"); } else if (cursorPosition == 3) { - if (audibleSilence == true){ + if (audibleSilence){ audibleSilence = false; EEPROM.write(79,0); } else { @@ -1326,18 +1262,13 @@ void config(){ EEPROM.write(79,1); } EEPROM.commit(); - configTop = (String)mainSettingsFireAlarmSettings[3]+audibleSilence; - if (keyRequiredVisual == true){ - configBottom = (String)mainSettingsFireAlarmSettings[4]+keylessSilence; + if (keyRequiredVisual){ + configLCDUpdate(3, (String)mainSettingsFireAlarmSettings[3]+audibleSilence, (String)mainSettingsFireAlarmSettings[4]+keylessSilence, true, true); } else { - configBottom = (String)mainSettingsFireAlarmSettings[4]+"off"; + configLCDUpdate(3, (String)mainSettingsFireAlarmSettings[3]+audibleSilence, (String)mainSettingsFireAlarmSettings[4]+"off", true, false); } - configTop.replace("1","*"); - configTop.replace("0","$"); - configBottom.replace("1","*"); - configBottom.replace("0","$"); - } else if (cursorPosition == 4 and keyRequiredVisual == true){ - if (keylessSilence == true){ + } else if (cursorPosition == 4 and keyRequiredVisual){ + if (keylessSilence){ keylessSilence = false; EEPROM.write(27,0); } else { @@ -1345,41 +1276,31 @@ void config(){ EEPROM.write(27,1); } EEPROM.commit(); - configTop = (String)mainSettingsFireAlarmSettings[4]+keylessSilence; - configBottom = (String)mainSettingsFireAlarmSettings[5]; - configTop.replace("1","*"); - configTop.replace("0","$"); + configLCDUpdate(4, (String)mainSettingsFireAlarmSettings[4]+keylessSilence, (String)mainSettingsFireAlarmSettings[5], true, false); } else if (cursorPosition == 5){ - configPage = 11; - cursorPosition = 0; - + configPage = 11; if (strobeSync == 0){ - configTop = (String)mainSettingsFireAlarmSettingsStrobeSync[0] + "*"; + configLCDUpdate(0, (String)mainSettingsFireAlarmSettingsStrobeSync[0] + "*", (String)mainSettingsFireAlarmSettingsStrobeSync[1]); + } else if (strobeSync == 1){ + configLCDUpdate(0, (String)mainSettingsFireAlarmSettingsStrobeSync[0], (String)mainSettingsFireAlarmSettingsStrobeSync[1] + "*"); } else { - configTop = (String)mainSettingsFireAlarmSettingsStrobeSync[0]; - } - if (strobeSync == 1){ - configBottom = (String)mainSettingsFireAlarmSettingsStrobeSync[1] + "*"; - } else { - configBottom = (String)mainSettingsFireAlarmSettingsStrobeSync[1]; + configLCDUpdate(0, (String)mainSettingsFireAlarmSettingsStrobeSync[0], (String)mainSettingsFireAlarmSettingsStrobeSync[1]); } } else if (cursorPosition == 6){ - if (twoWire == true){ - twoWire = false; + if (useTwoWire){ + useTwoWire = false; EEPROM.write(30,0); } else { - twoWire = true; + useTwoWire = true; EEPROM.write(30,1); } EEPROM.commit(); - configTop = (String)mainSettingsFireAlarmSettings[6]+twoWire; - if (twoWire == false){ - configBottom = (String)mainSettingsFireAlarmSettings[0]; + configTop = (String)mainSettingsFireAlarmSettings[6]+useTwoWire; + if (useTwoWire){ + configLCDUpdate(6, (String)mainSettingsFireAlarmSettings[6]+useTwoWire, (String)mainSettingsFireAlarmSettings[0] + " off", true, false); } else { - configBottom = (String)mainSettingsFireAlarmSettings[0] + " off"; + configLCDUpdate(6, (String)mainSettingsFireAlarmSettings[6]+useTwoWire, (String)mainSettingsFireAlarmSettings[0], true, false); } - configTop.replace("1","*"); - configTop.replace("0","$"); } } //----------------------------------------------------------------------------- SETTINGS > FIRE ALARM @@ -1644,10 +1565,10 @@ void config(){ } else if (silencePressed == true and silenceStillPressed == false){ configPage = 3; //change screen to facp settings cursorPosition = 0; - if (twoWire == false){ - configTop = (String)mainSettingsFireAlarmSettings[0]; - } else { + if (useTwoWire){ configTop = (String)mainSettingsFireAlarmSettings[0] + " off"; + } else { + configTop = (String)mainSettingsFireAlarmSettings[0]; } configBottom = (String)mainSettingsFireAlarmSettings[1]; } else if (drillPressed == true and drillStillPressed == false){ @@ -1668,7 +1589,7 @@ void config(){ if (resetPressed == true and resetStillPressed == false){ if (cursorPosition == 0){ cursorPosition = 1; - if (isVerification == false){ + if (verificationEnabled == false){ configTop = (String)mainSettingsVerificationSettings[1] + "off"; } else { configTop = (String)mainSettingsVerificationSettings[1] + (verificationTime/1000)+"s"; @@ -1721,13 +1642,13 @@ void config(){ } else { configTop = (String)mainSettingsVerificationSettings[4] + "off"; } - configBottom = (String)mainSettingsVerificationSettings[0] + isVerification; + configBottom = (String)mainSettingsVerificationSettings[0] + verificationEnabled; configBottom.replace("1","*"); configBottom.replace("0","$"); } else if (cursorPosition == 4) { cursorPosition = 0; - configTop = (String)mainSettingsVerificationSettings[0] + isVerification; - if (isVerification == false){ + configTop = (String)mainSettingsVerificationSettings[0] + verificationEnabled; + if (verificationEnabled == false){ configBottom = (String)mainSettingsVerificationSettings[1] + "off"; } else { configBottom = (String)mainSettingsVerificationSettings[1] + (verificationTime/1000)+"s"; @@ -1742,23 +1663,23 @@ void config(){ configBottom = (String)mainSettingsFireAlarmSettings[2]; } else if (drillPressed == true and drillStillPressed == false){ if (cursorPosition == 0){ - if (isVerification == true){ - isVerification = false; + if (verificationEnabled == true){ + verificationEnabled = false; EEPROM.write(9,0); } else { - isVerification = true; + verificationEnabled = true; EEPROM.write(9,1); } EEPROM.commit(); - configTop = (String)mainSettingsVerificationSettings[0]+isVerification; - if (isVerification == false){ + configTop = (String)mainSettingsVerificationSettings[0]+verificationEnabled; + if (verificationEnabled == false){ configBottom = (String)mainSettingsVerificationSettings[1] + "off"; } else { configBottom = (String)mainSettingsVerificationSettings[1] + (verificationTime/1000)+"s"; } configTop.replace("1","*"); configTop.replace("0","$"); - } else if (cursorPosition == 1 and isVerification == true) { + } else if (cursorPosition == 1 and verificationEnabled == true) { if (verificationTime == 500){ verificationTime = 1000; EEPROM.write(10,10); @@ -1779,7 +1700,7 @@ void config(){ EEPROM.write(10,5); } EEPROM.commit(); - if (isVerification == false){ + if (verificationEnabled == false){ configTop = (String)mainSettingsVerificationSettings[1] + "off"; } else { configTop = (String)mainSettingsVerificationSettings[1] + (verificationTime/1000)+"s"; @@ -1886,7 +1807,7 @@ void config(){ } else { configTop = (String)mainSettingsVerificationSettings[4] + (smokeDetectorPostRestartVerificationTime/60000) + "m"; } - configBottom = (String)mainSettingsVerificationSettings[0] + isVerification; + configBottom = (String)mainSettingsVerificationSettings[0] + verificationEnabled; configBottom.replace("1","*"); configBottom.replace("0","$"); } @@ -2123,7 +2044,7 @@ void config(){ configPage = 3; //change screen to facp settings cursorPosition = 5; configTop = (String)mainSettingsFireAlarmSettings[5]; - configBottom = (String)mainSettingsFireAlarmSettings[6]+twoWire; + configBottom = (String)mainSettingsFireAlarmSettings[6]+useTwoWire; configBottom.replace("1","*"); configBottom.replace("0","$"); } else if (drillPressed == true and drillStillPressed == false){ @@ -2205,7 +2126,7 @@ void lcdBacklight(){ } else if (backlightOn == true) { lcdTimeoutTimer++; } - if (drillPressed == true or silencePressed == true or resetPressed == true or fullAlarm == true or trouble == true or (keyInserted == true and keyRequired == true) or smokeDetectorCurrentlyInVerification == true){ + if (drillPressed == true or silencePressed == true or resetPressed == true or fullAlarm == true or trouble == true or (panelUnlocked == true and keyRequired == true) or smokeDetectorCurrentlyInVerification == true){ lcdTimeoutTimer = 0; if (backlightOn == false){ lcd.backlight(); @@ -2264,12 +2185,10 @@ void failsafe(){ //--------------------------------------------- FAILSAFE MODE I ESP.restart(); } if (troubleLedTimer >= 2000){ - if (readyLedStatus == true){ + if (digitalRead(readyLed)){ digitalWrite(readyLed, LOW); - readyLedStatus = false; } else { digitalWrite(readyLed, HIGH); - readyLedStatus = true; } troubleLedTimer = 0; } else { @@ -2302,15 +2221,14 @@ void loop() { } if (buttonCheckTimer >= 20){ - if (configMenu==false){ - if ((keyInserted == true and keyRequired == true) or (keyRequired==false)){ + if (not inConfigMenu){ + if ((panelUnlocked == true and keyRequired == true) or (keyRequired==false)){ checkButtons(); //check if certain buttons are pressed } else if (keylessSilence == true and fullAlarm == true and silenced == false){ if (digitalRead(silenceButtonPin) == HIGH){ digitalWrite(silenceLed, HIGH); digitalWrite(alarmLed, LOW); digitalWrite(readyLed, LOW); - readyLedStatus = false; horn = false; if (audibleSilence == false){ strobe = false; @@ -2321,8 +2239,8 @@ void loop() { } lcdUpdate(); //------------------------------------------------------ UPDATE LCD DISPLAY - } else if (configMenu==true) { - if ((keyInserted == true and keyRequired == true) or (keyInserted==false and keyRequired==false)){ + } else if (inConfigMenu) { + if ((panelUnlocked == true and keyRequired == true) or (panelUnlocked==false and keyRequired==false)){ config(); } } diff --git a/instructions/antigneous_tech_instructions.odt b/instructions/antigneous_tech_instructions.odt index db3d23e306119bd5d088d4ca1f000a861ca60c0e..f9ae6c5cdf61339ac4e81bd825d5ab54c58fa290 100644 GIT binary patch delta 21034 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 T_@6RwAah2595>F;z-#<}!GbJu delta 21526 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�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 J41({Y{{b+{M`i#3