Index: firmware/App/Controllers/ConductivitySensors.c =================================================================== diff -u -r83b12013a84403fe4d7d6f70b516d623bfb2fcfd -r30bf93016955d5eb5c4053645d5b2065f20be911 --- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 83b12013a84403fe4d7d6f70b516d623bfb2fcfd) +++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 30bf93016955d5eb5c4053645d5b2065f20be911) @@ -7,8 +7,8 @@ * * @file ConductivitySensors.c * -* @author (last) Dara Navaei -* @date (last) 02-Feb-2023 +* @author (last) Bill Bracken +* @date (last) 31-Mar-2023 * * @author (original) Quang Nguyen * @date (original) 13-Jul-2020 @@ -20,6 +20,7 @@ #include "FPGA.h" #include "NVDataMgmt.h" #include "MessageSupport.h" +#include "ModeFill.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "SystemCommMessages.h" @@ -52,8 +53,11 @@ #define MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM 200.0F ///< Maximum allowed low conductivity value in uS/cm. #define MIN_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM 220.0F ///< Minimum allowed low conductivity value in uS/cm. +#define MAX_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM 100.0F ///< Maximum RO only mode high conductivity value in uS/cm. +#define MIN_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM 90.0F ///< Minimum RO only mode high conductivity value in uS/cm. + #define MAX_ALLOWED_UNCHANGED_CONDUCTIVITY_READS ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< New reading every 800 ms, expect to get valid new reading in 1s. -#define MAX_CONDUCTIVITY_SENSOR_FAILURES 5 ///< maximum number of conductivity sensor errors within window period before alarm. +#define MAX_CONDUCTIVITY_SENSOR_FAILURES 2 ///< maximum number of conductivity sensor errors within window period before alarm. #define MAX_CONDUCTIVITY_SENSOR_FAILURE_WINDOW_MS ( 60 * MS_PER_SECOND ) ///< Conductivity sensor error window. #define COND_SENSOR_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for conductivity sensor out of range error. @@ -75,6 +79,7 @@ #define EMSTAT_CPO_OR_CD2_INDEX 1 ///< Emstat board CPo index number. #define EMSTAT_PACKAGE_BUFFER_SIZE 50 ///< EmStat package buffer size +#define EMSTAT_RX_FIFO_COUNT_MASK 0x7FFF ///< EmStat Rx fifo count mask #define DATA_PUBLISH_COUNTER_START_COUNT 40 ///< Data publish counter start count. #define COND_SENSOR_BAD_STATUS_PERSISTENCE_PERIOD ( 1 * MS_PER_SECOND ) ///< Conductivity sensor bad status persistence period. @@ -99,7 +104,6 @@ CONDUCTIVITY_SENSORS_T condSnsr; ///< Emstat conductivity sensor on the board. TEMPERATURE_SENSORS_T condSnsrTempSnsr; ///< Emstat conductivity sensor temperature sensor. ALARM_ID_T condSnsrHex2StrAlarm; ///< Emstat conductivity sensor hex to string alarm. - U32 invalidCharCounter; } EMSTAT_COND_SENSORS_T; /// Emstat board structure @@ -109,15 +113,14 @@ U08 packageIndex; ///< Emstat package index number. U08 package[ EMSTAT_PACKAGE_BUFFER_SIZE ]; ///< Emstat read buffer package. EMSTAT_COND_SENSORS_T sensors[ EMSTAT_NUM_OF_SENSORS_PER_BOARD ]; ///< Emstat conductivity and corresponding temperature sensors. - U08 packetIndex; - U08 packetData[100]; } EMSTAT_READ_T; /// Conductivity sensors structure typedef struct { U08 readCount; ///< Conductivity sensor FPGA read count (For V3). U32 internalErrorCount; ///< Conductivity sensor internal error count. + U32 badCharErrorCount; ///< Conductivity sensor bad char error count OVERRIDE_F32_T compensatedCondValue; ///< Conductivity sensor compensated value F32 rawCondValue; ///< Conductivity sensor raw value. U32 sensorStatus; ///< Conductivity sensor status. @@ -185,22 +188,17 @@ emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ EMSTAT_CPI_OR_CD1_INDEX ].condSnsr = CONDUCTIVITYSENSORS_CPI_SENSOR; emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ EMSTAT_CPI_OR_CD1_INDEX ].condSnsrTempSnsr = TEMPSENSORS_INLET_PRIMARY_HEATER; emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ EMSTAT_CPI_OR_CD1_INDEX ].condSnsrHex2StrAlarm = ALARM_ID_DG_CPI_COND_SENSOR_INVALID_CHAR; - emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ EMSTAT_CPI_OR_CD1_INDEX ].invalidCharCounter = 0; emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ EMSTAT_CPO_OR_CD2_INDEX ].condSnsr = CONDUCTIVITYSENSORS_CPO_SENSOR; emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ EMSTAT_CPO_OR_CD2_INDEX ].condSnsrTempSnsr = TEMPSENSORS_OUTLET_PRIMARY_HEATER; emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ EMSTAT_CPO_OR_CD2_INDEX ].condSnsrHex2StrAlarm = ALARM_ID_DG_CPO_COND_SENSOR_INVALID_CHAR; - emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ EMSTAT_CPO_OR_CD2_INDEX ].invalidCharCounter = 0; - // CD1/CD2 Emstat board conductivity sensors and their corresponding temperature sensors emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].sensors[ EMSTAT_CPI_OR_CD1_INDEX ].condSnsr = CONDUCTIVITYSENSORS_CD1_SENSOR; emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].sensors[ EMSTAT_CPI_OR_CD1_INDEX ].condSnsrTempSnsr = TEMPSENSORS_CONDUCTIVITY_SENSOR_1; emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].sensors[ EMSTAT_CPI_OR_CD1_INDEX ].condSnsrHex2StrAlarm = ALARM_ID_DG_CD1_COND_SENSOR_INVALID_CHAR; - emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].sensors[ EMSTAT_CPI_OR_CD1_INDEX ].invalidCharCounter = 0; emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].sensors[ EMSTAT_CPO_OR_CD2_INDEX ].condSnsr = CONDUCTIVITYSENSORS_CD2_SENSOR; emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].sensors[ EMSTAT_CPO_OR_CD2_INDEX ].condSnsrTempSnsr = TEMPSENSORS_CONDUCTIVITY_SENSOR_2; emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].sensors[ EMSTAT_CPO_OR_CD2_INDEX ].condSnsrHex2StrAlarm = ALARM_ID_DG_CD2_COND_SENSOR_INVALID_CHAR; - emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].sensors[ EMSTAT_CPO_OR_CD2_INDEX ].invalidCharCounter = 0; // For V3 conductivity sensors setFPGACPiProbeType( COND_CPI_SENSOR_PROBE_TYPE ); @@ -209,11 +207,6 @@ initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CONDUCTIVITY_SENSOR_ERROR, MAX_CONDUCTIVITY_SENSOR_FAILURES, MAX_CONDUCTIVITY_SENSOR_FAILURE_WINDOW_MS ); initPersistentAlarm( ALARM_ID_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_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_CONDUCTIVITY_SENSOR_BAD_STATUS, COND_SENSOR_BAD_STATUS_PERSISTENCE_PERIOD, COND_SENSOR_BAD_STATUS_PERSISTENCE_PERIOD ); - initPersistentAlarm( ALARM_ID_DG_CPI_COND_SENSOR_INVALID_CHAR, COND_SENSORS_BAD_CHAR_TIME_OUT_MS, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); - initPersistentAlarm( ALARM_ID_DG_CPO_COND_SENSOR_INVALID_CHAR, COND_SENSORS_BAD_CHAR_TIME_OUT_MS, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); - initPersistentAlarm( ALARM_ID_DG_CD1_COND_SENSOR_INVALID_CHAR, COND_SENSORS_BAD_CHAR_TIME_OUT_MS, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); - initPersistentAlarm( ALARM_ID_DG_CD2_COND_SENSOR_INVALID_CHAR, COND_SENSORS_BAD_CHAR_TIME_OUT_MS, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); @@ -311,9 +304,20 @@ { DG_OP_MODE_T opMode = getCurrentOperationMode(); F32 conductivity = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); - BOOL isConductTooLow = ( conductivity < MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? TRUE : FALSE ); - BOOL isConductTooHigh = ( conductivity > MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? TRUE : FALSE ); + 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 ); + } + switch( opMode ) { case DG_MODE_GENE: @@ -329,7 +333,14 @@ if ( TRUE == isAlarmActive( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE ) ) { - isConductTooHigh = ( conductivity <= MIN_COND_SENSOR_CPI_WARNING_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 @@ -340,6 +351,7 @@ case DG_MODE_STAN: case DG_MODE_FLUS: case DG_MODE_HEAT: + case DG_MODE_HCOL: case DG_MODE_CHEM: case DG_MODE_CHFL: if ( VALVE_STATE_OPEN == getValveStateName( VPI ) ) @@ -527,25 +539,12 @@ { U08 emstatByte = 0; U16 rxFifoCount = 0; - static U32 maxRxFifoCount = 0; - static U32 numRxFifoEmpty = 0; - static U32 numRxFifoCheck = 0; switch ( board ) { - // TODO should check Rx FIFO to see if a character exists? case EMSTAT_CPI_CPO_BOARD: // Check for continuous incoming bytes - rxFifoCount = getFPGAEmstatCPiCPoRxFifoCount() & 0x7FFF; - numRxFifoCheck++; - if (numRxFifoCheck == 10000) - { - maxRxFifoCount = 0; - numRxFifoEmpty = 0; - } - if (rxFifoCount > maxRxFifoCount) maxRxFifoCount = rxFifoCount; - if (rxFifoCount == 0) numRxFifoEmpty++; - + rxFifoCount = getFPGAEmstatCPiCPoRxFifoCount() & EMSTAT_RX_FIFO_COUNT_MASK; checkFPGAPersistentAlarms( FPGA_PERS_ERROR_CPI_CPO_COND_SENSORS, rxFifoCount ); // Only process the sensor read if there is a new byte @@ -558,7 +557,7 @@ case EMSTAT_CD1_CD2_BOARD: // Check for continuous incoming bytes - rxFifoCount = getFPGAEmstatCD1CD2RxFifoCount() & 0x7FFF;; + rxFifoCount = getFPGAEmstatCD1CD2RxFifoCount() & EMSTAT_RX_FIFO_COUNT_MASK; checkFPGAPersistentAlarms( FPGA_PERS_ERROR_CD1_CD2_COND_SENSORS, rxFifoCount ); // Only process the sensor read if there is a new byte @@ -590,21 +589,15 @@ switch ( emstatByte ) { case 'P': - if ( FALSE == readPackage->packageStarted) - { - readPackage->packageStarted = TRUE; - readPackage->packageIndex = 0; - readPackage->packetIndex = 0; - readPackage->packetData[readPackage->packetIndex++] = emstatByte; - } + readPackage->packageStarted = TRUE; + readPackage->packageIndex = 0; break; case ';': if ( TRUE == readPackage->packageStarted ) { processEmstatMeasurementDataPackets( EMSTAT_CPI_OR_CD1_INDEX, readPackage, (EMSTAT_VARIABLE_T*)readPackage->package ); readPackage->packageIndex = 0; - readPackage->packetData[readPackage->packetIndex++] = emstatByte; } break; @@ -613,15 +606,13 @@ { processEmstatMeasurementDataPackets( EMSTAT_CPO_OR_CD2_INDEX, readPackage, (EMSTAT_VARIABLE_T*)readPackage->package ); readPackage->packageStarted = FALSE; - readPackage->packetData[readPackage->packetIndex++] = emstatByte; } break; default: if ( TRUE == readPackage->packageStarted ) { - readPackage->packetData[readPackage->packetIndex++] = emstatByte; - if (readPackage->packageIndex < EMSTAT_PACKAGE_BUFFER_SIZE ) + if ( readPackage->packageIndex < EMSTAT_PACKAGE_BUFFER_SIZE ) { readPackage->package[ readPackage->packageIndex++ ] = emstatByte; } @@ -646,18 +637,15 @@ CONDUCTIVITY_SENSORS_T sensorId = readPackage->sensors[ boardSensorIndex ].condSnsr; BOOL convStatus = hexStrToDec( (U08*)&receivedPackets->status, &condSensorStatus[ sensorId ].sensorStatus, sizeof( receivedPackets->status ) ); - BOOL isSensorStatusBad = ( EMSTAT_PICO_STATUS_OK == condSensorStatus[ sensorId ].sensorStatus ? FALSE : TRUE ); + BOOL isSensorStatusBad = ( EMSTAT_PICO_STATUS_TIMING_NOT_MET == condSensorStatus[ sensorId ].sensorStatus ? TRUE : FALSE ); ALARM_ID_T badHexAlarm = readPackage->sensors[ boardSensorIndex ].condSnsrHex2StrAlarm; BOOL isConvNotValid = FALSE; if ( FALSE == isSensorStatusBad ) { U32 prefix = prefixStrToSIFactor( receivedPackets->prefix ); convStatus = hexStrToDec( receivedPackets->value, &condSensorStatus[ sensorId ].rawEmstatCondValue, sizeof( receivedPackets->value ) ); - if (FALSE == convStatus) - { - readPackage->sensors[ boardSensorIndex ].invalidCharCounter++; - } + 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; @@ -670,15 +658,23 @@ isConvNotValid = ( TRUE == convStatus ? FALSE : TRUE ); // Check the conductivity sensors bad status alarm - checkPersistentAlarm( badHexAlarm, isConvNotValid, isConvNotValid, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); - checkPersistentAlarm( ALARM_ID_DG_CONDUCTIVITY_SENSOR_BAD_STATUS, isSensorStatusBad, condSensorStatus[ sensorId ].sensorStatus, - EMSTAT_PICO_STATUS_TIMING_NOT_MET ); + if ( TRUE == isConvNotValid ) + { + if ( ++condSensorStatus[ sensorId ].badCharErrorCount > MAX_CONDUCTIVITY_SENSOR_FAILURES ) + { + SET_ALARM_WITH_1_U32_DATA( badHexAlarm, sensorId ); + } + } + else + { + condSensorStatus[ sensorId ].badCharErrorCount = 0; + } - if ( EMSTAT_PICO_STATUS_OK != condSensorStatus[ sensorId ].sensorStatus ) + if ( EMSTAT_PICO_STATUS_TIMING_NOT_MET == condSensorStatus[ sensorId ].sensorStatus ) { if ( ++condSensorStatus[ sensorId ].internalErrorCount > MAX_CONDUCTIVITY_SENSOR_FAILURES ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_CONDUCTIVITY_SENSOR_FAULT, sensorId, condSensorStatus[ sensorId ].sensorStatus ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_CONDUCTIVITY_SENSOR_FAULT, sensorId, condSensorStatus[ sensorId ].sensorStatus ); } } else