Index: firmware/App/Controllers/LoadCell.c =================================================================== diff -u -r7cd1a0f1b82cde58d1d67bf722deac5c004e1b94 -r2468e56fbecd26da713bc78535bd727f4b105fe1 --- firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision 7cd1a0f1b82cde58d1d67bf722deac5c004e1b94) +++ firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision 2468e56fbecd26da713bc78535bd727f4b105fe1) @@ -37,7 +37,6 @@ #define LOAD_CELL_REPORT_PERIOD (100 / TASK_PRIORITY_INTERVAL) ///< Broadcast load cell values message every 100 ms. /// Conversion factor from ADC counts to grams. static const F32 ADC2GRAM = (0.0894 * 1.1338); -#define LOAD_CELL_FILTER_ALPHA 0.05 ///< Alpha factor for the alpha filter used on load cell readings. #define SIZE_OF_SMALL_LOAD_CELL_AVG 100 ///< Small load cell moving average has 100 raw samples @ 10ms intervals (1-second). #define SIZE_OF_LARGE_LOAD_CELL_AVG 40 ///< Large load cell moving average has 40 samples from small filter @ 100ms intervals (4-second). @@ -46,10 +45,12 @@ #define LOAD_CELL_MIN_ALLOWED_WEIGHT_GRAMS 0.0 ///< Load cell minimum allowed weight in grams. #define LOAD_CELL_MAX_ALLOWED_WEIGHT_GRAMS 4500.0 ///< Load cell maximum allowed weight in grams. #define LOAD_CELL_MIN_ALLOWED_WEIGHT_BEFORE_TARE_GRAMS 1600.0 ///< Load cell minimum allowed weight before tare in grams. -#define MAX_ALLOWED_EXTRA_WEIGHT_BEFORE_TARE_GRAMS 300.0 ///< Max allowed extra weight before tare in grams. #define LOAD_CELL_WEIGHT_OUT_RANGE_PERSISTENT_PERIOD_MS (5 * MS_PER_SECOND) ///< Load cell weight out of range persistent period in milliseconds. -#define LOAD_CELL_PRIMARY_BACKUP_MAX_ALLOWED_DRIFT_GRAMS 60.0 ///< Load cell primary and backup maximum allowed weight drift in grams. #define LOAD_CELL_PRIMARY_BACKUP_MAX_DRIFT_PERSISTENT_PERIOD_MS (5 * MS_PER_SECOND) ///< Load cell primary and backup maximum allowed weight drift persistent period in milliseconds. +#define EMPTY_RESERVOIR_WEIGHT_GRAMS 1600 ///< Reservoirs empty weight in grams. +#define MAX_ALLOWED_EXTRA_WEIGHT_BEFORE_FIRST_TARE_GRAMS 300 ///< Max allowed extra weight before first tare in grams. +#define MAX_ALLOWED_EXTRA_WEIGHT_BEFORE_TARE_GRAMS 60 ///< Max allowed extra weight before tare in grams. +#define LOAD_CELL_PRIMARY_BACKUP_MAX_ALLOWED_DRIFT_GRAMS 60.0 ///< Load cell primary and backup maximum allowed weight drift in grams. /// Load cell data structure. typedef struct @@ -189,8 +190,16 @@ // Rolling average of last 100 raw samples in small filter for ( ii = 0; ii < NUM_OF_LOAD_CELLS; ++ii ) { - loadcells[ ii ].weight.data = (F32)loadcells[ ii ].rawReading * ADC2GRAM; + F32 loadCell = (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(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; + loadcells[ ii ].loadCellVelocity_g_min = ( getLoadCellWeight( (LOAD_CELL_ID_T)ii ) - loadcells[ ii ].smallFilterReadings[ smallReadingsIdx ] ) * (F32)SEC_PER_MIN; @@ -200,14 +209,7 @@ loadcells[ ii ].smallFilterTotal += getLoadCellWeight( (LOAD_CELL_ID_T)ii ); // 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; + loadcells[ ii ].smallFilteredWeight = (F32)( loadcells[ ii ].smallFilterTotal / (F64)SIZE_OF_SMALL_LOAD_CELL_AVG ); // Monitor the load cells weight monitorLoadCellsWeightOutOfRange( (LOAD_CELL_ID_T)ii ); @@ -300,8 +302,8 @@ { // For the first tare, the weight of the reservoir should be considered // The current weight of the load cell should not be greater than the weight of the reservoir + the extra weight - F32 deltaWeight = fabs( weight - LOAD_CELL_MIN_ALLOWED_WEIGHT_BEFORE_TARE_GRAMS ); - isWeightOutOfRange = ( deltaWeight > MAX_ALLOWED_EXTRA_WEIGHT_BEFORE_TARE_GRAMS ? TRUE : FALSE ); + F32 deltaWeight = fabs( weight - EMPTY_RESERVOIR_WEIGHT_GRAMS ); + isWeightOutOfRange = ( deltaWeight > MAX_ALLOWED_EXTRA_WEIGHT_BEFORE_FIRST_TARE_GRAMS ? TRUE : FALSE ); } else {