SUPER experimental new version of 2D table lookup. See #270
This commit is contained in:
parent
9b96707036
commit
91206ac90e
|
@ -97,11 +97,13 @@ static inline byte correctionWUE()
|
||||||
{
|
{
|
||||||
byte WUEValue;
|
byte WUEValue;
|
||||||
//Possibly reduce the frequency this runs at (Costs about 50 loops per second)
|
//Possibly reduce the frequency this runs at (Costs about 50 loops per second)
|
||||||
if (currentStatus.coolant > (WUETable.axisX[9] - CALIBRATION_TEMPERATURE_OFFSET))
|
//if (currentStatus.coolant > (WUETable.axisX[9] - CALIBRATION_TEMPERATURE_OFFSET))
|
||||||
|
if (currentStatus.coolant > (table2D_getAxisValue(&WUETable, 9) - CALIBRATION_TEMPERATURE_OFFSET))
|
||||||
{
|
{
|
||||||
//This prevents us doing the 2D lookup if we're already up to temp
|
//This prevents us doing the 2D lookup if we're already up to temp
|
||||||
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_WARMUP);
|
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_WARMUP);
|
||||||
WUEValue = WUETable.values[9]; //Set the current value to be whatever the final value on the curve is.
|
//WUEValue = WUETable.values[9]; //Set the current value to be whatever the final value on the curve is.
|
||||||
|
WUEValue = table2D_getAxisValue(&WUETable, 9);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -298,8 +300,7 @@ Uses a 2D enrichment table (WUETable) where the X axis is engine temp and the Y
|
||||||
static inline byte correctionBatVoltage()
|
static inline byte correctionBatVoltage()
|
||||||
{
|
{
|
||||||
byte batValue = 100;
|
byte batValue = 100;
|
||||||
if (currentStatus.battery10 > (injectorVCorrectionTable.axisX[5])) { batValue = injectorVCorrectionTable.values[injectorVCorrectionTable.xSize-1]; } //This prevents us doing the 2D lookup if the voltage is above maximum
|
batValue = table2D_getValue(&injectorVCorrectionTable, currentStatus.battery10);
|
||||||
else { batValue = table2D_getValue(&injectorVCorrectionTable, currentStatus.battery10); }
|
|
||||||
|
|
||||||
return batValue;
|
return batValue;
|
||||||
}
|
}
|
||||||
|
@ -311,8 +312,7 @@ This corrects for changes in air density from movement of the temperature
|
||||||
static inline byte correctionIATDensity()
|
static inline byte correctionIATDensity()
|
||||||
{
|
{
|
||||||
byte IATValue = 100;
|
byte IATValue = 100;
|
||||||
if ( (currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET) > (IATDensityCorrectionTable.axisX[8])) { IATValue = IATDensityCorrectionTable.values[IATDensityCorrectionTable.xSize-1]; } //This prevents us doing the 2D lookup if the intake temp is above maximum
|
IATValue = table2D_getValue(&IATDensityCorrectionTable, currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET); //currentStatus.IAT is the actual temperature, values in IATDensityCorrectionTable.axisX are temp+offset
|
||||||
else { IATValue = table2D_getValue(&IATDensityCorrectionTable, currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET); }//currentStatus.IAT is the actual temperature, values in IATDensityCorrectionTable.axisX are temp+offset
|
|
||||||
|
|
||||||
return IATValue;
|
return IATValue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,7 +263,7 @@ void idleControl()
|
||||||
|
|
||||||
doStep();
|
doStep();
|
||||||
}
|
}
|
||||||
else if( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < iacStepTable.axisX[IDLE_TABLE_SIZE-1])
|
else if( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < table2D_getAxisValue(&iacStepTable, (IDLE_TABLE_SIZE-1)) )
|
||||||
{
|
{
|
||||||
//Standard running
|
//Standard running
|
||||||
//We must also have more than zero RPM for the running state
|
//We must also have more than zero RPM for the running state
|
||||||
|
|
|
@ -57,78 +57,95 @@ void initialiseAll()
|
||||||
|
|
||||||
//Repoint the 2D table structs to the config pages that were just loaded
|
//Repoint the 2D table structs to the config pages that were just loaded
|
||||||
taeTable.valueSize = SIZE_BYTE; //Set this table to use byte values
|
taeTable.valueSize = SIZE_BYTE; //Set this table to use byte values
|
||||||
|
taeTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
taeTable.xSize = 4;
|
taeTable.xSize = 4;
|
||||||
taeTable.values = configPage4.taeValues;
|
taeTable.values = configPage4.taeValues;
|
||||||
taeTable.axisX = configPage4.taeBins;
|
taeTable.axisX = configPage4.taeBins;
|
||||||
maeTable.valueSize = SIZE_BYTE; //Set this table to use byte values
|
maeTable.valueSize = SIZE_BYTE; //Set this table to use byte values
|
||||||
|
maeTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
maeTable.xSize = 4;
|
maeTable.xSize = 4;
|
||||||
maeTable.values = configPage4.maeRates;
|
maeTable.values = configPage4.maeRates;
|
||||||
maeTable.axisX = configPage4.maeBins;
|
maeTable.axisX = configPage4.maeBins;
|
||||||
WUETable.valueSize = SIZE_BYTE; //Set this table to use byte values
|
WUETable.valueSize = SIZE_BYTE; //Set this table to use byte values
|
||||||
|
WUETable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
WUETable.xSize = 10;
|
WUETable.xSize = 10;
|
||||||
WUETable.values = configPage2.wueValues;
|
WUETable.values = configPage2.wueValues;
|
||||||
WUETable.axisX = configPage4.wueBins;
|
WUETable.axisX = configPage4.wueBins;
|
||||||
ASETable.valueSize = SIZE_BYTE;
|
ASETable.valueSize = SIZE_BYTE;
|
||||||
|
ASETable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
ASETable.xSize = 4;
|
ASETable.xSize = 4;
|
||||||
ASETable.values = configPage2.asePct;
|
ASETable.values = configPage2.asePct;
|
||||||
ASETable.axisX = configPage2.aseBins;
|
ASETable.axisX = configPage2.aseBins;
|
||||||
ASECountTable.valueSize = SIZE_BYTE;
|
ASECountTable.valueSize = SIZE_BYTE;
|
||||||
|
ASECountTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
ASECountTable.xSize = 4;
|
ASECountTable.xSize = 4;
|
||||||
ASECountTable.values = configPage2.aseCount;
|
ASECountTable.values = configPage2.aseCount;
|
||||||
ASECountTable.axisX = configPage2.aseBins;
|
ASECountTable.axisX = configPage2.aseBins;
|
||||||
PrimingPulseTable.valueSize = SIZE_BYTE;
|
PrimingPulseTable.valueSize = SIZE_BYTE;
|
||||||
|
PrimingPulseTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
PrimingPulseTable.xSize = 4;
|
PrimingPulseTable.xSize = 4;
|
||||||
PrimingPulseTable.values = configPage2.primePulse;
|
PrimingPulseTable.values = configPage2.primePulse;
|
||||||
PrimingPulseTable.axisX = configPage2.primeBins;
|
PrimingPulseTable.axisX = configPage2.primeBins;
|
||||||
crankingEnrichTable.valueSize = SIZE_BYTE;
|
crankingEnrichTable.valueSize = SIZE_BYTE;
|
||||||
crankingEnrichTable.valueSize = SIZE_BYTE;
|
crankingEnrichTable.axisSize = SIZE_BYTE;
|
||||||
crankingEnrichTable.xSize = 4;
|
crankingEnrichTable.xSize = 4;
|
||||||
crankingEnrichTable.values = configPage10.crankingEnrichValues;
|
crankingEnrichTable.values = configPage10.crankingEnrichValues;
|
||||||
crankingEnrichTable.axisX = configPage10.crankingEnrichBins;
|
crankingEnrichTable.axisX = configPage10.crankingEnrichBins;
|
||||||
|
|
||||||
dwellVCorrectionTable.valueSize = SIZE_BYTE;
|
dwellVCorrectionTable.valueSize = SIZE_BYTE;
|
||||||
|
dwellVCorrectionTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
dwellVCorrectionTable.xSize = 6;
|
dwellVCorrectionTable.xSize = 6;
|
||||||
dwellVCorrectionTable.values = configPage4.dwellCorrectionValues;
|
dwellVCorrectionTable.values = configPage4.dwellCorrectionValues;
|
||||||
dwellVCorrectionTable.axisX = configPage6.voltageCorrectionBins;
|
dwellVCorrectionTable.axisX = configPage6.voltageCorrectionBins;
|
||||||
injectorVCorrectionTable.valueSize = SIZE_BYTE;
|
injectorVCorrectionTable.valueSize = SIZE_BYTE;
|
||||||
|
injectorVCorrectionTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
injectorVCorrectionTable.xSize = 6;
|
injectorVCorrectionTable.xSize = 6;
|
||||||
injectorVCorrectionTable.values = configPage6.injVoltageCorrectionValues;
|
injectorVCorrectionTable.values = configPage6.injVoltageCorrectionValues;
|
||||||
injectorVCorrectionTable.axisX = configPage6.voltageCorrectionBins;
|
injectorVCorrectionTable.axisX = configPage6.voltageCorrectionBins;
|
||||||
IATDensityCorrectionTable.valueSize = SIZE_BYTE;
|
IATDensityCorrectionTable.valueSize = SIZE_BYTE;
|
||||||
|
IATDensityCorrectionTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
IATDensityCorrectionTable.xSize = 9;
|
IATDensityCorrectionTable.xSize = 9;
|
||||||
IATDensityCorrectionTable.values = configPage6.airDenRates;
|
IATDensityCorrectionTable.values = configPage6.airDenRates;
|
||||||
IATDensityCorrectionTable.axisX = configPage6.airDenBins;
|
IATDensityCorrectionTable.axisX = configPage6.airDenBins;
|
||||||
IATRetardTable.valueSize = SIZE_BYTE;
|
IATRetardTable.valueSize = SIZE_BYTE;
|
||||||
|
IATRetardTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
IATRetardTable.xSize = 6;
|
IATRetardTable.xSize = 6;
|
||||||
IATRetardTable.values = configPage4.iatRetValues;
|
IATRetardTable.values = configPage4.iatRetValues;
|
||||||
IATRetardTable.axisX = configPage4.iatRetBins;
|
IATRetardTable.axisX = configPage4.iatRetBins;
|
||||||
CLTAdvanceTable.valueSize = SIZE_BYTE;
|
CLTAdvanceTable.valueSize = SIZE_BYTE;
|
||||||
|
CLTAdvanceTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
CLTAdvanceTable.xSize = 6;
|
CLTAdvanceTable.xSize = 6;
|
||||||
CLTAdvanceTable.values = (byte*)configPage4.cltAdvValues;
|
CLTAdvanceTable.values = (byte*)configPage4.cltAdvValues;
|
||||||
CLTAdvanceTable.axisX = configPage4.cltAdvBins;
|
CLTAdvanceTable.axisX = configPage4.cltAdvBins;
|
||||||
rotarySplitTable.valueSize = SIZE_BYTE;
|
rotarySplitTable.valueSize = SIZE_BYTE;
|
||||||
|
rotarySplitTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
rotarySplitTable.xSize = 8;
|
rotarySplitTable.xSize = 8;
|
||||||
rotarySplitTable.values = configPage10.rotarySplitValues;
|
rotarySplitTable.values = configPage10.rotarySplitValues;
|
||||||
rotarySplitTable.axisX = configPage10.rotarySplitBins;
|
rotarySplitTable.axisX = configPage10.rotarySplitBins;
|
||||||
|
|
||||||
flexFuelTable.valueSize = SIZE_BYTE;
|
flexFuelTable.valueSize = SIZE_BYTE;
|
||||||
|
flexFuelTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
flexFuelTable.xSize = 6;
|
flexFuelTable.xSize = 6;
|
||||||
flexFuelTable.values = configPage10.flexFuelAdj;
|
flexFuelTable.values = configPage10.flexFuelAdj;
|
||||||
flexFuelTable.axisX = configPage10.flexFuelBins;
|
flexFuelTable.axisX = configPage10.flexFuelBins;
|
||||||
flexAdvTable.valueSize = SIZE_BYTE;
|
flexAdvTable.valueSize = SIZE_BYTE;
|
||||||
|
flexAdvTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
flexAdvTable.xSize = 6;
|
flexAdvTable.xSize = 6;
|
||||||
flexAdvTable.values = configPage10.flexAdvAdj;
|
flexAdvTable.values = configPage10.flexAdvAdj;
|
||||||
flexAdvTable.axisX = configPage10.flexAdvBins;
|
flexAdvTable.axisX = configPage10.flexAdvBins;
|
||||||
flexBoostTable.valueSize = SIZE_INT;
|
flexBoostTable.valueSize = SIZE_INT;
|
||||||
|
flexBoostTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins (NOTE THIS IS DIFFERENT TO THE VALUES!!)
|
||||||
flexBoostTable.xSize = 6;
|
flexBoostTable.xSize = 6;
|
||||||
flexBoostTable.values16 = configPage10.flexBoostAdj;
|
flexBoostTable.values = configPage10.flexBoostAdj;
|
||||||
flexBoostTable.axisX = configPage10.flexBoostBins;
|
flexBoostTable.axisX = configPage10.flexBoostBins;
|
||||||
|
|
||||||
knockWindowStartTable.valueSize = SIZE_BYTE;
|
knockWindowStartTable.valueSize = SIZE_BYTE;
|
||||||
|
knockWindowStartTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
knockWindowStartTable.xSize = 6;
|
knockWindowStartTable.xSize = 6;
|
||||||
knockWindowStartTable.values = configPage10.knock_window_angle;
|
knockWindowStartTable.values = configPage10.knock_window_angle;
|
||||||
knockWindowStartTable.axisX = configPage10.knock_window_rpms;
|
knockWindowStartTable.axisX = configPage10.knock_window_rpms;
|
||||||
knockWindowDurationTable.valueSize = SIZE_BYTE;
|
knockWindowDurationTable.valueSize = SIZE_BYTE;
|
||||||
|
knockWindowDurationTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||||
knockWindowDurationTable.xSize = 6;
|
knockWindowDurationTable.xSize = 6;
|
||||||
knockWindowDurationTable.values = configPage10.knock_window_dur;
|
knockWindowDurationTable.values = configPage10.knock_window_dur;
|
||||||
knockWindowDurationTable.axisX = configPage10.knock_window_rpms;
|
knockWindowDurationTable.axisX = configPage10.knock_window_rpms;
|
||||||
|
|
|
@ -12,14 +12,16 @@ The 2D table can contain either 8-bit (byte) or 16-bit (int) values
|
||||||
The valueSize variable should be set to either 8 or 16 to indicate this BEFORE the table is used
|
The valueSize variable should be set to either 8 or 16 to indicate this BEFORE the table is used
|
||||||
*/
|
*/
|
||||||
struct table2D {
|
struct table2D {
|
||||||
|
//Used 5414 RAM with original version
|
||||||
byte valueSize;
|
byte valueSize;
|
||||||
|
byte axisSize;
|
||||||
byte xSize;
|
byte xSize;
|
||||||
|
|
||||||
byte *values;
|
void *values;
|
||||||
byte *axisX;
|
void *axisX;
|
||||||
|
|
||||||
int16_t *values16;
|
//int16_t *values16;
|
||||||
int16_t *axisX16;
|
//int16_t *axisX16;
|
||||||
|
|
||||||
//Store the last X and Y coordinates in the table. This is used to make the next check faster
|
//Store the last X and Y coordinates in the table. This is used to make the next check faster
|
||||||
int16_t lastXMax;
|
int16_t lastXMax;
|
||||||
|
@ -33,6 +35,8 @@ struct table2D {
|
||||||
|
|
||||||
//void table2D_setSize(struct table2D targetTable, byte newSize);
|
//void table2D_setSize(struct table2D targetTable, byte newSize);
|
||||||
void table2D_setSize(struct table2D, byte);
|
void table2D_setSize(struct table2D, byte);
|
||||||
|
int16_t table2D_getAxisValue(struct table2D, byte);
|
||||||
|
int16_t table2D_getRawValue(struct table2D, byte);
|
||||||
|
|
||||||
struct table3D {
|
struct table3D {
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ Note that this may clear some of the existing values of the table
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
|
/*
|
||||||
void table2D_setSize(struct table2D* targetTable, byte newSize)
|
void table2D_setSize(struct table2D* targetTable, byte newSize)
|
||||||
{
|
{
|
||||||
//Table resize is ONLY permitted during system initialisation.
|
//Table resize is ONLY permitted during system initialisation.
|
||||||
|
@ -33,6 +34,7 @@ void table2D_setSize(struct table2D* targetTable, byte newSize)
|
||||||
} //Byte or int
|
} //Byte or int
|
||||||
} //initialisationComplete
|
} //initialisationComplete
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
void table3D_setSize(struct table3D *targetTable, byte newSize)
|
void table3D_setSize(struct table3D *targetTable, byte newSize)
|
||||||
|
@ -56,7 +58,8 @@ ie: Given a value on the X axis, it returns a Y value that coresponds to the poi
|
||||||
This function must take into account whether a table contains 8-bit or 16-bit values.
|
This function must take into account whether a table contains 8-bit or 16-bit values.
|
||||||
Unfortunately this means many of the lines are duplicated depending on this
|
Unfortunately this means many of the lines are duplicated depending on this
|
||||||
*/
|
*/
|
||||||
int table2D_getValue(struct table2D *fromTable, int X_in)
|
/*
|
||||||
|
int table2D_getValue_orig(struct table2D *fromTable, int X_in)
|
||||||
{
|
{
|
||||||
int returnValue = 0;
|
int returnValue = 0;
|
||||||
bool valueFound = false;
|
bool valueFound = false;
|
||||||
|
@ -184,9 +187,7 @@ int table2D_getValue(struct table2D *fromTable, int X_in)
|
||||||
unsigned int n = xMaxValue - xMinValue;
|
unsigned int n = xMaxValue - xMinValue;
|
||||||
|
|
||||||
//Float version
|
//Float version
|
||||||
/*
|
//int yVal = (m / n) * (abs(fromTable.values[xMax] - fromTable.values[xMin]));
|
||||||
int yVal = (m / n) * (abs(fromTable.values[xMax] - fromTable.values[xMin]));
|
|
||||||
*/
|
|
||||||
|
|
||||||
//Non-Float version
|
//Non-Float version
|
||||||
uint16_t yVal;
|
uint16_t yVal;
|
||||||
|
@ -216,6 +217,160 @@ int table2D_getValue(struct table2D *fromTable, int X_in)
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int table2D_getValue(struct table2D *fromTable, int X_in)
|
||||||
|
{
|
||||||
|
//Orig memory usage = 5414
|
||||||
|
int returnValue = 0;
|
||||||
|
bool valueFound = false;
|
||||||
|
|
||||||
|
//Copy the from table values (bytes or ints) into common int temp arrays
|
||||||
|
int tempAxisX[fromTable->xSize];
|
||||||
|
int tempValues[fromTable->xSize];
|
||||||
|
for(byte x=0; x< fromTable->xSize; x++)
|
||||||
|
{
|
||||||
|
if(fromTable->valueSize == SIZE_INT) { tempValues[x] = ((int16_t*)((*fromTable).values))[x]; }
|
||||||
|
else if(fromTable->valueSize == SIZE_BYTE) { tempValues[x] = ((uint8_t*)((*fromTable).values))[x]; }
|
||||||
|
|
||||||
|
if(fromTable->axisSize == SIZE_INT) { tempAxisX[x] = ((int16_t*)((*fromTable).axisX))[x]; }
|
||||||
|
else if(fromTable->axisSize == SIZE_BYTE) { tempAxisX[x] = ((uint8_t*)((*fromTable).axisX))[x]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
int X = X_in;
|
||||||
|
int xMinValue, xMaxValue;
|
||||||
|
int xMin = 0;
|
||||||
|
int xMax = 0;
|
||||||
|
|
||||||
|
xMinValue = tempAxisX[0];
|
||||||
|
xMaxValue = tempAxisX[fromTable->xSize-1];
|
||||||
|
|
||||||
|
//Check whether the X input is the same as last time this ran
|
||||||
|
if( (X_in == fromTable->lastInput) && (fromTable->cacheTime == currentStatus.secl) )
|
||||||
|
{
|
||||||
|
returnValue = fromTable->lastOutput;
|
||||||
|
valueFound = true;
|
||||||
|
}
|
||||||
|
//If the requested X value is greater/small than the maximum/minimum bin, reset X to be that value
|
||||||
|
else if(X > xMaxValue)
|
||||||
|
{
|
||||||
|
returnValue = tempValues[fromTable->xSize-1];
|
||||||
|
valueFound = true;
|
||||||
|
}
|
||||||
|
else if(X < xMinValue)
|
||||||
|
{
|
||||||
|
returnValue = tempValues[0];
|
||||||
|
valueFound = true;
|
||||||
|
}
|
||||||
|
//Finally if none of that is found
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fromTable->cacheTime = currentStatus.secl; //As we're not using the cache value, set the current secl value to track when this new value was calc'd
|
||||||
|
|
||||||
|
//If the requested X value is greater/small than the maximum/minimum bin, reset X to be that value
|
||||||
|
//Failsafe, this should've been handled above
|
||||||
|
if(X > xMaxValue) { X = xMaxValue; }
|
||||||
|
if(X < xMinValue) { X = xMinValue; }
|
||||||
|
|
||||||
|
|
||||||
|
//1st check is whether we're still in the same X bin as last time
|
||||||
|
if ( (X <= tempAxisX[fromTable->lastXMax]) && (X > tempAxisX[fromTable->lastXMin]) )
|
||||||
|
{
|
||||||
|
xMaxValue = tempAxisX[fromTable->lastXMax];
|
||||||
|
xMinValue = tempAxisX[fromTable->lastXMin];
|
||||||
|
xMax = fromTable->lastXMax;
|
||||||
|
xMin = fromTable->lastXMin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//If we're not in the same bin, loop through to find where we are
|
||||||
|
for (int x = fromTable->xSize-1; x >= 0; x--)
|
||||||
|
{
|
||||||
|
//Checks the case where the X value is exactly what was requested
|
||||||
|
if ( (X == tempAxisX[x]) || (x == 0) )
|
||||||
|
{
|
||||||
|
returnValue = tempValues[x]; //Simply return the coresponding value
|
||||||
|
valueFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Normal case
|
||||||
|
if ( (X <= tempAxisX[x]) && (X > tempAxisX[x-1]) )
|
||||||
|
{
|
||||||
|
xMaxValue = tempAxisX[x];
|
||||||
|
xMinValue = tempAxisX[x-1];
|
||||||
|
xMax = x;
|
||||||
|
fromTable->lastXMax = xMax;
|
||||||
|
xMin = x-1;
|
||||||
|
fromTable->lastXMin = xMin;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} //X_in same as last time
|
||||||
|
|
||||||
|
if (valueFound == false)
|
||||||
|
{
|
||||||
|
int16_t m = X - xMinValue;
|
||||||
|
int16_t n = xMaxValue - xMinValue;
|
||||||
|
|
||||||
|
//Float version
|
||||||
|
/*
|
||||||
|
int yVal = (m / n) * (abs(fromTable.values[xMax] - fromTable.values[xMin]));
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Non-Float version
|
||||||
|
int16_t yVal;
|
||||||
|
yVal = ((long)(m << 6) / n) * (abs(tempValues[xMax] - tempValues[xMin]));
|
||||||
|
yVal = (yVal >> 6);
|
||||||
|
|
||||||
|
if (tempValues[xMax] > tempValues[xMin]) { yVal = tempValues[xMin] + yVal; }
|
||||||
|
else { yVal = tempValues[xMin] - yVal; }
|
||||||
|
|
||||||
|
returnValue = yVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
fromTable->lastInput = X_in;
|
||||||
|
fromTable->lastOutput = returnValue;
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns an axis (bin) value from the 2D table. This works regardless of whether that axis is bytes or int16_ts
|
||||||
|
*
|
||||||
|
* @param fromTable
|
||||||
|
* @param X_in
|
||||||
|
* @return int16_t
|
||||||
|
*/
|
||||||
|
int16_t table2D_getAxisValue(struct table2D *fromTable, byte X_in)
|
||||||
|
{
|
||||||
|
int returnValue = 0;
|
||||||
|
|
||||||
|
if(fromTable->axisSize == SIZE_INT) { returnValue = ((int16_t*)((*fromTable).axisX))[X_in]; }
|
||||||
|
else if(fromTable->axisSize == SIZE_BYTE) { returnValue = ((uint8_t*)((*fromTable).axisX))[X_in]; }
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns an value from the 2D table given an index value. No interpolation is performed
|
||||||
|
*
|
||||||
|
* @param fromTable
|
||||||
|
* @param X_in
|
||||||
|
* @return int16_t
|
||||||
|
*/
|
||||||
|
int16_t table2D_getRawValue(struct table2D *fromTable, byte X_index)
|
||||||
|
{
|
||||||
|
int returnValue = 0;
|
||||||
|
|
||||||
|
if(fromTable->valueSize == SIZE_INT) { returnValue = ((int16_t*)((*fromTable).values))[X_index]; }
|
||||||
|
else if(fromTable->valueSize == SIZE_BYTE) { returnValue = ((uint8_t*)((*fromTable).values))[X_index]; }
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//This function pulls a value from a 3D table given a target for X and Y coordinates.
|
//This function pulls a value from a 3D table given a target for X and Y coordinates.
|
||||||
|
|
Loading…
Reference in New Issue