Index: firmware/App/Controllers/ConductivitySensors.c =================================================================== diff -u -r025612ad77fe630889a364586de54bffe5262d56 -rc7ed4f90b600fe684097654f150e4972646ffec9 --- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 025612ad77fe630889a364586de54bffe5262d56) +++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision c7ed4f90b600fe684097654f150e4972646ffec9) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 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) 06-Nov-2021 +* @date (last) 02-Mar-2022 * * @author (original) Quang Nguyen * @date (original) 13-Jul-2020 @@ -18,8 +18,9 @@ #include "ConductivitySensors.h" #include "FPGA.h" -#include "PersistentAlarm.h" +#include "NVDataMgmt.h" #include "MessageSupport.h" +#include "PersistentAlarm.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TaskPriority.h" @@ -43,16 +44,19 @@ #define COND_SENSOR_REFERENCE_TEMPERATURE 25 ///< Reference temperature for conductivity sensor. #define COND_SENSOR_REPORT_PERIOD ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Broadcast conductivity values message every second. -#define COND_SENSOR_CPI_MAX_VALUE 2000 ///< Maximum inlet water conductivity. -#define COND_SENSOR_CPI_MIN_VALUE 100 ///< Minimum inlet water conductivity. +#define MAX_COND_SENSOR_CPI_WARNING_HIGH 2000.0F ///< Maximum allowed high conductivity value. +#define MIN_COND_SENSOR_CPI_WARNING_HIGH 1990.0F ///< Minimum allowed high conductivity value. +#define MAX_COND_SENSOR_CPI_WARNING_LOW 100.0F ///< Maximum allowed low conductivity value. +#define MIN_COND_SENSOR_CPI_WARNING_LOW 110.0F ///< Minimum allowed low conductivity value. + #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_FAILURE_WINDOW_MS ( 60 * MS_PER_SECOND ) ///< Conductivity sensor error window. #define RO_REJECTION_RATIO_OUT_OF_RANGE_VALUE 1.0 ///< Out of range value for RO rejection ratio when CPi conductivity is zero. -#define MAX_RO_REJECTION_RATIO_ALLOW 0.1 ///< Maximum RO rejection ratio. -#define MAX_CPO_CONDUCTIVITY_ALLOW 15.0 ///< Maximum CPo sensor conductivity value. +#define MAX_RO_REJECTION_RATIO_ALLOW 0.10F ///< Maximum RO rejection ratio. +#define MAX_CPO_CONDUCTIVITY_ALLOW 30.0 ///< Maximum CPo sensor conductivity value. #define COND_SENSOR_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for conductivity sensor out of range error. #define RO_REJECTION_RATIO_PERSISTENCE_PERIOD ( 10 * MS_PER_SECOND ) ///< Persistence period for RO rejection ratio. @@ -61,6 +65,7 @@ #define EMSTAT_PICO_GOOD_STATUS 0x10 ///< Measurement good status. #define EMSTAT_PICO_TIMING_NOT_MET_STATUS 0x11 ///< Measurement takes too long status. #define EMSTAT_PICO_FIFO_EMPTY_MASK 0x8000 ///< Emstat Pico buffer empty indication bit. +#define DATA_PUBLISH_COUNTER_START_COUNT 40 ///< Data publish counter start count. #pragma pack(push,1) /// Emstat pico measurement data package structure @@ -89,14 +94,15 @@ static U08 readCount[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Read count for conductivity readings. static U32 internalErrorCount[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Internal error count for conductivity readings. static OVERRIDE_F32_T compensatedConductivityValues[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Latest compensated conductivity values. +static F32 rawConductivityValues[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Latest raw conductivity values. static F32 roRejectionRatio; ///< Latest RO rejection ratio. static OVERRIDE_U32_T conductivityDataPublishInterval = { COND_SENSOR_REPORT_PERIOD, COND_SENSOR_REPORT_PERIOD, 0, 0 }; ///< Conductivity sensors publish time interval override. -static U32 conductivityDataPublicationTimerCounter = 0; ///< Conductivity sensors data publish timer counter. +static U32 conductivityDataPublicationTimerCounter; ///< Conductivity sensors data publish timer counter. static BOOL packageStarted = FALSE; ///< Flag to indicate the start of a package measurement data. -static U08 packageIndex = 0U; ///< Current package measurement data bytes index. +static U08 packageIndex; ///< Current package measurement data bytes index. static U08 package[ 50 ]; ///< Storage of package bytes until ready to process. static DG_COND_SENSORS_CAL_RECORD_T condSensorsCalRecord; ///< Conductivity sensors' calibration record. @@ -109,7 +115,6 @@ static U32 prefixStrToSIFactor( U08 prefix ); static void processMeasurementDataPackage( U32 sensorId ); static void processCD1CD2SensorRead( U16 fpgaReadCount, U08 fpgaErrorCount ); -static BOOL processCalibrationData( void ); static F32 getCalibrationAppliedConductivityValue( U32 sensorId, F32 compensatedValue ); /*********************************************************************//** @@ -122,7 +127,9 @@ void initConductivitySensors( void ) { U32 i; - roRejectionRatio = 0.0; + roRejectionRatio = 0.0; + packageIndex = 0U; + conductivityDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; for ( i = 0; i < NUM_OF_CONDUCTIVITY_SENSORS; i++ ) { @@ -133,14 +140,17 @@ compensatedConductivityValues[ i ].ovData = 0.0; compensatedConductivityValues[ i ].ovInitData = 0.0; compensatedConductivityValues[ i ].override = OVERRIDE_RESET; + + rawConductivityValues[ i ] = 0.0; } setFPGACPiProbeType( COND_CPI_SENSOR_PROBE_TYPE ); setFPGACPoProbeType( COND_CPO_SENSOR_PROBE_TYPE ); initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CONDUCTIVITY_SENSOR_ERROR, MAX_CONDUCTIVITY_SENSOR_FAILURES, MAX_CONDUCTIVITY_SENSOR_FAILURE_WINDOW_MS ); initPersistentAlarm( ALARM_ID_INLET_WATER_HIGH_CONDUCTIVITY, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); - initPersistentAlarm( ALARM_ID_INLET_WATER_LOW_CONDUCTIVITY, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); + initPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); + initPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); initPersistentAlarm( ALARM_ID_RO_REJECTION_RATIO_OUT_OF_RANGE, RO_REJECTION_RATIO_PERSISTENCE_PERIOD, RO_REJECTION_RATIO_PERSISTENCE_PERIOD ); } @@ -158,8 +168,8 @@ // Check if a new calibration is available if ( TRUE == isNewCalibrationRecordAvailable() ) { - // Get the new calibration data and check its validity - processCalibrationData(); + getNVRecord2Driver( GET_CAL_CONDUCTIVITY_SENSORS, (U08*)&condSensorsCalRecord, sizeof( condSensorsCalRecord ), + NUM_OF_CAL_DATA_COND_SENSORS, ALARM_ID_DG_COND_SENSORS_INVALID_CAL_RECORD ); } processCPiCPoSensorRead( CONDUCTIVITYSENSORS_CPI_SENSOR, getFPGACPi(), getFPGACPiReadCount(), getFPGACPiErrorCount(), getFPGACPiFault() ); @@ -173,12 +183,18 @@ calcRORejectionRatio(); conductivityDataPublicationTimerCounter = 0; - data.roRejectionRatio = roRejectionRatio; + data.roRejectionRatio = roRejectionRatio; + data.cpi = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); data.cpo = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); data.cd1 = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); data.cd2 = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); + data.cpiRaw = rawConductivityValues[ CONDUCTIVITYSENSORS_CPI_SENSOR ]; + data.cpoRaw = rawConductivityValues[ CONDUCTIVITYSENSORS_CPO_SENSOR ]; + data.cd1Raw = rawConductivityValues[ CONDUCTIVITYSENSORS_CD1_SENSOR ]; + data.cd2Raw = rawConductivityValues[ CONDUCTIVITYSENSORS_CD2_SENSOR ]; + broadcastData( MSG_ID_DG_CONDUCTIVITY_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( CONDUCTIVITY_DATA_T ) ); } } @@ -195,7 +211,8 @@ { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; - BOOL calStatus = processCalibrationData(); + 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 ); if ( TRUE == calStatus ) { @@ -212,20 +229,41 @@ /*********************************************************************//** * @brief * The checkInletWaterConductivity function checks inlet water conductivity value - * and triggers an alarm when conductivity value is out of allowed range. + * and triggers an alarm when conductivity value is not within the specified + * values. * @details Inputs: CPi sensor conductivity - * @details Outputs: Trigger alarms when conductivity is out of allowed range + * @details Outputs: Trigger warning alarm if conductivity is in the warning + * range. Trigger alarm if conductivity is below minimum conductivity. * @return none *************************************************************************/ void checkInletWaterConductivity( void ) { #ifndef DISABLE_WATER_QUALITY_CHECK - F32 const conductivity = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); - BOOL const isCondTooHigh = ( conductivity > COND_SENSOR_CPI_MAX_VALUE ); - BOOL const isCondTooLow = ( conductivity < COND_SENSOR_CPI_MIN_VALUE ); - checkPersistentAlarm( ALARM_ID_INLET_WATER_HIGH_CONDUCTIVITY, isCondTooHigh, conductivity, COND_SENSOR_CPI_MAX_VALUE ); - checkPersistentAlarm( ALARM_ID_INLET_WATER_LOW_CONDUCTIVITY, isCondTooLow, conductivity, COND_SENSOR_CPI_MIN_VALUE ); + F32 conductivity = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); + BOOL isConductTooLow = ( conductivity < MAX_COND_SENSOR_CPI_WARNING_LOW ? TRUE : FALSE ); + BOOL isConductInWarningRange = ( conductivity > MAX_COND_SENSOR_CPI_WARNING_HIGH ? TRUE : FALSE ); + + // Alarm per PRS 403 + if ( TRUE == isConductTooLow ) + { + checkPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, isConductTooLow, conductivity, MAX_COND_SENSOR_CPI_WARNING_LOW ); + } + else if ( conductivity >= MIN_COND_SENSOR_CPI_WARNING_LOW ) + { + checkPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, FALSE, conductivity, MAX_COND_SENSOR_CPI_WARNING_LOW ); + } + + // Alarm per PRS 404 + if ( TRUE == isConductInWarningRange ) + { + checkPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE, isConductInWarningRange, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH ); + } + else if ( conductivity <= MIN_COND_SENSOR_CPI_WARNING_HIGH ) + { + checkPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE, FALSE, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH ); + } + #endif } @@ -241,10 +279,11 @@ void checkRORejectionRatio( void ) { #ifndef DISABLE_RO_RATIO_CHECK - F32 const cpo = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); - BOOL const isRORejectionRatioOutOfRange = ( roRejectionRatio > MAX_RO_REJECTION_RATIO_ALLOW ) || ( cpo >= MAX_CPO_CONDUCTIVITY_ALLOW ); + F32 cpo = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); + BOOL isRORectionOutOfRange = ( ( roRejectionRatio > MAX_RO_REJECTION_RATIO_ALLOW ) || ( cpo >= MAX_CPO_CONDUCTIVITY_ALLOW ) ? TRUE : FALSE ); - checkPersistentAlarm( ALARM_ID_RO_REJECTION_RATIO_OUT_OF_RANGE, isRORejectionRatioOutOfRange, roRejectionRatio, MAX_RO_REJECTION_RATIO_ALLOW ); + // Fault alarm per PRS 483 + checkPersistentAlarm( ALARM_ID_RO_REJECTION_RATIO_OUT_OF_RANGE, isRORectionOutOfRange, roRejectionRatio, MAX_RO_REJECTION_RATIO_ALLOW ); #endif } @@ -277,7 +316,7 @@ * @brief * The calcCompensatedConductivity function calculates the compensated * conductivity based on given temperature and conductivity taken at - * reference temperature of 25 Celcius. + * reference temperature of 25 degree Celsius. * @details Inputs: conductivity, temperature * @details Outputs: none * @param conductivity conductivity value @@ -286,10 +325,10 @@ *************************************************************************/ static F32 calcCompensatedConductivity( F32 conductivity, F32 temperature ) { - // EC = EC_25 * (1 + temp_coef * (temperature - 25)) + // EC = EC_25 * (1 + temp_coef * ( temperature - 25 )) F32 const compensatedCoef = ( 1.0 + ( COND_SENSOR_TEMPERATURE_COEF * ( temperature - COND_SENSOR_REFERENCE_TEMPERATURE ) ) ); - return conductivity * compensatedCoef; + return conductivity / compensatedCoef; } /*********************************************************************//** @@ -340,6 +379,7 @@ readCount[ sensorId ] = fpgaReadCount; internalErrorCount[ sensorId ] = 0; compensatedConductivityValues[ sensorId ].data = getCalibrationAppliedConductivityValue( sensorId, compensatedCond ); + rawConductivityValues[ sensorId ] = conductivity; // store raw conductivity data from CPi and CPo } else { @@ -418,10 +458,13 @@ internalErrorCount[ sensorId ] = 0; compensatedConductivityValues[ sensorId ].data = getCalibrationAppliedConductivityValue( sensorId, compensatedCond ); + rawConductivityValues[ sensorId ] = conductivity; // store raw conductivity data from CD1 and CD2 + } else { compensatedConductivityValues[ sensorId ].data = 0.0; + rawConductivityValues[ sensorId ] = 0.0; } if ( EMSTAT_PICO_TIMING_NOT_MET_STATUS == status ) @@ -502,47 +545,6 @@ /*********************************************************************//** * @brief - * The processCalibrationData function gets the calibration data and makes - * sure it is valid by checking the calibration date. The calibration date - * should not be 0. - * @details Inputs: none - * @details Outputs: condSensorsCalRecord - * @return TRUE if the calibration record is valid, otherwise FALSE - *************************************************************************/ -static BOOL processCalibrationData( void ) -{ - BOOL status = TRUE; - U32 sensor; - - // Get the calibration record from NVDataMgmt - DG_COND_SENSORS_CAL_RECORD_T calData = getDGConducitivitySensorsCalibrationRecord(); - - for ( sensor = 0; sensor < NUM_OF_CAL_DATA_COND_SENSORS; sensor++ ) - { -#ifndef SKIP_CAL_CHECK - // Check if the calibration data that was received from NVDataMgmt is legitimate - // The calibration date item should not be zero. If the calibration date is 0, - // then the data is not stored in the NV memory or it was corrupted. - if ( 0 == calData.condSensors[ sensor ].calibrationTime ) - { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_COND_SENSORS_INVALID_CAL_RECORD, (U32)sensor ); - status = FALSE; - } -#endif - - // The calibration data was valid, update the local copy - condSensorsCalRecord.condSensors[ sensor ].fourthOrderCoeff = calData.condSensors[ sensor ].fourthOrderCoeff; - condSensorsCalRecord.condSensors[ sensor ].thirdOrderCoeff = calData.condSensors[ sensor ].thirdOrderCoeff; - condSensorsCalRecord.condSensors[ sensor ].secondOrderCoeff = calData.condSensors[ sensor ].secondOrderCoeff; - condSensorsCalRecord.condSensors[ sensor ].gain = calData.condSensors[ sensor ].gain; - condSensorsCalRecord.condSensors[ sensor ].offset = calData.condSensors[ sensor ].offset; - } - - return status; -} - -/*********************************************************************//** - * @brief * The getCalibrationAppliedConductivityValue function gets the temperature * compensated conductivity value and applies calibration to it. * @details Inputs: condSensorsCalRecord