Index: firmware/App/Controllers/ConcentratePumps.h =================================================================== diff -u -r94a190522ce398399c7b93c59f788d7666ec0060 -r7d293e18ea5ac0fce443c68525100e44df80b4fd --- firmware/App/Controllers/ConcentratePumps.h (.../ConcentratePumps.h) (revision 94a190522ce398399c7b93c59f788d7666ec0060) +++ firmware/App/Controllers/ConcentratePumps.h (.../ConcentratePumps.h) (revision 7d293e18ea5ac0fce443c68525100e44df80b4fd) @@ -31,23 +31,23 @@ // ********** public definitions ********** -#define CONCENTRATE_PUMP_MAX_SPEED 48.0 ///< Maximum speed for concentrate pump in mL per min. +#define CONCENTRATE_PUMP_MAX_SPEED 48.0 ///< Maximum speed for concentrate pump in mL/min /// Enumeration of concentrate pumps. typedef enum ConcentratePumps { - CONCENTRATEPUMPS_CP1_ACID = 0, ///< Acid concentrate pump - CONCENTRATEPUMPS_CP2_BICARB, ///< Bicarbonate concentrate pump - NUM_OF_CONCENTRATE_PUMPS ///< Number of concentrate pumps + CONCENTRATEPUMPS_CP1_ACID = 0, ///< Acid concentrate pump + CONCENTRATEPUMPS_CP2_BICARB, ///< Bicarbonate concentrate pump + NUM_OF_CONCENTRATE_PUMPS ///< Number of concentrate pumps } CONCENTRATE_PUMPS_T; /// Concentrate pump data struct. typedef struct { - F32 cp1CurrentSetSpeed; ///< Concentrate pump CP1 current set speed - F32 cp1MeasuredSpeed; ///< Concentrate pump CP1 measured speed - F32 cp2CurrentSetSpeed; ///< Concentrate pump CP2 current set speed - F32 cp2MeasuredSpeed; ///< Concentrate pump CP2 measured speed + F32 cp1CurrentSetSpeed; ///< Concentrate pump CP1 current set speed + F32 cp1MeasuredSpeed; ///< Concentrate pump CP1 measured speed + F32 cp2CurrentSetSpeed; ///< Concentrate pump CP2 current set speed + F32 cp2MeasuredSpeed; ///< Concentrate pump CP2 measured speed } CONCENTRATE_PUMP_DATA_T; // ********** public function prototypes ********** @@ -62,9 +62,9 @@ void requestConcentratePumpOff( CONCENTRATE_PUMPS_T pumpId ); void setConcentratePumpTargetSpeed( CONCENTRATE_PUMPS_T pumpId, F32 targetSpeed_ml_min ); -F32 getMeasuredPumpSpeed( CONCENTRATE_PUMPS_T pumpId ); +F32 getMeasuredPumpSpeed( CONCENTRATE_PUMPS_T pumpId ); -DG_ACID_CONCENTRATES_RECORD_T getAcidConcentrateCalRecord( void ); +DG_ACID_CONCENTRATES_RECORD_T getAcidConcentrateCalRecord( void ); DG_BICARB_CONCENTRATES_RECORD_T getBicarbConcentrateCalRecord( void ); BOOL testSetConcentratePumpDataPublishIntervalOverride( U32 value ); Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r3b5080777e3dac1b5802ee18227f66a0b49deefa -r7d293e18ea5ac0fce443c68525100e44df80b4fd --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 3b5080777e3dac1b5802ee18227f66a0b49deefa) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 7d293e18ea5ac0fce443c68525100e44df80b4fd) @@ -411,7 +411,6 @@ publishHeatersData(); } - /*********************************************************************//** * @brief * The resetHeatersEfficiency function resets the heaters efficiency upon Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r1aeab08c1baf6445514b81fe51fc60a3e536e782 -r7d293e18ea5ac0fce443c68525100e44df80b4fd --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 1aeab08c1baf6445514b81fe51fc60a3e536e782) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 7d293e18ea5ac0fce443c68525100e44df80b4fd) @@ -20,6 +20,7 @@ #include "etpwm.h" #include "mibspi.h" +#include "ConcentratePumps.h" #include "FPGA.h" #include "InternalADC.h" #include "NVDataMgmt.h" @@ -354,6 +355,8 @@ if ( ++flowFilterCounter >= FLOW_SAMPLES_TO_AVERAGE ) { F32 flow = RO_FLOW_ADC_TO_LPM_FACTOR / ( (F32)measuredFlowReadingsSum * FLOW_AVERAGE_MULTIPLIER ); + flow = flow - ( getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP1_ACID ) / 1000.0 ) - + ( getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP2_BICARB ) / 1000.0 ); measuredROFlowRateLPM.data = pow(flow, 4) * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].fourthOrderCoeff + pow(flow, 3) * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].thirdOrderCoeff + Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -r3b5080777e3dac1b5802ee18227f66a0b49deefa -r7d293e18ea5ac0fce443c68525100e44df80b4fd --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 3b5080777e3dac1b5802ee18227f66a0b49deefa) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 7d293e18ea5ac0fce443c68525100e44df80b4fd) @@ -43,7 +43,7 @@ // ********** private definitions ********** #define TARGET_RO_PRESSURE_PSI 130 ///< Target pressure for RO pump. -#define TARGET_RO_FLOW_RATE_L 0.8 ///< Target flow rate for RO pump. +#define TARGET_RO_FLOW_RATE_L 0.8 //TODO do we need to use this as default? ///< Target flow rate for RO pump. #define DIALYSATE_FILL_TIME_OUT ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time out period when reservoir is not filled with correct dialysate. #define EMPTY_BOTTLE_DETECT_PERSISTENT_PERIOD_MS ( 5 * MS_PER_SECOND ) ///< Persistent period for empty bottle detect. @@ -153,7 +153,7 @@ DG_RESERVOIR_ID_T inactiveReservoir = getInactiveReservoir(); initFillMode(); - reservoirBaseWeight = getReservoirWeight( inactiveReservoir ); + reservoirBaseWeight = getReservoirWeight( inactiveReservoir ); dialysateFillStartTime = getMSTimerCount(); // Set initial actuator states @@ -167,7 +167,7 @@ // because the initial guess in the heaters driver needs the target flow to calculate // the new PWMs for the main and small primary heaters #ifndef DISABLE_FLOW_CONTROL_TREATMENT - setROPumpTargetFlowRate( TARGET_RO_FLOW_RATE_L, TARGET_RO_PRESSURE_PSI ); + setROPumpTargetFlowRate( getTargetFillFlowRateLPM(), TARGET_RO_PRESSURE_PSI ); #endif startHeater( DG_PRIMARY_HEATER ); @@ -471,15 +471,18 @@ *************************************************************************/ static DG_FILL_MODE_STATE_T handleDeliverDialysateState( void ) { - F32 measuredROFlowRate_mL_min = getMeasuredROFlowRate() * ML_PER_LITER; - F32 acidConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); - F32 dialysateConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); - BOOL isAcidConductivityOutOfRange = ( acidConductivity <= MIN_ACID_CONCENTRATE_CONDUCTIVITY ) || ( acidConductivity >= MAX_ACID_CONCENTRATE_CONDUCTIVITY ); - BOOL isDialysateConductivityOutOfRange = ( dialysateConductivity <= MIN_DIALYSATE_CONDUCTIVITY ) || ( dialysateConductivity >= MAX_DIALYSATE_CONDUCTIVITY ); + F32 integratedVolume_mL; - DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_DELIVER_DIALYSATE; + F32 measuredROFlowRate_mL_min = getMeasuredROFlowRate() * ML_PER_LITER; + F32 acidConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); + F32 dialysateConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); + BOOL isAcidConductivityOutOfRange = ( acidConductivity <= MIN_ACID_CONCENTRATE_CONDUCTIVITY ) || + ( acidConductivity >= MAX_ACID_CONCENTRATE_CONDUCTIVITY ) ? TRUE : FALSE; + BOOL isDialysateConductivityOutOfRange = ( dialysateConductivity <= MIN_DIALYSATE_CONDUCTIVITY ) || + ( dialysateConductivity >= MAX_DIALYSATE_CONDUCTIVITY ) ? TRUE : FALSE; + + DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_DELIVER_DIALYSATE; DG_RESERVOIR_ID_T inactiveReservoir = getInactiveReservoir(); - F32 integratedVolume_mL; // Set concentrate pumps speed based off RO pump flow rate handleDialysateMixing( measuredROFlowRate_mL_min ); Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -r1aeab08c1baf6445514b81fe51fc60a3e536e782 -r7d293e18ea5ac0fce443c68525100e44df80b4fd --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 1aeab08c1baf6445514b81fe51fc60a3e536e782) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 7d293e18ea5ac0fce443c68525100e44df80b4fd) @@ -69,6 +69,7 @@ static U32 reservoirWeightUnchangeStartTime[ NUM_OF_DG_RESERVOIRS ] = { 0, 0 }; ///< The reservoirs' weight start time when weight stop decreasing. static BOOL tareLoadCellRequest; ///< Flag indicates if load cell tare has been requested by HD. static DG_RESERVOIR_VOLUME_RECORD_T reservoirsCalRecord; ///< DG reservoirs non-volatile record. +static F32 targetFillFlowRateLPM; // ********** private function prototypes ********** @@ -78,14 +79,16 @@ * @brief * The initReservoirs function initializes the Reservoirs module. * @details Inputs: none - * @details Outputs: Reservoirs module initialized + * @details Outputs: activeReservoir.data, fillVolumeTargetMl.data, + * drainVolumeTargetMl.data, targetFillFlowRateLPM * @return none *************************************************************************/ void initReservoirs( void ) { - activeReservoir.data = (U32)DG_RESERVOIR_1; - fillVolumeTargetMl.data = DEFAULT_FILL_VOLUME_ML; - drainVolumeTargetMl.data = DEFAULT_DRAIN_VOLUME_ML; + activeReservoir.data = (U32)DG_RESERVOIR_1; + fillVolumeTargetMl.data = DEFAULT_FILL_VOLUME_ML; + drainVolumeTargetMl.data = DEFAULT_DRAIN_VOLUME_ML; + targetFillFlowRateLPM = 0.0; } /*********************************************************************//** @@ -248,25 +251,26 @@ * The startFillCmd function handles a fill command from the HD. * @details Inputs: none * @details Outputs: move to fill mode - * @param fillToVolMl Target volume (in mL) to fill reservoir to + * @param fillToVolMl target volume (in mL) to fill reservoir to + * @param fillTargeteFlowLPM target fill flow rate in L/min * @return none *************************************************************************/ -void startFillCmd( U32 fillToVolMl ) +void startFillCmd( U32 fillToVolMl, F32 fillTargetLPM ) { DG_CMD_RESPONSE_T cmdResponse; - cmdResponse.commandID = DG_CMD_START_FILL; - cmdResponse.rejected = TRUE; + cmdResponse.commandID = DG_CMD_START_FILL; + cmdResponse.rejected = TRUE; cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; // fill command only valid in generation idle mode - if ( ( DG_MODE_GENE == getCurrentOperationMode() ) && - ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == getCurrentGenIdleState() ) ) + if ( ( DG_MODE_GENE == getCurrentOperationMode() ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == getCurrentGenIdleState() ) ) { // validate parameters if ( fillToVolMl < MAX_FILL_VOLUME_ML ) { fillVolumeTargetMl.data = fillToVolMl; + requestNewOperationMode( DG_MODE_FILL ); cmdResponse.rejected = FALSE; } @@ -280,6 +284,8 @@ cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE; } + targetFillFlowRateLPM = fillTargetLPM; + sendCommandResponseMsg( &cmdResponse ); } @@ -433,7 +439,7 @@ * @brief * The getReservoirWeight function returns the small filtered weight * of the reservoir's associated load cell. - * @details Inputs: associatedLoadCell[] + * @details Inputs: none * @details Outputs: none * @param reservoirId id of reservoir to get weight from * @return small filtered weight @@ -445,6 +451,19 @@ /*********************************************************************//** * @brief + * The getTargetFillFlowRateLPM function returns the target fill flow rate + * in L/min. + * @details Inputs: none + * @details Outputs: none + * @return target fill flow rate in L/min + *************************************************************************/ +F32 getTargetFillFlowRateLPM( void ) +{ + return targetFillFlowRateLPM; +} + +/*********************************************************************//** + * @brief * The getReservoirsCalRecord function returns the reservoirs' calibration * record. * @details Inputs: reservoirsCalRecord Index: firmware/App/Services/Reservoirs.h =================================================================== diff -u -r1aeab08c1baf6445514b81fe51fc60a3e536e782 -r7d293e18ea5ac0fce443c68525100e44df80b4fd --- firmware/App/Services/Reservoirs.h (.../Reservoirs.h) (revision 1aeab08c1baf6445514b81fe51fc60a3e536e782) +++ firmware/App/Services/Reservoirs.h (.../Reservoirs.h) (revision 7d293e18ea5ac0fce443c68525100e44df80b4fd) @@ -35,12 +35,12 @@ #define MAX_RESERVOIR_VOLUME_ML 2000 ///< Maximum reservoir volume in mL. #pragma pack(push,1) - /// Fill command data structure. typedef struct { U32 fillToVolumeMl; ///< Target volume to fill to (in mL) U32 cmd; ///< General command (start/stop) + F32 targetFlowLPM; ///< Target flow rate L/min } FILL_CMD_T; /// Drain command data structure. @@ -67,7 +67,6 @@ U32 fillToVolumeMl; ///< Volume target to fill to U32 drainToVolumeMl; ///< Volume target to drain to } RESERVOIR_DATA_T; - #pragma pack(pop) // ********** public function prototypes ********** @@ -79,7 +78,7 @@ void setActiveReservoirCmd( DG_RESERVOIR_ID_T resID ); // handle switch reservoirs command from HD void changeValveSettingCmd( DG_VALVE_SETTING_ID_T valveSettingID ); // handle valve setting change command from HD -void startFillCmd( U32 fillToVolMl ); // handle fill command from HD +void startFillCmd( U32 fillToVolMl, F32 fillTargetFlowLPM ); // handle fill command from HD void stopFillCmd( void ); // handle stop fill command from HD void startDrainCmd( DRAIN_CMD_T drainCmd ); // handle drain command from HD void stopDrainCmd( void ); // handle stop drain command from HD @@ -89,6 +88,7 @@ DG_RESERVOIR_ID_T getInactiveReservoir( void ); F32 getReservoirWeight( DG_RESERVOIR_ID_T reservoirId ); +F32 getTargetFillFlowRateLPM( void ); DG_RESERVOIR_VOLUME_RECORD_T getReservoirsCalRecord( void ); Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r1aeab08c1baf6445514b81fe51fc60a3e536e782 -r7d293e18ea5ac0fce443c68525100e44df80b4fd --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 1aeab08c1baf6445514b81fe51fc60a3e536e782) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 7d293e18ea5ac0fce443c68525100e44df80b4fd) @@ -1043,6 +1043,10 @@ handleDGServiceScheduleRequest( message ); break; + case MSG_ID_HD_REQUEST_DG_CONCENTRATE_MIXING_RATIOS: + handleDGSendConcentrateMixingRatios( message ); + break; + // NOTE: This case must be last case MSG_ID_DG_TESTER_LOGIN_REQUEST: handleTesterLogInRequest( message ); Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r6bb7cd715299d16c131ab074fac0e62d8022f235 -r7d293e18ea5ac0fce443c68525100e44df80b4fd --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 6bb7cd715299d16c131ab074fac0e62d8022f235) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 7d293e18ea5ac0fce443c68525100e44df80b4fd) @@ -523,6 +523,41 @@ /*********************************************************************//** * @brief + * The handleDGServiceScheduleRequest function handles a request for DG + * service information. + * @details Inputs: none + * @details Outputs: message handled, response constructed and queued for + * transmit. + * @return none + *************************************************************************/ +void handleDGSendConcentrateMixingRatios( MESSAGE_T *message ) +{ + MESSAGE_T msg; + + DG_ACID_CONCENTRATES_RECORD_T acid = getAcidConcentrateCalRecord(); + DG_BICARB_CONCENTRATES_RECORD_T bicarb = getBicarbConcentrateCalRecord(); + U32 fillPrepTimeMS = 9000; // TODO make a get for this in mode fill + + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_CONCENTRATE_MIXING_RATIOS_DATA; + msg.hdr.payloadLen = sizeof( F32 ) + sizeof( F32 ) + sizeof( U32 ); + + // Fill message payload + memcpy( payloadPtr, &acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidConcMixRatio, sizeof( F32 ) ); + payloadPtr += sizeof( F32 ); + memcpy( payloadPtr, &bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio, sizeof( F32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &fillPrepTimeMS, sizeof( U32 ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_2_HD, ACK_REQUIRED ); +} + +/*********************************************************************//** + * @brief * The sendDGCalibrationRecord function sends out the DG calibration * record. * @details Inputs: none @@ -841,7 +876,7 @@ if ( DG_CMD_START == fillCmd.cmd ) { - startFillCmd( fillCmd.fillToVolumeMl ); + startFillCmd( fillCmd.fillToVolumeMl, fillCmd.targetFlowLPM ); } else { Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r1aeab08c1baf6445514b81fe51fc60a3e536e782 -r7d293e18ea5ac0fce443c68525100e44df80b4fd --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 1aeab08c1baf6445514b81fe51fc60a3e536e782) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 7d293e18ea5ac0fce443c68525100e44df80b4fd) @@ -95,6 +95,9 @@ // MSG_ID_UI_REQUEST_SERVICE_INFO void handleDGServiceScheduleRequest( MESSAGE_T *message ); +// MSG_ID_HD_REQUEST_DG_CONCENTRATE_RATIOS +void handleDGSendConcentrateMixingRatios( MESSAGE_T *message ); + // MSG_ID_DG_SWITCH_RESERVOIR_CMD void handleSwitchReservoirCmd( MESSAGE_T *message );