Index: firmware/App/Controllers/UVReactors.c =================================================================== diff -u -r55a8b1f7f4e8a8eaf6dc83f0d5fcf0a3e36a7027 -rbcb768dd6a13286e028533394916a9f69c9f254f --- firmware/App/Controllers/UVReactors.c (.../UVReactors.c) (revision 55a8b1f7f4e8a8eaf6dc83f0d5fcf0a3e36a7027) +++ firmware/App/Controllers/UVReactors.c (.../UVReactors.c) (revision bcb768dd6a13286e028533394916a9f69c9f254f) @@ -34,42 +34,45 @@ // ********** private definitions ********** -#define INLET_UV_REACTOR_ENABLE_PIN 0 ///< Inlet UV reactor GPIO pin number (enable pin). -#define OUTLET_UV_REACTOR_ENABLE_PIN 1 ///< Outlet UV reactor GPIO pin number (enable Pin). -#define INLET_UV_REACTOR_INDICATION_PIN 0x18 ///< Inlet UV reactor N2HET1 pin number (health check). -#define OUTLET_UV_REACTOR_INDICATION_PIN 0x0B ///< Outlet UV reactor N2HET1 pin number (health check). -#define UV_REACTORS_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< UV reactors data publication time interval. -/// Self test wait time after enabling the reactors and before checking for their health in ms. -#define SELF_TEST_DELAY_TIME 1000 -#define MAX_ALLOWED_UNHEALTHY_REACTOR_PERIOD MS_PER_SECOND ///< UV reactors unhealthy state period. -#define DATA_PUBLISH_COUNTER_START_COUNT 90 ///< Data publish counter start count. +#define INLET_UV_REACTOR_ENABLE_PIN 0 ///< Inlet UV reactor GPIO pin number (enable pin). +#define OUTLET_UV_REACTOR_ENABLE_PIN 1 ///< Outlet UV reactor GPIO pin number (enable Pin). +#define INLET_UV_REACTOR_INDICATION_PIN 0x18 ///< Inlet UV reactor N2HET1 pin number (health check). +#define OUTLET_UV_REACTOR_INDICATION_PIN 0x0B ///< Outlet UV reactor N2HET1 pin number (health check). +#define UV_REACTORS_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< UV reactors data publication time interval. +#define SELF_TEST_DELAY_TIME 1000 ///< Self test wait time after enabling the reactors and before checking for their health in ms. +#define MAX_ALLOWED_UNHEALTHY_REACTOR_PERIOD MS_PER_SECOND ///< UV reactors unhealthy state period. +#define DATA_PUBLISH_COUNTER_START_COUNT 90 ///< Data publish counter start count. +#define UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS ( 1 * MS_PER_SECOND ) ///< UV reactors on with no flow time out in milliseconds. + /// UV reactors self test states typedef enum self_tests { - UV_REACTORS_SELF_TEST_OFF = 0, ///< UV reactors self test state off - UV_REACTORS_SELF_TEST_CHECK_HEALTH, ///< UV reactors self test check health - UV_REACTORS_SELF_TEST_COMPLETE, ///< UV reactors self test complete - NUM_OF_UV_REACTORS_SELF_TEST_STATES, ///< Number of UV reactors self test states + UV_REACTORS_SELF_TEST_OFF = 0, ///< UV reactors self test state off. + UV_REACTORS_SELF_TEST_CHECK_HEALTH, ///< UV reactors self test check health. + UV_REACTORS_SELF_TEST_COMPLETE, ///< UV reactors self test complete. + NUM_OF_UV_REACTORS_SELF_TEST_STATES, ///< Number of UV reactors self test states. } UV_REACTORS_SELF_TEST_STATE_T; /// UV reactors exec states typedef enum exec_states { - UV_REACTOR_STATE_OFF = 0, ///< UV reactor state off - UV_REACTOR_STATE_ON, ///< UV reactor state on - NUM_OF_UV_REACTOR_STATES, ///< Number of UV reactor states + UV_REACTOR_STATE_OFF = 0, ///< UV reactor state off. + UV_REACTOR_STATE_ON, ///< UV reactor state on. + NUM_OF_UV_REACTOR_STATES, ///< Number of UV reactor states. } UV_REACTOR_STATE_T; /// UV reactor status typedef struct { - UV_REACTOR_STATE_T execState; ///< UV reactor executive state - PIN_SIGNAL_STATE_T pinSignalState; ///< UV reactor pin signal state - UV_REACTOR_STATES_T switchState; ///< UV reactor turn on/turn off state - U32 reactorEnablePin; ///< UV reactor enable pin of GIO port A - U32 reactorHealthStatusPin; ///< UV reactor status pin of N2HET1 - OVERRIDE_U32_T healthStatus; ///< UV reactor current health status + UV_REACTOR_STATE_T execState; ///< UV reactor executive state. + PIN_SIGNAL_STATE_T pinSignalState; ///< UV reactor pin signal state. + UV_REACTOR_STATES_T switchState; ///< UV reactor turn on/turn off state. + U32 reactorEnablePin; ///< UV reactor enable pin of GIO port A. + U32 reactorHealthStatusPin; ///< UV reactor status pin of N2HET1. + OVERRIDE_U32_T healthStatus; ///< UV reactor current health status. + BOOL isFlowBelowMin; ///< UV reactor flag to indicate the flow is below minimum. + U32 reactorOnWithNoFlowTimer; ///< UV reactor on with no flow start time. } UV_REACTOR_STATUS_T; // ********** private data ********** @@ -129,6 +132,7 @@ reactorsStatus[ reactor ].pinSignalState = PIN_SIGNAL_LOW; reactorsStatus[ reactor ].execState = UV_REACTOR_STATE_OFF; reactorsStatus[ reactor ].switchState = TURN_OFF; + setReactorEnableStatus( reactor, PIN_SIGNAL_LOW ); } @@ -363,17 +367,22 @@ { UV_REACTOR_STATE_T state = UV_REACTOR_STATE_OFF; - // Set the health status to be off. When the reactor is off, it does not report - // its health status - reactorsStatus[reactor].healthStatus.data = (U32)UV_REACTOR_OFF; + // Set the health status to be off. When the reactor is off, it does not report its health status + reactorsStatus[ reactor ].healthStatus.data = (U32)UV_REACTOR_OFF; - // If the a reactor is requested to be on and it is off, turn it on - // and change the state + // Check if the a reactor is requested to be on and it is off if ( TURN_ON == reactorsStatus[ reactor ].switchState ) { - setReactorEnableStatus( reactor, PIN_SIGNAL_HIGH ); + // Check if the flow is below minimum + reactorsStatus[ reactor ].isFlowBelowMin = ( getMeasuredROFlowRateLPM() < MIN_RO_FLOWRATE_LPM ? TRUE : FALSE ); - state = UV_REACTOR_STATE_ON; + // If the flow is no longer below minimum and the reactor is requested to be on, turn it back on + if ( FALSE == reactorsStatus[ reactor ].isFlowBelowMin ) + { + setReactorEnableStatus( reactor, PIN_SIGNAL_HIGH ); + + state = UV_REACTOR_STATE_ON; + } } return state; @@ -408,6 +417,27 @@ } } + // Check if the flow is below minimum + BOOL isFlowBelowMin = ( getMeasuredROFlowRateLPM() < MIN_RO_FLOWRATE_LPM ? TRUE : FALSE ); + + if ( TRUE == isFlowBelowMin ) + { + // If the flow is below minimum for the first time, start the timer + if ( FALSE == reactorsStatus[ reactor ].isFlowBelowMin ) + { + reactorsStatus[ reactor ].isFlowBelowMin = TRUE; + reactorsStatus[ reactor ].reactorOnWithNoFlowTimer = getMSTimerCount(); + } + else if ( TRUE == didTimeout( reactorsStatus[ reactor ].reactorOnWithNoFlowTimer, UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS ) ) + { + // If the flow is below minimum and the allowed time has elapsed, set the reactor's signal to be low and set its state + // to be off. + setReactorEnableStatus( reactor, PIN_SIGNAL_LOW ); + // The state is directly changed here because the switch state is not changed to be off + reactorsStatus[ reactor ].execState = UV_REACTOR_STATE_OFF; + } + } + // Check if it has been requested to turn off a reactor if ( TURN_OFF == reactorsStatus[ reactor ].switchState ) { @@ -463,6 +493,7 @@ if ( ++dataPublishCounter > getU32OverrideValue( &uvReactorsDataPublishInterval ) ) { UV_REACTORS_DATA_T uvReactorsData; + // Publish the reactors health status uvReactorsData.inletUVReactorHealthStatus = (U32)getUVReactorHealth( INLET_UV_REACTOR ); uvReactorsData.outletUVReactorHealthStatus = (U32)getUVReactorHealth( OUTLET_UV_REACTOR );