prismaardvark

Avro RJ85 PSU

Apr 16th, 2021 (edited)
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 31.82 KB | None | 0 0
  1. /*  Code for the domestic installation of an overhead passenger service unit of an Avro RJ (British Aerospace 146) turbofan regional jet.
  2.     Written: March 2021.
  3.     Author: Sam Shelton [email protected]
  4.  
  5.     The PSU, originally configured to run on 28v, has been completely rewired to operate at around 5v. All original
  6.     incandescent bulbs have been replaced by home-made LED parts. The original call bell light (which was non-functioning
  7.     on delivery) has been replaced by a red/blue LED custom part.
  8.  
  9.     Additional features not present in the original installation include passenger control of;
  10.     No smoking signs.
  11.     Fasten seat belt signs.
  12.     Blower fans.
  13.     Oxygen mask deployment.
  14.  
  15.     V1.2: Improved button-press behaviour.
  16. */
  17.  
  18.  
  19. // ARDUINO PINOUT GUIDE
  20. // These constants are the connections for all our inputs and outputs:
  21. // Inputs Pins:
  22. const int inputPinButtonA =         A0;             // A-A0  // Short-Press toggles RLA, Long-press toggles No Smoking.          GREEN CABLE
  23. const int inputPinButtonB =         A1;             // B-A1  // Short-Press toggles RLB, Long-press toggles blower.              BLUE CABLE
  24. const int inputPinButtonC =         A2;             // C-A2  // Short-Press toggles RLC, Long-press toggles Fasten Seat Belts    YELLOW CABLE
  25. const int inputPinButtonCallBell =  A3;             //       // Short-Press toggles BLU, Long-press deploys oxygen masks.        RED CABLE
  26.  
  27. // Output Pins:
  28. const int outputPinLightCallBellBlue = 8;   // This should be connected directly to '8BLU' on the call bell module.
  29. const int outputPinLightCallBellRed = 9 ;   // This should be connected directly to '9RED' on the call bell module.
  30. const int outputPinMasks = 10;              // This should be connected to the 'IN1/MSK' relay - THIS RELAY OPERATES ISOLATED 9V BATTERY / ACTUATOR ONLY
  31. const int outputPinChime = 11;              // This should be connected to the the audio module.
  32. const int outputPinCabinNoise = 12;         // This should be connected to the the audio module.
  33. const int outputPinlightReadingA = 2;       // This should be connected to the 'IN2/RLA' relay.                               GREEN CABLE.
  34. const int outputPinlightReadingB = 3;       // This should be connected to the 'IN3/RLB' relay.                               BLUE CABLE.
  35. const int outputPinlightReadingC = 4;       // This should be connected to the 'IN4/RLC' relay.                               YELLOW CABLE.
  36. const int outputPinlightNoSmoking = 5;      // This should be connected to the 'IN5/NS'  relay.                               GREEN CABLE.
  37. const int outputPinlightSeatBelts = 6;      // This should be connected to the 'IN6/FSB' relay.                               YELLOW CABLE.
  38. const int outputPinBlower = 7;              // This should be connected to the 'IN7/BLW' relay.                               BLUE CABLE.
  39.  
  40. // Still available to use:                     Input-only: A4, A5            Input OR Output: 13
  41.  
  42. const unsigned int toggleTime = 1000;                 // the number of ms below which a light will not toggle on/off.
  43. const unsigned int longPressTime = 2000;              // the number of ms
  44. const unsigned int maxLongPressTime = 3000;           // for the purpose of the mask-drop system, the maximum long-press time.
  45. const unsigned int maskActiveTime = 500;              // the number of ms that the mask release system stays active following an activation before resetting.
  46. const int          startUpDelay = 250;                // the number of ms the setup waits between switching things on when booting to reduce load.
  47. const int          serialUpdateTime = 5000;            // the number of ms between serial monitor updates, for readability.
  48. const unsigned long   autoOffTime = 550000;            // the number of ms before auto shutdown when party mode is not eanabled. (2 mins = 120000. 10 mins = 600000.)
  49. const unsigned long lengthOfAudioFile = 600000;        // the number of ms that the audio file lasts for, so that we can restart it when it ends.
  50.  
  51. // PRESSED/RELEASED STATE OF BUTTONS:
  52. // These bools store the on/off status of our inputs:
  53. bool buttonCallBell = 0;                    // Stores the current pressed (1)/ not-pressed (0) state of this button.
  54. bool buttonA = 0;                           // Stores the current pressed (1)/ not-pressed (0) state of this button.
  55. bool buttonB = 0;                           // Stores the current pressed (1)/ not-pressed (0) state of this button.
  56. bool buttonC = 0;                           // Stores the current pressed (1)/ not-pressed (0) state of this button.
  57.  
  58. bool buttonCallBellActive = 0;                    // Stores a bool flagging whether this button has been pressed *and that action not yet processed*.
  59. bool buttonAActive = 0;                           // Stores a bool flagging whether this button has been pressed *and that action not yet processed*.
  60. bool buttonBActive = 0;                           // Stores a bool flagging whether this button has been pressed *and that action not yet processed*.
  61. bool buttonCActive = 0;                           // Stores a bool flagging whether this button has been pressed *and that action not yet processed*.
  62.  
  63.  
  64. // ON/OFF STATE OF LIGHTS AND EQUIPMENT:
  65. // These bools store the on/off status of our outputs:
  66. bool lightCallBellBlue = 0;                 // Stores the current on (1) / off (0) state of the blue call bell.
  67. bool lightCallBellRed = 0;                  // Stores the current on (1) / off (0) state of the red call bell. (NOT CURRENTLY IN USE)
  68. bool lightReadingA = 0;                     // Stores the current on (1) / off (0) state of reading light A.
  69. bool lightReadingB = 0;                     // Stores the current on (1) / off (0) state of reading light B.
  70. bool lightReadingC = 0;                     // Stores the current on (1) / off (0) state of reading light C.
  71. bool lightSeatBelts = 0;                    // Stores the current on (1) / off (0) state of the fasten seatbelt sign.
  72. bool lightNoSmoking = 0;                    // Stores the current on (1) / off (0) state of the no smoking sign.
  73. bool masks = 0;                             // Stores the current on (1) / off (0) state of mask deployment actuator.
  74. bool blower = 0;                            // Stores the current on (1) / off (0) state of the air blower.
  75. bool maskButtonReleaseActive = 0;           // Stores the current on (1) / off (0) state of the mask button. When this is 1, releasing the button will activate the mask drop.
  76. bool partyMode = 0;                         // Stores the current on (1) / off (0) state of party mode.
  77. bool autoShutdownActivated = 0;             // Stores the current on (1) / off (0) state of whether the unit is currently shut down by the auto shutdown function.
  78.  
  79. unsigned long currentMillis;          // stores the time at which the current loop started.
  80. unsigned long buttonALastOff;         // stores the time at which buttonA was last in the 'off' state.
  81. unsigned long buttonBLastOff;         // stores the time at which buttonB was last in the 'off' state.
  82. unsigned long buttonCLastOff;         // stores the time at which buttonC was last in the 'off' state.
  83. unsigned long buttonCallBellLastOff;  // stores the time at which buttonCallBell was last in the 'off' state.
  84. unsigned long audioRunning;           // stores the length of time for which the audio track has been running.
  85. unsigned long lightReadingALastToggled;         // stores the time at which lightReadingA was last toggled.
  86. unsigned long lightReadingBLastToggled;         // stores the time at which lightReadingB was last toggled.
  87. unsigned long lightReadingCLastToggled;         // stores the time at which lightReadingC was last toggled.
  88. unsigned long lightCallBellBlueLastToggled;     // stores the time at which lightCallBellBlue was last toggled.
  89. unsigned long lightNoSmokingLastToggled;        // stores the time at which lightNoSmoking was last toggled.
  90. unsigned long lightSeatBeltsLastToggled;        // stores the time at which lightSeatBelts was last toggled.
  91. unsigned long blowerLastToggled;                // stores the time at which the blower was last toggled.
  92. unsigned long partyModeLastToggled;             // stores the time at which party mode was last toggled.
  93. unsigned long masksReleasedAt;                  // stores the time at which the mask panel was released.
  94. unsigned long serialUpdatedLast;                // stores the time at which the serial monitor was last updated.
  95. unsigned long lastInputTime;                    // to make auto-shutdown work, the time at which there was last an input
  96. unsigned long timeToShutdown;                   // the number of seconds until autoShutdown;
  97. unsigned long audioRestartedLast;               // stores the time at which the audio file was last restarted.
  98.  
  99. void setup() { // This block of code runs only once, when the unit is switched on.
  100.   Serial.begin(9600);     // for troubleshooting, output a summary of current inputs and outputs,
  101.   Serial.println(" ");    // beginning with some sexy asterisk-surrounded shenanigans...
  102.   Serial.println("********************************************************************************");
  103.   Serial.println("*                            Passenger Service Unit                            *");
  104.   Serial.println("*                                  March 2021                                  *");
  105.   Serial.println("*                                                                              *");
  106.   Serial.println("*                                   Booting...                                 *");
  107.   Serial.println("****************************************-***************************************");
  108.  
  109.   // Set up the pins as outputs and inputs:
  110.   pinMode (inputPinButtonCallBell, INPUT_PULLUP);
  111.   pinMode (inputPinButtonA, INPUT_PULLUP);
  112.   pinMode (inputPinButtonB, INPUT_PULLUP);
  113.   pinMode (inputPinButtonC, INPUT_PULLUP);
  114.   pinMode (outputPinLightCallBellBlue, OUTPUT);
  115.   pinMode (outputPinLightCallBellRed, OUTPUT);
  116.   pinMode (outputPinlightReadingA, OUTPUT);
  117.   pinMode (outputPinlightReadingB, OUTPUT);
  118.   pinMode (outputPinlightReadingC, OUTPUT);
  119.   pinMode (outputPinlightSeatBelts, OUTPUT);
  120.   pinMode (outputPinlightNoSmoking, OUTPUT);
  121.   pinMode (outputPinMasks, OUTPUT);
  122.   pinMode (outputPinBlower, OUTPUT);
  123.   pinMode (outputPinChime, OUTPUT);
  124.   pinMode (outputPinCabinNoise, OUTPUT);
  125.  
  126.  
  127.   // Configure settings for when the PSU is booted:
  128.   digitalWrite(outputPinChime, HIGH);
  129.   digitalWrite(outputPinCabinNoise, HIGH);
  130.   lightCallBellRed = 1;
  131.   lightCallBellBlue = 0;
  132.   switchOutputs();
  133.   delay(startUpDelay);
  134.    lightCallBellRed = 0;
  135.   lightCallBellRed = 0;
  136.   switchOutputs();
  137.   delay(startUpDelay);
  138.    lightCallBellRed = 1;
  139.   lightReadingA = 1;
  140.   switchOutputs();
  141.   delay(startUpDelay);
  142.    lightCallBellRed = 0;
  143.   lightReadingB = 1;
  144.   switchOutputs();
  145.   delay(startUpDelay);
  146.    lightCallBellRed = 1;
  147.   lightReadingC = 1;
  148.   switchOutputs();
  149.   delay(startUpDelay);
  150.    lightCallBellRed = 0;
  151.   lightSeatBelts = 1;
  152.   switchOutputs();
  153.   delay(startUpDelay);
  154.    lightCallBellRed = 1;
  155.   lightNoSmoking = 1;
  156.   switchOutputs();
  157.   delay(startUpDelay);
  158.   lightCallBellRed = 0;
  159.   masks = 0;
  160.   switchOutputs();
  161.   delay(startUpDelay);
  162.   lightCallBellRed = 1;
  163.   switchOutputs();
  164.   delay(startUpDelay);
  165.   lightCallBellRed = 0;
  166.   blower = 1;
  167.   switchOutputs();
  168.   delay(startUpDelay);
  169.   lightCallBellRed = 0;
  170.   startCabinNoise();  
  171.   lastInputTime = millis();
  172. }
  173.  
  174. void loop() {     // These subroutines run thousands of times a second.
  175.  
  176.   currentMillis = millis(); // Take note of the time at which this loop started.
  177.   readInputs();             // Find out what buttons are pressed.
  178.   process();                // Figure out what to do with all of those inputs.
  179.   switchOutputs();          // Switch LEDS and relays on and off as necessary.
  180.   updateSerial();           // Update a serial monitor for troubleshooting.
  181.   maskReset();              // Monitor the status of the mask deployment actuator and reset it when necessary.
  182.   maskDropTimer();          // Run the red flashing light during call-bell long-press, and activate mask drop.
  183.   switchPartyMode();        // Check whether buttons A and B are pressed simultaneously, toggling party mode and confirming with lights.
  184.   autoShutdown();           // Check to see whether it's time to shut down the unit during normal operation (i.e. party mode is not enabled)
  185.   restartAudio();           // If the audio file is nearly finished, restart it - as long as the unit hasn't shut down.
  186.   restartAfterShutdown();   // while the unit is shutdown, monitor the buttons and 'wake up' if one of them is pressed.
  187.   // delay(200) ;           // DURING TESTING ONLY: SLOW EVERYTHING DOWN A BIT SO WE DON'T BREAK ANYTHING!
  188. }
  189.  
  190. void restartAudio() {       // If the audio file is nearly finished, restart it - as long as the unit hasn't shut down.
  191.   if (currentMillis - audioRestartedLast > lengthOfAudioFile && autoShutdownActivated == 0) { // If the lengthOfAudioFile has past, and the unit hasn't shut down...
  192.     startCabinNoise();      // Restart the cabin noise track from the start.
  193.   }
  194. }
  195.  
  196. void restartAfterShutdown() {           // while the unit is shutdown, monitor the buttons and 'wake up' if one of them is pressed.
  197.   if (autoShutdownActivated == 1) {     // if the unit is currently shut down...
  198.     if (buttonCallBell || buttonA || buttonB || buttonC )     // and if one the buttons is pressed...
  199.     {
  200.       autoShutdownActivated = 0;        // set the autoShutdownActivated flag to 0.
  201.       startCabinNoise();                // Restart the cabin noise track from the start.
  202.       lightNoSmoking = 1;               // Switch the no smoking light on.
  203.       lightSeatBelts = 1;               // Switch the seat belt light on.
  204.     }
  205.   }
  206. }
  207.  
  208. void readInputs() {  // Find out what buttons are pressed.
  209.   buttonCallBell  = !digitalRead(inputPinButtonCallBell);   // If this button is 'LOW' (remember we're using a pullup resistor) then set the relevant status to 'HIGH'.
  210.   buttonA         = !digitalRead(inputPinButtonA);          // If this button is 'LOW' (remember we're using a pullup resistor) then set the relevant status to 'HIGH'.
  211.   buttonB         = !digitalRead(inputPinButtonB);          // If this button is 'LOW' (remember we're using a pullup resistor) then set the relevant status to 'HIGH'.
  212.   buttonC         = !digitalRead(inputPinButtonC);          // If this button is 'LOW' (remember we're using a pullup resistor) then set the relevant status to 'HIGH'.
  213. }
  214.  
  215.  
  216.  
  217. void process() {    // Figure out what to do with all of those inputs.
  218.   // PROCESS FOR CALL BELL BUTTON **********************************************************************************************
  219.   if (buttonCallBell) {                                                 // if the button is pressed...
  220.     buttonCallBellActive = 1;                                           // set the 'active' status of this button to 1
  221.     lastInputTime = currentMillis;                                      // set the last input time to now.
  222.   };
  223.  
  224.   if (buttonCallBellActive && !buttonCallBell) {                        // if the status is 'active' and the button has now been released...
  225.     if (currentMillis - lightCallBellBlueLastToggled > toggleTime && currentMillis - buttonCallBellLastOff < longPressTime) { // if it was a short-press, and the light hasn't just been already toggled.
  226.       if (lightCallBellBlue == 0) {                                     // if the call bell light is currently off (We only want it to chime when it goes from OFF to ON, and not the other way around.)
  227.         startCabinChime();                                              // start the cabin sound track that starts with a chime.
  228.       }
  229.       lightCallBellBlue = !lightCallBellBlue;                           // toggle the light
  230.       lightCallBellBlueLastToggled = currentMillis;                     // and take note of the time it was toggled.
  231.     }
  232.     if (maskButtonReleaseActive == 1) {                                 // if it was a long-press:
  233.       masks = 1;                                                        // set the mask release flag to 1
  234.       masksReleasedAt = currentMillis;                                  // take note of the time it was done.
  235.       ("The masks were deployed");
  236.     }
  237.     buttonCallBellActive = 0;                                           // otherwise, ignore the fact the button was pressed and released.
  238.   }
  239.   if (!buttonCallBell) {                                                // if the button is not pressed...
  240.     buttonCallBellLastOff = currentMillis;                              // take note of the time (now) that it was last not pressed.
  241.     buttonCallBellActive = 0;                                           // and set the active flag back to 0.
  242.   }
  243.  
  244.   // PROCESS FOR READING LIGHT A BUTTON *****************************************************************************************
  245.   if (buttonA) {                                                 // if the button is pressed...
  246.     buttonAActive = 1;                                           // set the 'active' status of this button to 1
  247.     lastInputTime = currentMillis;                                      // set the last input time to now.
  248.   };
  249.   if (buttonAActive && !buttonA) {                        // if the status is 'active' and the button has now been released...
  250.     if (currentMillis - lightReadingALastToggled > toggleTime && currentMillis - buttonALastOff < longPressTime) { // if it was a short-press, and the light hasn't just been already toggled.
  251.       lightReadingA = !lightReadingA;                           // toggle the light
  252.       lightReadingALastToggled = currentMillis;                     // and take note of the time it was toggled.
  253.       buttonAActive = 0;                                           // and set the active flag back to 0.
  254.     }
  255.   }
  256.   if (buttonAActive && currentMillis - buttonALastOff > longPressTime && currentMillis - lightNoSmokingLastToggled  > toggleTime) {        // if it was a long-press and the light hasn't been toggled recently.
  257.     Serial.println("Toggling No Smoking Light");
  258.     lightNoSmoking = !lightNoSmoking;                            // toggle the light.
  259.     lightNoSmokingLastToggled = currentMillis;                   // and take note of the time it was toggled.
  260.     buttonAActive = 0;                                           // and set the active flag back to 0.
  261.   }
  262.  
  263.   if (!buttonA) {                                                // if the button is not pressed...
  264.     buttonALastOff = currentMillis;                              // take note of the time (now) that it was last not pressed.
  265.     buttonAActive = 0;                                           // and set the active flag back to 0.
  266.   }
  267.  
  268.   // PROCESS FOR READING LIGHT B BUTTON *****************************************************************************************
  269.   if (buttonB) {                                                 // if the button is pressed...
  270.     buttonBActive = 1;                                           // set the 'active' status of this button to 1
  271.     lastInputTime = currentMillis;                                      // set the last input time to now.
  272.   };
  273.   if (buttonBActive && !buttonB) {                        // if the status is 'active' and the button has now been released...
  274.     if (currentMillis - lightReadingBLastToggled > toggleTime && currentMillis - buttonBLastOff < longPressTime) { // if it was a short-press, and the light hasn't just been already toggled.
  275.       lightReadingB = !lightReadingB;                           // toggle the light
  276.       lightReadingBLastToggled = currentMillis;                     // and take note of the time it was toggled.
  277.       buttonBActive = 0;                                           // otherwise, ignore the fact the button was pressed and released.
  278.     }
  279.   }
  280.   if (buttonBActive && currentMillis - buttonBLastOff > longPressTime && currentMillis - blowerLastToggled  > toggleTime) {        // if it was a long-press and the light hasn't been toggled recently.
  281.     blower = !blower;                            // toggle the light.
  282.     blowerLastToggled = currentMillis;                   // and take note of the time it was toggled.
  283.     buttonBActive = 0;                                           // otherwise, ignore the fact the button was pressed and released.
  284.   }
  285.   if (!buttonB) {                                                // if the button is not pressed...
  286.     buttonBLastOff = currentMillis;                              // take note of the time (now) that it was last not pressed.
  287.     buttonBActive = 0;                                           // and set the active flag back to 0.
  288.   }
  289.  
  290.  
  291.   // PROCESS FOR READING LIGHT C BUTTON *****************************************************************************************
  292.   if (buttonC) {                                                 // if the button is pressed...
  293.     buttonCActive = 1;                                           // set the 'active' status of this button to 1
  294.     lastInputTime = currentMillis;                                      // set the last input time to now.
  295.   };
  296.   if (buttonCActive && !buttonC) {                        // if the status is 'active' and the button has now been released...
  297.     if (currentMillis - lightReadingCLastToggled > toggleTime && currentMillis - buttonCLastOff < longPressTime) { // if it was a short-press, and the light hasn't just been already toggled.
  298.       lightReadingC = !lightReadingC;                           // toggle the light
  299.       lightReadingCLastToggled = currentMillis;                     // and take note of the time it was toggled.
  300.       buttonCActive = 0;                                           // otherwise, ignore the fact the button was pressed and released.
  301.     }
  302.   }
  303.   if (buttonCActive && currentMillis - buttonCLastOff > longPressTime && currentMillis - lightSeatBeltsLastToggled  > toggleTime) {        // if it was a long-press and the light hasn't been toggled recently.
  304.     lightSeatBelts = !lightSeatBelts;                            // toggle the light.
  305.     lightSeatBeltsLastToggled = currentMillis;                   // and take note of the time it was toggled.
  306.     buttonCActive = 0;                                           // otherwise, ignore the fact the button was pressed and released.
  307.   }
  308.   if (!buttonC) {                                                // if the button is not pressed...
  309.     buttonCLastOff = currentMillis;                              // take note of the time (now) that it was last not pressed.
  310.     buttonCActive = 0;                                           // and set the active flag back to 0.
  311.   }
  312. }// end of process
  313.  
  314. void switchOutputs() {    // Switch LEDS and relays on and off as necessary.
  315.   digitalWrite(outputPinlightReadingA, !lightReadingA);
  316.   digitalWrite(outputPinlightReadingB, !lightReadingB);
  317.   digitalWrite(outputPinlightReadingC, !lightReadingC);
  318.   digitalWrite(outputPinLightCallBellBlue, lightCallBellBlue);
  319.   digitalWrite(outputPinLightCallBellRed, lightCallBellRed);
  320.   digitalWrite(outputPinMasks, !masks);
  321.   digitalWrite(outputPinlightNoSmoking , !lightNoSmoking);
  322.   digitalWrite(outputPinlightSeatBelts , !lightSeatBelts);
  323.   digitalWrite(outputPinBlower , !blower);
  324. }
  325.  
  326. void maskReset() { // if the mask panel actuator has been triggered, reset it after maskActiveTime so that it can be manually reset.
  327.   if (masks == 1 && currentMillis - masksReleasedAt > maskActiveTime) {
  328.     masks = 0;
  329.     Serial.println("The masks were reset");
  330.   }
  331. }
  332.  
  333. void startCabinNoise() {                        // Restart the cabin noise track from the start.
  334.   Serial.println("startCabinNoise()");
  335.   digitalWrite(outputPinCabinNoise , LOW);      // Set the cabin noise pin to low (this triggers the track playing).
  336.   delay(200);                                   // Wait a moment.
  337.   digitalWrite(outputPinCabinNoise , HIGH);     // Set the cabin noise pin back to high (ready to be reacivated when necessary).
  338.   audioRestartedLast = currentMillis;           // For the purpose of restarting the track when it's finished (restartAudio()), take note of the time.
  339.  
  340. }
  341.  
  342. void startCabinChime() {                        // Restart the cabin noise track 'that starts with a chime' from the start.
  343.   Serial.println("startCabinChime()");
  344.   digitalWrite(outputPinChime , LOW);           // Set the cabin noise pin to low (this triggers the track playing).
  345.   delay(200);                                   // Wait a moment.
  346.   digitalWrite(outputPinChime , HIGH);          // Set the cabin noise pin back to high (ready to be reacivated when necessary).
  347.   audioRestartedLast = currentMillis;           // For the purpose of restarting the track when it's finished (restartAudio()), take note of the time.
  348. }
  349.  
  350. void maskDropTimer() {              // Run the red flashing light during call-bell long-press, and activate mask drop.
  351.   if ((currentMillis - buttonCallBellLastOff > 500 && currentMillis - buttonCallBellLastOff < 1000) ||
  352.   (currentMillis - buttonCallBellLastOff > 1500 && currentMillis - buttonCallBellLastOff < 2000) ||
  353.   (currentMillis - buttonCallBellLastOff > 2500 && currentMillis - buttonCallBellLastOff < 3000)) { // if the call bell flashing sequence is in it's 'on' phase...
  354.     lightCallBellRed = 1;                                                                           // turn lightCallBellRed to 'on'.
  355.   } else {                                                                                          // else
  356.     lightCallBellRed = 0;                                                                           // turn lightCallBellRed to 'off'.
  357.   }
  358.  
  359.   if (currentMillis - buttonCallBellLastOff > 3500 && currentMillis - buttonCallBellLastOff < 4000) {  // if the call bell flashing sequence is in it's fourth 'on' phase...  
  360.     lightCallBellRed = 1;                                                                            // turn lightCallBellRed to 'on'.
  361.     maskButtonReleaseActive = 1;                                                                     // and set maskButtonReleaseActive to on, meaning that releasing it during this phase will drop the masks
  362.   } else {                                                                                           // else
  363.     maskButtonReleaseActive = 0;                                                                     // leave maskButtonReleaseActive off.
  364.   }
  365. }
  366.  
  367. void switchPartyMode() {                        // Check whether buttons A and B are pressed simultaneously, toggling party mode and confirming with lights.
  368.   if (buttonA && buttonB && partyMode) {        // if buttons A and B are pressed, and party mode is currently set to on,
  369.     Serial.println("Party Mode OFF");
  370.     digitalWrite(outputPinlightReadingA, 0);    // flash the lights alternately.
  371.     digitalWrite(outputPinlightReadingB, 0);
  372.     digitalWrite(outputPinlightReadingC, 0);
  373.     delay(500);
  374.     digitalWrite(outputPinlightReadingA, 1);
  375.     digitalWrite(outputPinlightReadingB, 1);
  376.     digitalWrite(outputPinlightReadingC, 1);
  377.     delay(500);
  378.     digitalWrite(outputPinlightReadingA, 0);
  379.     digitalWrite(outputPinlightReadingB, 0);
  380.     digitalWrite(outputPinlightReadingC, 0);
  381.     delay(500);
  382.     partyModeLastToggled = currentMillis;       // take note of the current time to debounce party mode.
  383.     partyMode = 0;                              // set party mode to 'off'
  384.     everythingOff();                            // turn everything off.
  385.   }
  386.   if (buttonA && buttonB && !partyMode) {     // if buttons A and B are pressed, and party mode is currently set to off.
  387.     Serial.println("Party Mode ON");
  388.     digitalWrite(outputPinlightReadingA, 0);    // flash the lights together.
  389.     digitalWrite(outputPinlightReadingB, 1);
  390.     digitalWrite(outputPinlightReadingC, 0);
  391.     delay(500);
  392.     digitalWrite(outputPinlightReadingA, 1);
  393.     digitalWrite(outputPinlightReadingB, 0);
  394.     digitalWrite(outputPinlightReadingC, 1);
  395.     delay(500);
  396.     digitalWrite(outputPinlightReadingA, 0);
  397.     digitalWrite(outputPinlightReadingB, 1);
  398.     digitalWrite(outputPinlightReadingC, 0);
  399.     delay(500);
  400.     partyModeLastToggled = currentMillis;       // take note of the current time to debounce party mode.
  401.     partyMode = 1;                              // set party mode to 'on'.
  402.     everythingOn();                             // turn everything on.
  403.   }
  404. }
  405.  
  406. void everythingOff() {            // what to do when we 'turn everything off'.
  407.   Serial.println("Turning everything OFF");
  408.   lightCallBellBlue = 0;
  409.   lightCallBellRed = 0;
  410.   lightReadingA = 0;
  411.   lightReadingB = 0;
  412.   lightReadingC = 0;
  413.   lightSeatBelts = 0;
  414.   lightNoSmoking = 0;
  415.   blower = 0;
  416.   buttonA = 0;
  417.   buttonB = 0;
  418.   buttonC = 0;
  419.   buttonAActive = 0;
  420.   buttonBActive = 0;
  421.   buttonCActive = 0;
  422. }
  423.  
  424. void everythingOn() {             // what to do when we 'turn everything on'.
  425.   Serial.println("Turning everything ON");
  426.   lightCallBellBlue = 0;
  427.   lightCallBellRed = 0;
  428.   lightReadingA = 1;
  429.   lightReadingB = 1;
  430.   lightReadingC = 1;
  431.   lightSeatBelts = 1;
  432.   lightNoSmoking = 1;
  433.   blower = 1;
  434.   buttonA = 0;
  435.   buttonB = 0;
  436.   buttonC = 0;
  437.   buttonAActive = 0;
  438.   buttonBActive = 0;
  439.   buttonCActive = 0;
  440. }
  441.  
  442. void updateSerial() {                                                 // Update a serial monitor for troubleshooting.
  443.   if (currentMillis - serialUpdatedLast > serialUpdateTime) {
  444.     // Button states:
  445.     Serial.print("Buttons A");
  446.     Serial.print(buttonA);
  447.     Serial.print(" B");
  448.     Serial.print(buttonB);
  449.     Serial.print(" C ");
  450.     Serial.print(buttonC);
  451.     Serial.print(" Call ");
  452.     Serial.print(buttonCallBell);
  453.  
  454.     // Equipment states:
  455.     Serial.print("      BLU:");
  456.     Serial.print(lightCallBellBlue);
  457.     Serial.print(" RED:");
  458.     Serial.print(lightCallBellRed);
  459.     Serial.print(" RL A");
  460.     Serial.print(lightReadingA);
  461.     Serial.print(" B");
  462.     Serial.print(lightReadingB);
  463.     Serial.print(" C");
  464.     Serial.print(lightReadingC);
  465.     Serial.print("      FSB:");
  466.     Serial.print(lightSeatBelts);
  467.     Serial.print(" NS:");
  468.     Serial.print(lightNoSmoking);
  469.     Serial.print(" MSK:");
  470.     Serial.print(masks);
  471.     Serial.print(" BLW:");
  472.     Serial.print(blower);
  473.     Serial.print(" Party:");
  474.     Serial.print(partyMode);
  475.  
  476.     // System up-time:
  477.     Serial.print("      UP: ");
  478.     Serial.print(abs(currentMillis / 86400000));
  479.     Serial.print("d ");
  480.     Serial.print(abs(currentMillis / 3600000) - abs(currentMillis / 86400000) * 24);
  481.     Serial.print("h ");
  482.     Serial.print(abs(currentMillis / 60000) - (abs(currentMillis / 3600000) * 60));
  483.     Serial.print("m ");
  484.     Serial.print((currentMillis / 1000) - (abs(currentMillis / 60000) * 60));
  485.     Serial.print ("s");
  486.  
  487.     // Autoshutdown:
  488.     if (partyMode == 0) {
  489.       Serial.print("   Auto-shutdown in: ");
  490.       Serial.print(timeToShutdown);
  491.     } else {
  492.       Serial.print("   Party Mode enabled.");
  493.     }
  494.  
  495.     Serial.println(""); // start a new line:
  496.  
  497.     serialUpdatedLast = currentMillis;
  498.   }
  499. }
  500.  
  501. void autoShutdown() {           // Check to see whether it's time to shut down the unit during normal operation (i.e. party mode is not enabled).
  502.   if (partyMode == 0) {         // if party mode is currently set to 'off'.
  503.     if (((autoOffTime - (currentMillis - lastInputTime)) / 1000) > 400000) { //  If the 'time to shut-down isn't an erroneously  high number.
  504.       timeToShutdown = (autoOffTime / 1000);                                  // set  timeToShutdown to the autoOffTime in seconds.
  505.     } else {                                                                  // else (if it's an erroneously high number)
  506.       timeToShutdown = (autoOffTime - (currentMillis - lastInputTime)) / 1000;  // set it to the number of seconds till shutdown.
  507.     }
  508.   }
  509.   if (timeToShutdown < 1) {                 // if the timeToShutdown is under 1 second...
  510.     lastInputTime = currentMillis;          // set the last input time to now
  511.     everythingOff();                        // turn everything off.
  512.     autoShutdownActivated = 1;              // activate shutdown mode.
  513.   }
  514. }
Advertisement
Add Comment
Please, Sign In to add comment