Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r4b661aa14eff362b3ebb154e7791fcaa87d68368 -r0931b50383943421f0c0b85dcda738bb8b006a16 --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 4b661aa14eff362b3ebb154e7791fcaa87d68368) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 0931b50383943421f0c0b85dcda738bb8b006a16) @@ -29,7 +29,8 @@ #include "PersistentAlarm.h" #include "PIControllers.h" #include "SafetyShutdown.h" -#include "SystemCommMessages.h" +#include "SystemCommMessages.h" +#include "SystemComm.h" #include "TaskGeneral.h" #include "TaskPriority.h" #include "Timers.h" @@ -82,6 +83,8 @@ static const U32 DIP_DIRECTION_ERROR_PERSIST = (250 / TASK_PRIORITY_INTERVAL); /// Persist time (task intervals) dialysate flow rate out of range error condition. static const U32 DIP_MAX_FLOW_RATE_OUT_OF_RANGE_PERSIST = ((1 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +/// Time threshold to trigger an alarm if Dialysate flow data has not arrived within 3 seconds +static const U32 DIP_DIALYSATE_FLOW_DATA_ALARM_THRESHOLD = ((3 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); #define DIP_MAX_CURR_WHEN_STOPPED_MA 150.0 ///< Motor controller current should not exceed this when pump should be stopped. #define DIP_MAX_CURR_WHEN_RUNNING_MA 2000.0 ///< Motor controller current should not exceed this when pump should be running. @@ -152,7 +155,8 @@ static PUMP_CONTROL_MODE_T dialInPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP;///< Currently set dialIn pump control mode. /// Interval (in ms) at which to publish dialIn flow data to CAN bus -static OVERRIDE_U32_T dialInFlowDataPublishInterval = { DIAL_IN_FLOW_DATA_PUB_INTERVAL, DIAL_IN_FLOW_DATA_PUB_INTERVAL, DIAL_IN_FLOW_DATA_PUB_INTERVAL, 0 }; +static OVERRIDE_U32_T dialInFlowDataPublishInterval = { DIAL_IN_FLOW_DATA_PUB_INTERVAL, DIAL_IN_FLOW_DATA_PUB_INTERVAL, DIAL_IN_FLOW_DATA_PUB_INTERVAL, 0 }; +static U32 dialysateFlowDataFreshStatusCounter = 0; ///< Counter use to trigger alarm if no fresh dialysate flow data is received static S32 targetDialInFlowRate = 0; ///< Requested dialIn flow rate static OVERRIDE_F32_T measuredDialInFlowRate = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet flow rate static OVERRIDE_F32_T dialInPumpRotorSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet pump rotor speed @@ -178,9 +182,9 @@ static U32 errorDialInRotorSpeedPersistTimerCtr = 0; ///< Persistence timer counter for rotor speed error condition. static U32 errorDialInPumpDirectionPersistTimerCtr = 0; ///< Persistence timer counter for pump direction error condition. -static F32 flowReadings[ SIZE_OF_ROLLING_AVG ]; ///< Holds flow samples for a rolling average. +static F64 flowReadings[ SIZE_OF_ROLLING_AVG ]; ///< Holds flow samples for a rolling average. static U32 flowReadingsIdx = 0; ///< Index for next sample in rolling average array. -static F32 flowReadingsTotal = 0.0; ///< Rolling total - used to calc average. +static F64 flowReadingsTotal = 0.0; ///< Rolling total - used to calc average. static U32 flowReadingsCount = 0; ///< Number of samples in flow rolling average buffer. static U32 dipCurrErrorDurationCtr = 0; ///< Used for tracking persistence of dip current errors. @@ -196,7 +200,8 @@ static void releaseDialInPumpStop( void ); static void setDialInPumpDirection( MOTOR_DIR_T dir ); static void publishDialInFlowData( void ); -static void resetDialInFlowMovingAverage( void ); +static void resetDialInFlowMovingAverage( void ); +static void filterDialInFlowReadings( F64 flow ); static void updateDialInPumpSpeedAndDirectionFromHallSensors( void ); static void checkDialInPumpRotor( void ); static void checkDialInPumpDirection( void ); @@ -401,10 +406,31 @@ U08 spReadCtr = getFPGADialysateFlowSlowPacketReadCounter(); U08 flowErrorCtr = getFPGADialysateFlowErrorCounter(); U08 flowStatus = getFPGADialysateFlowMeterStatus(); - + F64 dipFlow; + + // Process new dialysate flow readings + if ( TRUE == getDialysateFlowDataFreshFlag() ) + { + dipFlow = getDGDialysateFlowRateLMin() * (F64)ML_PER_LITER; // convert rate to mL/min + filterDialInFlowReadings( dipFlow ); // process the fresh dialysate flow data + dialysateFlowDataFreshStatusCounter = 0; // reset counter + } + else + { // Alarm if not receiving new dialysate flow readings in timely manner + if ( ++dialysateFlowDataFreshStatusCounter > DIP_DIALYSATE_FLOW_DATA_ALARM_THRESHOLD ) + { + filterDialInFlowReadings( 0.0 ); + if ( TRUE == isDGCommunicating() ) + { + activateAlarmNoData( ALARM_ID_HD_DIALYSATE_FLOW_DATA_NOT_RECEIVE ); + } + } + } + + // Get latest pump speed and current from motor controller adcDialInPumpMCSpeedRPM.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipRPM)) * DIP_SPEED_ADC_TO_RPM_FACTOR; adcDialInPumpMCCurrentmA.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipmA)) * DIP_CURRENT_ADC_TO_MA_FACTOR; - + // Calculate dialysate inlet pump motor speed/direction from hall sensor count updateDialInPumpSpeedAndDirectionFromHallSensors(); @@ -854,7 +880,7 @@ * @details Outputs: flowReadings[], flowReadingsIdx, flowReadingsCount, flowReadingsTotal * @return none *************************************************************************/ -void filterDialInFlowReadings( F32 flow ) +void filterDialInFlowReadings( F64 flow ) { if ( flowReadingsCount >= SIZE_OF_ROLLING_AVG ) { @@ -864,7 +890,7 @@ flowReadingsTotal += flow; flowReadingsIdx = INC_WRAP( flowReadingsIdx, 0, SIZE_OF_ROLLING_AVG - 1 ); flowReadingsCount = INC_CAP( flowReadingsCount, SIZE_OF_ROLLING_AVG ); - measuredDialInFlowRate.data = flowReadingsTotal / (F32)flowReadingsCount; + measuredDialInFlowRate.data = (F32)( flowReadingsTotal / (F64)flowReadingsCount ); } /*********************************************************************//**