Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -r2e21405574597474db0ebae86cdd7fa2d517f71c -r19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 2e21405574597474db0ebae86cdd7fa2d517f71c) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c) @@ -74,6 +74,11 @@ #define DRAIN_PUMP_OFF_RPM_ADC_COUNT 0xFFFF ///< ADC count value when pump is off. #define DATA_PUBLISH_COUNTER_START_COUNT 60 ///< Data publish counter start count. +#define DRAIN_PUMP_MAX_CURRENT_WHEN_OFF_A 0.1F ///< Drain pump maximum current when the pump is off in amps. +#define DRAIN_PUMP_MAX_CURRENT_A 2.2F ///< Drain pump maximum current in amps. +#define DRAIN_PUMP_CURRENT_OUT_OF_RANGE_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Drain pump current out of range timeout in milliseconds. +#define DRAIN_PUMP_DIR_OF_RANGE_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Drain pump direction out of range timeout in milliseconds. +#define DRAIN_PUMP_FORWARD_DIR 0 ///< Drain pump forward direction. /// Enumeration of drain pump states. typedef enum DrainPump_States @@ -95,32 +100,32 @@ // ********** private data ********** -static DRAIN_PUMP_STATE_T drainPumpState = DRAIN_PUMP_OFF_STATE; ///< Current state of drain pump controller state machine. +static DRAIN_PUMP_STATE_T drainPumpState; ///< Current state of drain pump controller state machine. static U32 drainPumpDataPublicationTimerCounter; ///< Used to schedule drain pump data publication to CAN bus. -static U32 drainPumpDAC = 0; ///< Initial drain pump DAC value. -static U32 drainPumpDACSet = 0; ///< Currently set drain pump DAC value. -static PUMP_CONTROL_MODE_T drainPumpControlMode = NUM_OF_PUMP_CONTROL_MODES; ///< Requested drain pump control mode. -static PUMP_CONTROL_MODE_T drainPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< Currently set drain pump control mode. - +static U32 drainPumpDAC; ///< Initial drain pump DAC value. +static U32 drainPumpDACSet; ///< Currently set drain pump DAC value. +static PUMP_CONTROL_MODE_T drainPumpControlMode; ///< Requested drain pump control mode. +static PUMP_CONTROL_MODE_T drainPumpControlModeSet; ///< Currently set drain pump control mode. static OVERRIDE_U32_T drainPumpDataPublishInterval = { DRAIN_PUMP_DATA_PUB_INTERVAL, DRAIN_PUMP_DATA_PUB_INTERVAL, 0, 0 }; ///< Interval (in ms) at which to publish drain pump data to CAN bus. -static U32 targetDrainPumpRPM = 0; ///< Target drain pump RPM. -static F32 targetDrainPumpOutletPressure = 0.0; ///< Target outlet pressure for the drain pump. - -static U32 drainControlTimerCounter = 0; ///< Determines when to perform control on drain pump. -static BOOL hasClosedLoopBeenRequested = FALSE; ///< Closed loop pump control flag. +static U32 targetDrainPumpRPM; ///< Target drain pump RPM. +static F32 targetDrainPumpOutletPressure; ///< Target outlet pressure for the drain pump. +static U32 drainControlTimerCounter; ///< Determines when to perform control on drain pump. +static BOOL hasClosedLoopBeenRequested; ///< Closed loop pump control flag. static OVERRIDE_U32_T drainPumpMeasuredRPM = { 0, 0, 0, 0 }; ///< Measured drain pump RPM from feedback. -static BOOL signalNewRPMRequest = FALSE; ///< Signal flag the indicates there is a new RPM request. - -static DRAIN_PUMP_STATE_T pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; ///< Delayed (pending) drain pump command. -static F32 pendingDrainPumpCmdTarget = 0.0; ///< Delayed (pending) drain pump command target (rpm or PSI depending on command). -static U32 pendingDrainPumpCmdCountDown = 0; ///< Delayed (pending) drain pump command count down timer (in task intervals). +static OVERRIDE_F32_T drainPumpMeasuredCurrentA = { 0.0F, 0.0F, 0.0F, 0 }; ///< Measured drain pump current feedback. +static OVERRIDE_U32_T drainPumpMeasuredDir = { 0, 0, 0, 0 }; ///< Measured drain pump direction. +static BOOL signalNewRPMRequest; ///< Signal flag the indicates there is a new RPM request. +static DRAIN_PUMP_STATE_T pendingDrainPumpCmd; ///< Delayed (pending) drain pump command. +static F32 pendingDrainPumpCmdTarget; ///< Delayed (pending) drain pump command target (rpm or PSI depending on command). +static U32 pendingDrainPumpCmdCountDown; ///< Delayed (pending) drain pump command count down timer (in task intervals). static DG_DRAIN_LINE_VOLUME_T drainLineVolumeRecord; ///< Drain line volume record. static DG_DRAIN_PUMP_CAL_RECORD_T drainPumpCalRecord; ///< Drain pump calibration record. /// ADC to RPM conversion coefficient or RPM to ADC conversion. -static const F32 CONVERSION_COEFF = (F32) SEC_PER_MIN / ( 2.0F * TOGGLE_PERIOD_RESOLUTION_SECONDS * ROTATIONAL_TO_TOGGLE_PERIOD_CONVERSION ); +static const F32 RPM_CONVERSION_COEFF = (F32) SEC_PER_MIN / ( 2.0F * TOGGLE_PERIOD_RESOLUTION_SECONDS * ROTATIONAL_TO_TOGGLE_PERIOD_CONVERSION ); +static const F32 CURRENT_CONVERSION_COEFF = (F32)( 1.0F / BITS_11_FULL_SCALE ); // ********** private function prototypes ********** @@ -129,18 +134,36 @@ static DRAIN_PUMP_STATE_T handleDrainPumpOpenLoopState( void ); static void stopDrainPump( void ); static void publishDrainPumpData( void ); +static F32 getDrainPumpMeasuredCurrentA( void ); +static U32 getDrainPumpMeasuredDirection( void ); /*********************************************************************//** * @brief * The initDrainPump function initializes the DrainPump module. * @details Inputs: none - * @details Outputs: hasClosedLoopBeenRequested, signalNewRPMRequest + * @details Outputs: drainPumpState, drainPumpDAC, drainPumpDACSet, + * drainPumpControlMode, drainPumpControlModeSet, targetDrainPumpRPM, + * targetDrainPumpOutletPressure, drainControlTimerCounter, + * pendingDrainPumpCmd, pendingDrainPumpCmdTarget, pendingDrainPumpCmdCountDown, + * hasClosedLoopBeenRequested, signalNewRPMRequest, + * drainPumpDataPublicationTimerCounter, * @return none *************************************************************************/ void initDrainPump( void ) { stopDrainPump(); + drainPumpState = DRAIN_PUMP_OFF_STATE; + drainPumpDAC = 0; + drainPumpDACSet = 0; + drainPumpControlMode = NUM_OF_PUMP_CONTROL_MODES; + drainPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP; + targetDrainPumpRPM = 0; + targetDrainPumpOutletPressure = 0.0F; + drainControlTimerCounter = 0; + pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; + pendingDrainPumpCmdTarget = 0.0F; + pendingDrainPumpCmdCountDown = 0; hasClosedLoopBeenRequested = FALSE; signalNewRPMRequest = FALSE; drainPumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; @@ -149,11 +172,11 @@ initializePIController( PI_CONTROLLER_ID_DRAIN_PUMP, DRAIN_PUMP_MIN_DAC, DRAIN_PUMP_P_COEFFICIENT, DRAIN_PUMP_I_COEFFICIENT, DRAIN_PUMP_MIN_DAC, DRAIN_PUMP_MAX_DAC ); - // Initialize the persistent alarm for open loop RPM out of range + // Initialize the persistent alarms initPersistentAlarm( ALARM_ID_DRAIN_PUMP_RPM_OUT_OF_RANGE, OPEN_LOOP_RPM_OUT_OF_RANGE_TIME_OUT, OPEN_LOOP_RPM_OUT_OF_RANGE_TIME_OUT ); - - // Initialize the persistent alarm for RPM not to be less than the min RPM when the pump is off initPersistentAlarm( ALARM_ID_DRAIN_PUMP_OFF_FAULT, SAFETY_SHUTDOWN_TIMEOUT, SAFETY_SHUTDOWN_TIMEOUT ); + initPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_CURRENT_OUT_OF_RANGE, DRAIN_PUMP_CURRENT_OUT_OF_RANGE_TIMEOUT_MS, DRAIN_PUMP_CURRENT_OUT_OF_RANGE_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, DRAIN_PUMP_DIR_OF_RANGE_TIMEOUT_MS, DRAIN_PUMP_DIR_OF_RANGE_TIMEOUT_MS ); } /*********************************************************************//** @@ -315,49 +338,102 @@ * The execDrainPumpMonitor function executes the drain pump monitor. * RPM = ( 1 / ADC ) * conversion coefficient. * ADC = ( 1 / RPM ) * conversion coefficient. - * @details Inputs: drainPumpControlModeSet, drainPumpState - * @details Outputs: drainPumpMeasuredRPM + * @details Inputs: drainPumpMeasuredRPM, drainPumpMeasuredCurrentA, + * drainPumpMeasuredDir + * @details Outputs: drainPumpMeasuredRPM, drainPumpMeasuredCurrentA, + * drainPumpMeasuredDir * @return none *************************************************************************/ void execDrainPumpMonitor( void ) { - U16 fpgaADCSpeedCount = getFPGADrainPumpSpeed(); - drainPumpMeasuredRPM.data = ( DRAIN_PUMP_OFF_RPM_ADC_COUNT == fpgaADCSpeedCount ? 0 : (U32)( CONVERSION_COEFF / (F32)fpgaADCSpeedCount ) ); + U16 fpgaADCSpeedCount = getFPGADrainPumpSpeed(); + U16 fpgaADCCurrentCount = getFPGADrainPumpCurrentFeedback(); + F32 currentA = getDrainPumpMeasuredCurrentA(); + drainPumpMeasuredRPM.data = ( DRAIN_PUMP_OFF_RPM_ADC_COUNT == fpgaADCSpeedCount ? 0 : (U32)( RPM_CONVERSION_COEFF / (F32)fpgaADCSpeedCount ) ); + drainPumpMeasuredCurrentA.data = ( (F32)fpgaADCCurrentCount * CURRENT_CONVERSION_COEFF ) - 1.0F; + drainPumpMeasuredDir.data = ( (U32)getFPGADrainPumpDirection() & 0x40 ) >> 7; #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_DRAIN_PUMP_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) #endif { - // Check if the pump is in off state and the RPM is greater than the minimum RPM - if ( DRAIN_PUMP_OFF_STATE == drainPumpState ) + switch( drainPumpState ) { - BOOL isRPMTooHigh = ( getDrainPumpMeasuredRPM() > MIN_DRAIN_PUMP_RPM ? TRUE : FALSE ); + case DRAIN_PUMP_OFF_STATE: + { + BOOL isOffCurrentOut = ( currentA > DRAIN_PUMP_MAX_CURRENT_WHEN_OFF_A ? TRUE : FALSE ); + BOOL isRPMTooHigh = ( getDrainPumpMeasuredRPM() > MIN_DRAIN_PUMP_RPM ? TRUE : FALSE ); - checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_RPM_OUT_OF_RANGE, FALSE, getDrainPumpMeasuredRPM(), MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); - checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_OFF_FAULT, isRPMTooHigh, getDrainPumpMeasuredRPM(), MIN_DRAIN_PUMP_RPM ); + checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_RPM_OUT_OF_RANGE, FALSE, getDrainPumpMeasuredRPM(), MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); + checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_OFF_FAULT, isRPMTooHigh, getDrainPumpMeasuredRPM(), MIN_DRAIN_PUMP_RPM ); - // If the off fault alarm has become active, trigger the safety shutdown - if ( TRUE == isAlarmActive( ALARM_ID_DRAIN_PUMP_OFF_FAULT ) ) + // If the off fault alarm has become active, trigger the safety shutdown + if ( TRUE == isAlarmActive( ALARM_ID_DRAIN_PUMP_OFF_FAULT ) ) + { + activateSafetyShutdown(); + } + +#ifndef _RELEASE_ + if ( ( getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) != SW_CONFIG_ENABLE_VALUE ) && ( getCurrentOperationMode() != DG_MODE_INIT ) ) +#endif + { + checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_CURRENT_OUT_OF_RANGE, isOffCurrentOut, currentA, DRAIN_PUMP_MAX_CURRENT_WHEN_OFF_A ); + checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, FALSE, getFPGADrainPumpDirection(), DRAIN_PUMP_FORWARD_DIR ); + } + } + break; + + // The RPM is only checked in open loop state that the pump is run at a fixed RPM. + case DRAIN_PUMP_OPEN_LOOP_STATE: { - activateSafetyShutdown(); + U32 direction = getDrainPumpMeasuredDirection(); + BOOL isDirInvalid = ( direction != DRAIN_PUMP_FORWARD_DIR ? TRUE : FALSE ); + U32 rpmDiff = abs( getDrainPumpTargetRPM() - getDrainPumpMeasuredRPM() ); + BOOL isRPMOutOfRange = ( rpmDiff > MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ? TRUE : FALSE ); + + checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_RPM_OUT_OF_RANGE, isRPMOutOfRange, getDrainPumpMeasuredRPM(), MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); + checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_OFF_FAULT, FALSE, getDrainPumpMeasuredRPM(), MIN_DRAIN_PUMP_RPM ); + +#ifndef _RELEASE_ + if ( ( getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) != SW_CONFIG_ENABLE_VALUE ) && ( getCurrentOperationMode() != DG_MODE_INIT ) ) +#endif + { + checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, isDirInvalid, (F32)direction, DRAIN_PUMP_FORWARD_DIR ); + } } + break; + + case DRAIN_PUMP_CONTROL_TO_TARGET_STATE: + { + U32 direction = getDrainPumpMeasuredDirection(); + BOOL isDirInvalid = ( direction != DRAIN_PUMP_FORWARD_DIR ? TRUE : FALSE ); + +#ifndef _RELEASE_ + if ( ( getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) != SW_CONFIG_ENABLE_VALUE ) && ( getCurrentOperationMode() != DG_MODE_INIT ) ) +#endif + { + checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, isDirInvalid, (F32)direction, DRAIN_PUMP_FORWARD_DIR ); + } + } + break; + + default: + // There are not out of range conditions, clear the alarms + checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_RPM_OUT_OF_RANGE, FALSE, getDrainPumpMeasuredRPM(), MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); + checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_OFF_FAULT, FALSE, getDrainPumpMeasuredRPM(), MIN_DRAIN_PUMP_RPM ); + checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, FALSE, getFPGADrainPumpDirection(), DRAIN_PUMP_FORWARD_DIR ); + break; } - // The RPM is only checked in open loop state that the pump is run at a fixed RPM. - else if ( DRAIN_PUMP_OPEN_LOOP_STATE == drainPumpState ) + +#ifndef _RELEASE_ + if ( ( getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) != SW_CONFIG_ENABLE_VALUE ) && ( getCurrentOperationMode() != DG_MODE_INIT ) ) +#endif { - // Using abs since the read RPM can be above or below the target - U32 rpmDiff = abs( getDrainPumpTargetRPM() - getDrainPumpMeasuredRPM() ); - BOOL isRPMOutOfRange = ( rpmDiff > MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ? TRUE : FALSE ); + // Check the persistent alarm for the maximum drain pump current + BOOL isCurrentOutOfRange = ( currentA > DRAIN_PUMP_MAX_CURRENT_A ? TRUE : FALSE ); - checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_RPM_OUT_OF_RANGE, isRPMOutOfRange, getDrainPumpMeasuredRPM(), MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); - checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_OFF_FAULT, FALSE, getDrainPumpMeasuredRPM(), MIN_DRAIN_PUMP_RPM ); + checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_CURRENT_OUT_OF_RANGE, isCurrentOutOfRange, currentA, DRAIN_PUMP_MAX_CURRENT_A ); } - else - { - // There are not out of range conditions, clear the alarms - checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_RPM_OUT_OF_RANGE, FALSE, getDrainPumpMeasuredRPM(), MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); - checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_OFF_FAULT, FALSE, getDrainPumpMeasuredRPM(), MIN_DRAIN_PUMP_RPM ); - } } // Publish drain pump data on interval @@ -485,13 +561,8 @@ *************************************************************************/ U32 getDrainPumpMeasuredRPM( void ) { - U32 rpm = drainPumpMeasuredRPM.data; + U32 rpm = getU32OverrideValue( &drainPumpMeasuredRPM ); - if ( OVERRIDE_KEY == drainPumpMeasuredRPM.override ) - { - rpm = drainPumpMeasuredRPM.ovData; - } - return rpm; } @@ -649,7 +720,7 @@ * The publishDrainPumpData function publishes drain pump data at the set * interval. * @details Inputs: drainPumpDataPublicationTimerCounter - * @details Outputs: drainPumpDataPublicationTimerCounter + * @details Outputs: none * @return none *************************************************************************/ static void publishDrainPumpData( void ) @@ -660,19 +731,51 @@ DRAIN_PUMP_DATA_T drainPumpData; // Populate the data structure for publication - drainPumpData.rpmSetPoint = getDrainPumpTargetRPM(); - drainPumpData.pumpDACSet = drainPumpDACSet; - drainPumpData.drainPumpState = (U32)drainPumpState; - drainPumpData.drainPumpRPM = getDrainPumpMeasuredRPM(); - drainPumpData.trgtOutletPrsr = targetDrainPumpOutletPressure; + drainPumpData.rpmSetPoint = getDrainPumpTargetRPM(); + drainPumpData.pumpDACSet = drainPumpDACSet; + drainPumpData.drainPumpState = (U32)drainPumpState; + drainPumpData.drainPumpRPM = getDrainPumpMeasuredRPM(); + drainPumpData.trgtOutletPrsr = targetDrainPumpOutletPressure; + drainPumpData.drainPumpCurrentA = getDrainPumpMeasuredCurrentA(); + drainPumpData.drainPumpDirection = getDrainPumpMeasuredDirection(); broadcastData( MSG_ID_DRAIN_PUMP_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&drainPumpData, sizeof( DRAIN_PUMP_DATA_T ) ); drainPumpDataPublicationTimerCounter = 0; } } +/*********************************************************************//** + * @brief + * The getDrainPumpMeasuredCurrentA function returns the drain pump current + * feedback. + * @details Inputs: drainPumpMeasuredCurrent + * @details Outputs: none + * @return drain pump current feedback + *************************************************************************/ +static F32 getDrainPumpMeasuredCurrentA( void ) +{ + F32 current = getF32OverrideValue( &drainPumpMeasuredCurrentA ); + return current; +} + +/*********************************************************************//** + * @brief + * The getDrainPumpMeasuredDirection function returns the drain pump current + * direction. + * @details Inputs: drainPumpMeasuredDir + * @details Outputs: none + * @return drain pump current direction + *************************************************************************/ +static U32 getDrainPumpMeasuredDirection( void ) +{ + U32 direction = getU32OverrideValue( &drainPumpMeasuredDir ); + + return direction; +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Controllers/DrainPump.h =================================================================== diff -u -ra9315539f527b92523b1598ff91e47db4d71dae2 -r19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c --- firmware/App/Controllers/DrainPump.h (.../DrainPump.h) (revision a9315539f527b92523b1598ff91e47db4d71dae2) +++ firmware/App/Controllers/DrainPump.h (.../DrainPump.h) (revision 19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c) @@ -39,11 +39,13 @@ /// Drain pump data publish typedef struct { - U32 rpmSetPoint; ///< Drain pump speed set point (for open loop) - U32 pumpDACSet; ///< Drain pump DAC set value - U32 drainPumpState; ///< Drain pump state machine state - U32 drainPumpRPM; ///< Drain pump current RPM - F32 trgtOutletPrsr; ///< Drain pump target outlet pressure + U32 rpmSetPoint; ///< Drain pump speed set point (for open loop). + U32 pumpDACSet; ///< Drain pump DAC set value. + U32 drainPumpState; ///< Drain pump state machine state. + U32 drainPumpRPM; ///< Drain pump current RPM. + F32 trgtOutletPrsr; ///< Drain pump target outlet pressure. + F32 drainPumpCurrentA; ///< Drain pump current in amps. + U32 drainPumpDirection; ///< Drain pump direction. } DRAIN_PUMP_DATA_T; // ********** public function prototypes ********** Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -rd8dbfa71fd70064ffe00d09ffa270f477c8f7af2 -r19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision d8dbfa71fd70064ffe00d09ffa270f477c8f7af2) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c) @@ -49,7 +49,7 @@ #define HEATERS_MAX_DUTY_CYCLE 1.00F ///< Heaters max duty cycle (100%). #define HEATERS_MIN_DUTY_CYCLE 0.00F ///< Heaters minimum duty cycle (0.00%). -#define HEATERS_MIN_HEAT_DISINFECT_DUTY_CYCLE 0.6F ///< Heaters minimum duty cycle during heat disinfect. +#define HEATERS_MIN_HEAT_DISINFECT_DUTY_CYCLE 0.6F // TODO remove ///< Heaters minimum duty cycle during heat disinfect. #define HEATERS_MIN_EST_GAIN 0.2F ///< Heaters minimum estimation gain. #define HEATERS_MAX_EST_GAIN 5.0F ///< Heaters maximum estimation gain. #define HEATERS_NEUTRAL_EST_GAIN 1.0F ///< Heaters neutral estimation gain. @@ -64,7 +64,7 @@ #define HEATERS_VOLTAGE_OUT_OF_RANGE_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Heaters voltage out of range time out in milliseconds. #define HEATERS_MAX_VOLTAGE_OUT_OF_RANGE_TOL 0.2F ///< Heaters max voltage out of range tolerance. #define TRIMMER_HEATER_MAX_POWER_W 66.5F ///< Trimmer heater maximum power in Watts. -#define TRIMMER_HEATER_CONTROL_CHECK_INTERVAL_COUNT ( ( 30 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Trimmer heater control interval count. +#define HEATER_CONTROL_CHECK_INTERVAL_COUNT ( ( 30 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Heater control interval count. #define DELTA_TEMPERATURE_TIME_COSNTANT_C 8.6F ///< Delta temperature calculated from time constant. #define PRIMARY_HEATER_DUTY_CYCLE_PER_TEMPERATURE_C 0.015F ///< Primary heaters duty cycle per temperature in C. @@ -96,7 +96,7 @@ static HEATER_STATUS_T heatersStatus[ NUM_OF_DG_HEATERS ]; ///< Heaters status. static U32 dataPublicationTimerCounter; ///< Data publication timer counter. -static U32 trimmerHeaterControlCounter; ///< Trimmer heater control counter. +static U32 heaterControlCounter; ///< Heater control counter. static OVERRIDE_U32_T heatersDataPublishInterval = { HEATERS_DATA_PUBLISH_INTERVAL, HEATERS_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Heaters data publish time interval. // ********** private function prototypes ********** @@ -132,7 +132,7 @@ { DG_HEATERS_T heater; dataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; - trimmerHeaterControlCounter = 0; + heaterControlCounter = 0; for ( heater = DG_PRIMARY_HEATER; heater < NUM_OF_DG_HEATERS; heater++ ) { @@ -327,9 +327,9 @@ if ( TRUE == heatersStatus[ heater ].isHeaterOn ) { ALARM_ID_T alarm; - F32 measFlow; - F32 minFlow; - BOOL isFlowLow; + F32 measFlow = 0.0F; + F32 minFlow = 0.0F; + BOOL isFlowLow = FALSE; if ( DG_PRIMARY_HEATER == heater ) { @@ -496,8 +496,9 @@ // Do nothing the mode that DG is in right now, does not need heaters to be on } - // Update the calculated target temperature + // Update the calculated target temperature and flow heatersStatus[ DG_PRIMARY_HEATER ].calculatedTemperature = targetTemperature; + heatersStatus[ DG_PRIMARY_HEATER ].targetFlow = targetFlow; setHeaterDutyCycle( heater, dutyCycle ); return state; @@ -539,28 +540,23 @@ HEATERS_STATE_T state = HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET; F32 heatDisinfectSensorTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); - // Check if the heaters control conditions have changed, if yes, switch back to ramp to target - if ( TRUE == haveHeaterControlConditionsChanged( heater ) ) + if ( ++heaterControlCounter > HEATER_CONTROL_CHECK_INTERVAL_COUNT ) { - state = HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET; - } + F32 tempDutyCycle = 0.0F; + F32 targetTemperature = heatersStatus[ DG_TRIMMER_HEATER ].targetTemp; + F32 targetFlowLPM = heatersStatus[ DG_TRIMMER_HEATER ].targetFlow; + F32 dutyCycle = calculateTrimmerHeaterDutyCycle( targetTemperature, heatDisinfectSensorTemp, targetFlowLPM, FALSE ); + heaterControlCounter = 0; + // Trimmer heater duty cycle function checks the minimum to -100%. So if the duty cycle was calculated to be negative it is set to 0 here + tempDutyCycle = MAX( dutyCycle, HEATERS_MIN_DUTY_CYCLE ); - // If the heat disinfect sensor indicates that the temperature is below target temperature but the target temperature had been reached - // before turn on the heaters with 100% power - if ( ( heatDisinfectSensorTemp <= heatersStatus[ heater ].targetTemp ) && ( TRUE == heatersStatus[ heater ].hasTargetBeenReached ) ) - { - heatersStatus[ heater ].hasTargetBeenReached = FALSE; - setHeaterDutyCycle( heater, HEATERS_MAX_DUTY_CYCLE ); - } + setHeaterDutyCycle( DG_TRIMMER_HEATER, tempDutyCycle ); - // If we have reached to target temperature, turn off the heaters - if ( heatDisinfectSensorTemp > heatersStatus[ heater ].targetTemp ) - { - // Set the flag to true for the next run - heatersStatus[ heater ].hasTargetBeenReached = TRUE; - // The primary heater are not turned off but it is set to a minimum duty cycle so the temperature is kept - // above the target - setHeaterDutyCycle( heater, HEATERS_MIN_HEAT_DISINFECT_DUTY_CYCLE ); + targetTemperature = heatersStatus[ DG_PRIMARY_HEATER ].targetTemp; + targetFlowLPM = heatersStatus[ DG_PRIMARY_HEATER ].targetFlow; + dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, heatDisinfectSensorTemp, targetFlowLPM, FALSE ); + + setHeaterDutyCycle( DG_PRIMARY_HEATER, dutyCycle ); } return state; @@ -578,9 +574,9 @@ { HEATERS_STATE_T state = HEATER_EXEC_STATE_TRIMMER_RAMP_TO_TARGET; DG_HEATERS_T heater = DG_TRIMMER_HEATER; - F32 currentTemperature = 0.0; + F32 currentTemperature = 0.0F; F32 targetFlowLPM = getTargetDialysateFlowLPM(); - F32 dutyCycle = 0.0; + F32 dutyCycle = 0.0F; F32 targetTemperature = heatersStatus[ heater ].targetTemp; DG_OP_MODE_T opMode = getCurrentOperationMode(); @@ -606,7 +602,7 @@ heatersStatus[ heater ].calculatedTemperature = currentTemperature; heatersStatus[ heater ].inactiveRsrvr = getInactiveReservoir(); heatersStatus[ heater ].targetFlow = targetFlowLPM; - trimmerHeaterControlCounter = 0; + heaterControlCounter = 0; // Cap the minimum duty cycle. So if it is calculated to negative, set it to 0 dutyCycle = MAX( dutyCycle, HEATERS_MIN_DUTY_CYCLE ); @@ -626,23 +622,23 @@ static HEATERS_STATE_T handleHeaterStateTrimmerControlToTarget( void ) { HEATERS_STATE_T state = HEATER_EXEC_STATE_TRIMMER_CONTROL_TO_TARGET; - F32 tempDutyCycle = 0.0; + F32 tempDutyCycle = 0.0F; // If the inactive reservoir has changed from the last run transition to ramp state to recalculate the // duty cycle for the next delivery if ( heatersStatus[ DG_TRIMMER_HEATER ].inactiveRsrvr != getInactiveReservoir() ) { state = HEATER_EXEC_STATE_TRIMMER_RAMP_TO_TARGET; } - else if ( ++trimmerHeaterControlCounter > TRIMMER_HEATER_CONTROL_CHECK_INTERVAL_COUNT ) + else if ( ++heaterControlCounter > HEATER_CONTROL_CHECK_INTERVAL_COUNT ) { // When the trimmer heater is on, its duty cycle is adjusted at the control interval. For this control check, // dialysate inlet temperature sensor is used rather than the theoretical calculations. F32 outletRedundantTemperature = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); F32 targetTemperature = heatersStatus[ DG_TRIMMER_HEATER ].targetTemp; F32 targetFlowLPM = heatersStatus[ DG_TRIMMER_HEATER ].targetFlow; F32 dutyCycle = calculateTrimmerHeaterDutyCycle( targetTemperature, outletRedundantTemperature, targetFlowLPM, TRUE ); - trimmerHeaterControlCounter = 0; + heaterControlCounter = 0; tempDutyCycle = heatersStatus[ DG_TRIMMER_HEATER ].dutyCycle + dutyCycle; tempDutyCycle = MIN( tempDutyCycle, HEATERS_MAX_DUTY_CYCLE ); Index: firmware/App/Controllers/Pressures.c =================================================================== diff -u -rd8dbfa71fd70064ffe00d09ffa270f477c8f7af2 -r19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c --- firmware/App/Controllers/Pressures.c (.../Pressures.c) (revision d8dbfa71fd70064ffe00d09ffa270f477c8f7af2) +++ firmware/App/Controllers/Pressures.c (.../Pressures.c) (revision 19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c) @@ -357,7 +357,6 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_PRESSURE_SENSOR_SELECTED, sensorId ); break; #endif - } } } Index: firmware/App/Services/FPGA.c =================================================================== diff -u -rd8dbfa71fd70064ffe00d09ffa270f477c8f7af2 -r19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision d8dbfa71fd70064ffe00d09ffa270f477c8f7af2) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c) @@ -2459,12 +2459,12 @@ /*********************************************************************//** * @brief - * The getFPGADrainPumpDirecion function returns the drain pump direction. + * The getFPGADrainPumpDirection function returns the drain pump direction. * @details Inputs: fpgaSensorReadings * @details Outputs: none * @return drain pump direction *************************************************************************/ -U08 getFPGADrainPumpDirecion( void ) +U08 getFPGADrainPumpDirection( void ) { return fpgaSensorReadings.fpgaDrainPumpDirection; } Index: firmware/App/Services/FPGA.h =================================================================== diff -u -rd8dbfa71fd70064ffe00d09ffa270f477c8f7af2 -r19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c --- firmware/App/Services/FPGA.h (.../FPGA.h) (revision d8dbfa71fd70064ffe00d09ffa270f477c8f7af2) +++ firmware/App/Services/FPGA.h (.../FPGA.h) (revision 19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c) @@ -175,7 +175,7 @@ U16 getFPGADrainPumpCurrentFeedback( void ); U16 getFPGADrainPumpSpeedFeedback( void ); -U08 getFPGADrainPumpDirecion( void ); +U08 getFPGADrainPumpDirection( void ); /**@}*/ Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r5e88efbadfacd95cbf2c3620a9520fe4f9b6fd46 -r19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 5e88efbadfacd95cbf2c3620a9520fe4f9b6fd46) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 19ed5eac0b3a24d9bf9da52767dcc5fe2872bd7c) @@ -1146,8 +1146,11 @@ cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_PARAMETER; } } - else + else if ( ( getCurrentOperationMode() != DG_MODE_HEAT ) && ( getCurrentOperationMode() != DG_MODE_CHEM ) ) { + // The trimmer heater is controlled by HD except when DG is running heat disinfect or chemical disinfect. + // If the trimmer heater is run by DG in the cleaning modes but HD is expecting the heater to be off, it will + // keep sending the stop command all the time. stopHeater( DG_TRIMMER_HEATER ); }