Index: firmware/App/Controllers/LoadCell.c =================================================================== diff -u -rc127dcd204e97f487256c3f14e1998bde0b7823d -re6f3a632890f96a5aa282922d11df148bdd06587 --- firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision c127dcd204e97f487256c3f14e1998bde0b7823d) +++ firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision e6f3a632890f96a5aa282922d11df148bdd06587) @@ -50,8 +50,8 @@ /// Load cell data structure. typedef struct { - U32 rawReading; ///< Latest raw load cell reading. - OVERRIDE_F32_T weight; ///< Latest load cell weight. + U32 rawReading; ///< Latest raw load cell reading + OVERRIDE_F32_T weight; ///< Latest load cell weight F32 autoCalOffset; ///< Load cell auto-calibration offset F32 loadCellVelocity_g_min; ///< Velocity (in g/min) of load cell. @@ -67,14 +67,14 @@ // ********** private data ********** static OVERRIDE_U32_T loadCellDataPublishInterval = { LOAD_CELL_REPORT_PERIOD, - LOAD_CELL_REPORT_PERIOD, 0, 0 }; ///< Broadcast load cell data publish interval. -static LOADCELL_T loadcells[ NUM_OF_LOAD_CELLS ]; ///< Load cell data structures. -static U32 loadCellFilterTimerCount = 0; ///< Load cell filtering timer count. -static U32 loadCellDataPublicationTimerCounter = 0; ///< Load cell data publication timer counter to CAN bus. + LOAD_CELL_REPORT_PERIOD, 0, 0 }; ///< Broadcast load cell data publish interval. +static LOADCELL_T loadcells[ NUM_OF_LOAD_CELLS ]; ///< Load cell data structures. +static U32 loadCellFilterTimerCount = 0; ///< Load cell filtering timer count. +static U32 loadCellDataPublicationTimerCounter = 0; ///< Load cell data publication timer counter to CAN bus. -static U32 smallReadingsIdx; ///< Index for next sample in load cell small rolling average sample array. -static U32 largeReadingsIdx; ///< Index for next sample in load cell large rolling average sample array. -static DG_LOAD_CELLS_CAL_RECORD_T loadCellsCalRecord; ///< Load cells calibration record. +static U32 smallReadingsIdx; ///< Index for next sample in load cell small rolling average sample array. +static U32 largeReadingsIdx; ///< Index for next sample in load cell large rolling average sample array. +static DG_LOAD_CELLS_CAL_RECORD_T loadCellsCalRecord; ///< Load cells calibration record. // ********** private function prototypes ********** @@ -127,7 +127,6 @@ loadcells[ i ].loadCellVelocity_g_min = 0.0; } - // Set all the load cells' calibration values to benign values for ( cell = CAL_DATA_LOAD_CELL_A1; cell < NUM_OF_CAL_DATA_LOAD_CELLS; cell++ ) { // Reset the calibration variables @@ -160,9 +159,9 @@ // update sums for load cell average calculations loadcells[ LOAD_CELL_RESERVOIR_1_PRIMARY ].rawReading = a1 & MASK_OFF_U32_MSB; - loadcells[ LOAD_CELL_RESERVOIR_1_BACKUP ].rawReading = a2 & MASK_OFF_U32_MSB; + loadcells[ LOAD_CELL_RESERVOIR_1_BACKUP ].rawReading = a2 & MASK_OFF_U32_MSB; loadcells[ LOAD_CELL_RESERVOIR_2_PRIMARY ].rawReading = b1 & MASK_OFF_U32_MSB; - loadcells[ LOAD_CELL_RESERVOIR_2_BACKUP ].rawReading = b2 & MASK_OFF_U32_MSB; + loadcells[ LOAD_CELL_RESERVOIR_2_BACKUP ].rawReading = b2 & MASK_OFF_U32_MSB; // Check error bits from new readings a1 = ( a1 >> 31 ) << SHIFT_24_BITS; @@ -175,7 +174,7 @@ } // Check if a new calibration is available - if ( isNewCalibrationRecordAvailable() == TRUE ) + if ( TRUE == isNewCalibrationRecordAvailable() ) { // Get the new calibration data and check its validity processCalibrationData(); @@ -191,22 +190,26 @@ for ( ii = 0; ii < NUM_OF_LOAD_CELLS; ++ii ) { loadcells[ ii ].weight.data = (F32)loadcells[ ii ].rawReading * ADC2GRAM; - // Apply the calibration factors to the data. - // load_cell_weight = fourth_order_coeff * (load_cell^4) + third_order_coeff * (load_cell^3) + second_order_coeff * (load_cell^2) + gain * load_cell + offset - loadcells[ ii ].weight.data = pow(loadcells[ ii ].weight.data, 4) * loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].fourthOrderCoeff + - pow(loadcells[ ii ].weight.data, 3) * loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].thirdOrderCoeff + - pow(loadcells[ ii ].weight.data, 2) * loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].secondOrderCoeff + - loadcells[ ii ].weight.data * loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].gain + - loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].offset; + loadcells[ ii ].weight.data = loadcells[ ii ].weight.data - loadcells[ ii ].autoCalOffset; - loadcells[ ii ].loadCellVelocity_g_min = ( getLoadCellWeight( (LOAD_CELL_ID_T)ii ) - loadcells[ ii ].smallFilterReadings[ smallReadingsIdx ] ) * (F32)SEC_PER_MIN; + loadcells[ ii ].loadCellVelocity_g_min = ( getLoadCellWeight( (LOAD_CELL_ID_T)ii ) - + loadcells[ ii ].smallFilterReadings[ smallReadingsIdx ] ) * (F32)SEC_PER_MIN; // Update small filter with new weight sample loadcells[ ii ].smallFilterTotal -= loadcells[ ii ].smallFilterReadings[ smallReadingsIdx ]; loadcells[ ii ].smallFilterReadings[ smallReadingsIdx ] = getLoadCellWeight( (LOAD_CELL_ID_T)ii ); loadcells[ ii ].smallFilterTotal += getLoadCellWeight( (LOAD_CELL_ID_T)ii ); - loadcells[ ii ].smallFilteredWeight = (F32)( loadcells[ ii ].smallFilterTotal / (F64)SIZE_OF_SMALL_LOAD_CELL_AVG ); + + // Calculate the load cell value before applying calibration to it + F32 loadCell = (F32)( loadcells[ ii ].smallFilterTotal / (F64)SIZE_OF_SMALL_LOAD_CELL_AVG ); + // Apply the calibration factors to the data. + // load_cell_weight = fourth_order_coeff * (load_cell^4) + third_order_coeff * (load_cell^3) + second_order_coeff * (load_cell^2) + gain * load_cell + offset + loadcells[ ii ].smallFilteredWeight = pow(loadCell, 4) * loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].fourthOrderCoeff + + pow(loadCell, 3) * loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].thirdOrderCoeff + + pow(loadCell, 2) * loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].secondOrderCoeff + + loadCell * loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].gain + + loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].offset; } smallReadingsIdx = INC_WRAP( smallReadingsIdx, 0, SIZE_OF_SMALL_LOAD_CELL_AVG - 1 ); @@ -230,13 +233,17 @@ // broadcast load cell data if we are at scheduled interval. if ( ++loadCellDataPublicationTimerCounter >= getLoadCellDataPublishInterval() ) { - loadCellDataPublicationTimerCounter = 0; + LOAD_CELL_DATA_T loadCellData; - // broadcast small filtered load cell data - broadcastLoadCellData( loadcells[ LOAD_CELL_RESERVOIR_1_PRIMARY ].smallFilteredWeight, - loadcells[ LOAD_CELL_RESERVOIR_1_BACKUP ].smallFilteredWeight, - loadcells[ LOAD_CELL_RESERVOIR_2_PRIMARY ].smallFilteredWeight, - loadcells[ LOAD_CELL_RESERVOIR_2_BACKUP ].smallFilteredWeight ); + loadCellData.loadCellA1inGram = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); + loadCellData.loadCellA2inGram = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_BACKUP ); + loadCellData.loadCellB1inGram = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); + loadCellData.loadCellB2inGram = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_BACKUP ); + + // Broadcast small filtered load cell data + broadcastLoadCellData( &loadCellData ); + + loadCellDataPublicationTimerCounter = 0; } } @@ -329,18 +336,14 @@ *************************************************************************/ F32 getLoadCellWeight( LOAD_CELL_ID_T loadCellID ) { - F32 result = 0; + F32 result = loadcells[ loadCellID ].weight.data; if ( loadCellID < NUM_OF_LOAD_CELLS ) { if ( OVERRIDE_KEY == loadcells[ loadCellID ].weight.override ) { result = loadcells[ loadCellID ].weight.ovData; } - else - { - result = loadcells[ loadCellID ].weight.data; - } } else { @@ -352,20 +355,26 @@ /*********************************************************************//** * @brief - * The getLoadCellSmallFilteredWeight function gets the small filtered load cell - * weight for a given load cell ID. + * The getLoadCellSmallFilteredWeight function gets the small filtered + * load cell weight for a given load cell ID. * @details Inputs: load cell filtered weight * @details Outputs: none * @param loadCellID ID of load cell to get large filtered weight * @return the small filtered load cell weight for the given load cell ID. *************************************************************************/ F32 getLoadCellSmallFilteredWeight( LOAD_CELL_ID_T loadCellID ) { - F32 result = 0; + F32 result = 0.0; if ( loadCellID < NUM_OF_LOAD_CELLS ) { result = loadcells[ loadCellID ].smallFilteredWeight; + + // If the load cell is in override mode, return the override weight + if ( OVERRIDE_KEY == loadcells[ loadCellID ].weight.override ) + { + result = loadcells[ loadCellID ].weight.ovData; + } } else { @@ -449,7 +458,7 @@ * 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: loadCellsCalRecord + * @details Inputs: none * @details Outputs: loadCellsCalRecord * @return TRUE if the calibration record is valid, otherwise FALSE *************************************************************************/ @@ -463,25 +472,23 @@ for ( cell = 0; cell < NUM_OF_CAL_DATA_LOAD_CELLS; cell++ ) { +#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 load cells data is not stored in the NV memory or it was corrupted. - if ( calData.loadCells[ cell ].calibrationTime == 0 ) + if ( 0 == calData.loadCells[ cell ].calibrationTime ) { -#ifndef DISABLE_CAL_CHECK SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_LOAD_CELLS_INVALID_CALIBRATION, (U32)cell ); -#endif status = FALSE; } - else - { - // The calibration data was valid, update the local copy - loadCellsCalRecord.loadCells[ cell ].fourthOrderCoeff = calData.loadCells[ cell ].fourthOrderCoeff; - loadCellsCalRecord.loadCells[ cell ].thirdOrderCoeff = calData.loadCells[ cell ].thirdOrderCoeff; - loadCellsCalRecord.loadCells[ cell ].secondOrderCoeff = calData.loadCells[ cell ].secondOrderCoeff; - loadCellsCalRecord.loadCells[ cell ].gain = calData.loadCells[ cell ].gain; - loadCellsCalRecord.loadCells[ cell ].offset = calData.loadCells[ cell ].offset; - } +#endif + + // The calibration data was valid, update the local copy + loadCellsCalRecord.loadCells[ cell ].fourthOrderCoeff = calData.loadCells[ cell ].fourthOrderCoeff; + loadCellsCalRecord.loadCells[ cell ].thirdOrderCoeff = calData.loadCells[ cell ].thirdOrderCoeff; + loadCellsCalRecord.loadCells[ cell ].secondOrderCoeff = calData.loadCells[ cell ].secondOrderCoeff; + loadCellsCalRecord.loadCells[ cell ].gain = calData.loadCells[ cell ].gain; + loadCellsCalRecord.loadCells[ cell ].offset = calData.loadCells[ cell ].offset; } return status;