Index: firmware/App/Controllers/ConductivitySensors.c =================================================================== diff -u -ra12e1212c1cf49011ed8d65beaf9416ca18ffe98 -rac029c36127b916d68c0039a470c3e4c68879adf --- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision a12e1212c1cf49011ed8d65beaf9416ca18ffe98) +++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision ac029c36127b916d68c0039a470c3e4c68879adf) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2020-2023 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file ConductivitySensors.c * * @author (last) Dara Navaei -* @date (last) 20-May-2023 +* @date (last) 05-Mar-2024 * * @author (original) Quang Nguyen * @date (original) 13-Jul-2020 @@ -44,7 +44,6 @@ #define COND_CPO_SENSOR_PROBE_TYPE 10 ///< 0.1 K cell constant conductivity probe. #define COND_SENSOR_DECIMAL_CONVERSION 100.0F ///< Conductivity value from FPGA has two decimal place. -#define COND_SENSOR_TEMPERATURE_COEF 0.02F ///< Linear temperature coefficient of variation at 25 Celcius for fresh water. #define COND_SENSOR_REFERENCE_TEMPERATURE 25.0F ///< Reference temperature for conductivity sensor. #define COND_SENSOR_REPORT_PERIOD ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Broadcast conductivity values message every second. @@ -145,11 +144,12 @@ static EMSTAT_READ_T emstatBoardRead[ NUM_OF_EMSTAT_BOARDS ]; ///< EMSTAT board read. static COND_SENSOR_STATUS_T condSensorStatus[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Conductivity sensors status. static DG_COND_SENSORS_CAL_RECORD_T condSensorsCalRecord; ///< Conductivity sensors' calibration record. +static DG_COND_SENSORS_TEMP_COMP_CAL_RECORD_T condSensorsTempCompCalRecord; ///< Conductivity sensors' temperature compensation calibration record. static CAL_DATA_DG_COND_SENSORS_T condSensorCalTable[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Conductivity sensors calibration table. // ********** private function prototypes ********** -static F32 calcCompensatedConductivity( F32 conductivity, F32 temperature ); +static F32 calcCompensatedConductivity( U32 sensorID, F32 conductivity, F32 temperature ); static void calcRORejectionRatio( void ); static void processCPiCPoSensorRead( U32 sensorId, U08 emstatBoardSensorIndex, U32 fgpaRead, U08 fpgaReadCount, U08 fpgaErrorCount, U08 fpgaSensorFault ); @@ -235,8 +235,8 @@ initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CONDUCTIVITY_SENSOR_ERROR, MAX_CONDUCTIVITY_SENSOR_FAILURES, MAX_CONDUCTIVITY_SENSOR_FAILURE_WINDOW_MS ); initPersistentAlarm( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_CLEAR_MS, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_TIMEOUT_MS ); initPersistentAlarm( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_CLEAR_MS, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_TIMEOUT_MS ); - initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_TIMEOUT_MS ); - initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH, 0, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW, 0, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_TIMEOUT_MS ); // Initialize the conductivity sensors' FPGA alarms initFPGAPersistentAlarm( FPGA_PERS_ERROR_CPI_CPO_COND_SENSORS, ALARM_ID_DG_CPI_CPO_SENSORS_FPGA_FAULT, COND_SENSORS_FPGA_ERROR_TIMEOUT_MS, COND_SENSORS_FPGA_ERROR_TIMEOUT_MS ); @@ -259,6 +259,9 @@ { getNVRecord2Driver( GET_CAL_CONDUCTIVITY_SENSORS, (U08*)&condSensorsCalRecord, sizeof( condSensorsCalRecord ), NUM_OF_CAL_DATA_COND_SENSORS, ALARM_ID_DG_COND_SENSORS_INVALID_CAL_RECORD ); + + getNVRecord2Driver( GET_CAL_CONDUCTIVITY_SENSORS_TEMP_COMP, (U08*)&condSensorsTempCompCalRecord, sizeof( DG_COND_SENSORS_TEMP_COMP_CAL_RECORD_T ), + NUM_OF_CAL_DATA_COND_SENSORS_TEMP_COMP, ALARM_ID_DG_COND_SENSORS_INVALID_TEMP_COMP_CAL_RECORD ); } #ifndef _RELEASE_ @@ -307,10 +310,16 @@ *************************************************************************/ SELF_TEST_STATUS_T execConductivitySensorsSelfTest( void ) { - BOOL calStatus = getNVRecord2Driver( GET_CAL_CONDUCTIVITY_SENSORS, (U08*)&condSensorsCalRecord, sizeof( condSensorsCalRecord ), - NUM_OF_CAL_DATA_COND_SENSORS, ALARM_ID_DG_COND_SENSORS_INVALID_CAL_RECORD ); - SELF_TEST_STATUS_T result = ( TRUE == calStatus ? SELF_TEST_STATUS_PASSED : SELF_TEST_STATUS_FAILED ); + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; + BOOL calStatus = FALSE; + calStatus |= getNVRecord2Driver( GET_CAL_CONDUCTIVITY_SENSORS, (U08*)&condSensorsCalRecord, sizeof( DG_COND_SENSORS_CAL_RECORD_T ), + NUM_OF_CAL_DATA_COND_SENSORS, ALARM_ID_DG_COND_SENSORS_INVALID_CAL_RECORD ); + calStatus |= getNVRecord2Driver( GET_CAL_CONDUCTIVITY_SENSORS_TEMP_COMP, (U08*)&condSensorsTempCompCalRecord, sizeof( DG_COND_SENSORS_TEMP_COMP_CAL_RECORD_T ), + NUM_OF_CAL_DATA_COND_SENSORS_TEMP_COMP, ALARM_ID_DG_COND_SENSORS_INVALID_TEMP_COMP_CAL_RECORD ); + + result = ( TRUE == calStatus ? SELF_TEST_STATUS_PASSED : SELF_TEST_STATUS_FAILED ); + return result; } @@ -326,76 +335,85 @@ *************************************************************************/ void checkInletWaterConductivity( void ) { + F32 conductivity = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); + + if ( VALVE_STATE_OPEN == getValveStateName( VPI ) ) + { #ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_WATER_QUALITY_CHECK ) != SW_CONFIG_ENABLE_VALUE ) + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_WATER_QUALITY_CHECK ) != SW_CONFIG_ENABLE_VALUE ) #endif - { - DG_OP_MODE_T opMode = getCurrentOperationMode(); - F32 conductivity = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); - BOOL isConductTooLow = FALSE; - BOOL isConductTooHigh = FALSE; - - if ( FALSE == isROOnlyModeEnabled() ) { - isConductTooLow = ( conductivity < MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? TRUE : FALSE ); - isConductTooHigh = ( conductivity > MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? TRUE : FALSE ); - } - else - { - isConductTooLow = FALSE; - isConductTooHigh = ( conductivity > MAX_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM ? TRUE : FALSE ); - } + DG_OP_MODE_T opMode = getCurrentOperationMode(); + BOOL isConductTooLow = FALSE; + BOOL isConductTooHigh = FALSE; - switch( opMode ) - { - case DG_MODE_GENE: - case DG_MODE_FILL: - case DG_MODE_DRAI: - case DG_MODE_STAN: - if ( TRUE == isAlarmActive( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE ) ) - { - isConductTooLow = ( conductivity >= MIN_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? FALSE : TRUE ); - } + if ( FALSE == isROOnlyModeEnabled() ) + { + isConductTooLow = ( conductivity < MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? TRUE : FALSE ); + isConductTooHigh = ( conductivity > MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? TRUE : FALSE ); + } + else + { + isConductTooLow = FALSE; + isConductTooHigh = ( conductivity > MAX_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM ? TRUE : FALSE ); + } - // Per PRS 403 - checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, isConductTooLow, conductivity, MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ); - - if ( TRUE == isAlarmActive( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE ) ) - { - if ( FALSE == isROOnlyModeEnabled() ) + switch( opMode ) + { + case DG_MODE_GENE: + case DG_MODE_FILL: + case DG_MODE_DRAI: + case DG_MODE_STAN: + if ( TRUE == isAlarmActive( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE ) ) { - isConductTooHigh = ( conductivity <= MIN_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? FALSE : TRUE ); + isConductTooLow = ( conductivity >= MIN_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? FALSE : TRUE ); } - else + + // Per PRS 403 + checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, isConductTooLow, conductivity, MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ); + + if ( TRUE == isAlarmActive( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE ) ) { - isConductTooHigh = ( conductivity <= MIN_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM ? FALSE : TRUE ); + if ( FALSE == isROOnlyModeEnabled() ) + { + isConductTooHigh = ( conductivity <= MIN_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? FALSE : TRUE ); + } + else + { + isConductTooHigh = ( conductivity <= MIN_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM ? FALSE : TRUE ); + } } - } - // Per PRS 404 - checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE, isConductTooHigh, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ); - break; + // Per PRS 404 + checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE, isConductTooHigh, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ); + break; - case DG_MODE_FLUS: - case DG_MODE_HEAT: - case DG_MODE_HCOL: - case DG_MODE_CHEM: - case DG_MODE_CHFL: - case DG_MODE_ROPS: - if ( VALVE_STATE_OPEN == getValveStateName( VPI ) ) - { + case DG_MODE_FLUS: + case DG_MODE_HEAT: + case DG_MODE_HCOL: + case DG_MODE_CHEM: + case DG_MODE_CHFL: + case DG_MODE_ROPS: // Per PRS 403 checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH, isConductTooHigh, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ); // Per PRS 404 checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW, isConductTooLow, conductivity, MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ); - } - break; + break; - default: - // NOTE: Do nothing for the rest of the modes - break; + default: + // NOTE: Do nothing for the rest of the modes + break; + } } } + else + { + // VPI is closed - clear all alarms + checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, FALSE, conductivity, MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ); + checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE, FALSE, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ); + checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH, FALSE, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ); + checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW, FALSE, conductivity, MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ); + } } /*********************************************************************//** @@ -463,14 +481,19 @@ * reference temperature of 25 degree Celsius. * @details Inputs: conductivity, temperature * @details Outputs: none + * @param sensorID the ID of the conductivity sensor * @param conductivity conductivity value * @param temperature temperature to compensate conductivity with * @return compensated conductivity based on temperature *************************************************************************/ -static F32 calcCompensatedConductivity( F32 conductivity, F32 temperature ) +static F32 calcCompensatedConductivity( U32 sensorID, F32 conductivity, F32 temperature ) { - // EC = EC_25 * (1 + temp_coef * ( temperature - 25 )) - F32 compensatedCoef = ( 1.0F + ( COND_SENSOR_TEMPERATURE_COEF * ( temperature - COND_SENSOR_REFERENCE_TEMPERATURE ) ) ); + F32 gain = condSensorsTempCompCalRecord.condSensorsTempComp[ (CAL_DATA_DG_COND_SENSORS_TEMP_COMP_T)sensorID ].gain; + F32 coeff = condSensorsTempCompCalRecord.condSensorsTempComp[ (CAL_DATA_DG_COND_SENSORS_TEMP_COMP_T)sensorID ].coefficient; + F32 offset = condSensorsTempCompCalRecord.condSensorsTempComp[ (CAL_DATA_DG_COND_SENSORS_TEMP_COMP_T)sensorID ].offset; + F32 compensation = ( gain * coeff ) + offset; + // EC = EC_25 * (1 + compensation * ( temperature - 25 )) + F32 compensatedCoef = ( 1.0F + ( compensation * ( temperature - COND_SENSOR_REFERENCE_TEMPERATURE ) ) ); return conductivity / compensatedCoef; } @@ -521,7 +544,7 @@ // EMSTAT sensors will be the permanent sensors from DVT onward. F32 temperature = getTemperatureValue( emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ emstatBoardSensorIndex ].condSnsrTempSnsr ); F32 conductivity = ( (F32)( fgpaRead ) / COND_SENSOR_DECIMAL_CONVERSION ); - F32 compensatedCond = calcCompensatedConductivity( conductivity, temperature ); + F32 compensatedCond = calcCompensatedConductivity( sensorId, conductivity, temperature ); condSensorStatus[ sensorId ].readCount = fpgaReadCount; condSensorStatus[ sensorId ].internalErrorCount = 0; @@ -706,7 +729,7 @@ F32 resistance = ( ( F32 )( condSensorStatus[ sensorId ].rawEmstatCondValue - EMSTAT_PICO_MEASUREMENT_OFFSET ) / prefix ); F32 temperature = getTemperatureValue( readPackage->sensors[ boardSensorIndex ].condSnsrTempSnsr ); F32 conductivity = ( 1.0F / resistance ) * SIEMENS_TO_MICROSIEMENS_CONVERSION; - F32 compensatedCond = calcCompensatedConductivity( conductivity, temperature ); + F32 compensatedCond = calcCompensatedConductivity( sensorId, conductivity, temperature ); condSensorStatus[ sensorId ].internalErrorCount = 0; condSensorStatus[ sensorId ].compensatedCondValue.data = getCalibrationAppliedConductivityValue( sensorId, compensatedCond );