#include "inc/freeEMS.h"
#include "inc/commsCore.h"
#include "inc/coreVarsGenerator.h"
Go to the source code of this file.
Defines | |
#define | COREVARSGENERATOR_C |
Functions | |
void | generateCoreVars () |
Generate the core variables and average them. |
This file contains the function that transfers the raw ADC values to actual physical measurements and averages them.
Definition in file coreVarsGenerator.c.
#define COREVARSGENERATOR_C |
Definition at line 39 of file coreVarsGenerator.c.
void generateCoreVars | ( | void | ) |
Generate the core variables and average them.
Each raw ADC value is converted to a usable measurement via a variety of methods chosen at runtime by configured settings. Once in their native units and therefore closer to maximal use of the available data range they are all averaged.
Definition at line 58 of file coreVarsGenerator.c.
Referenced by main().
00058 { 00059 /*&&&&&&&& Calculate and obtain the basic variables with which we will perform the calculations &&&&&&&&*/ 00060 00061 00062 /* Pre calculate things used in multiple places */ 00063 00064 /* Bound the TPS ADC reading and shift it to start at zero */ 00065 unsigned short unboundedTPSADC = ADCArrays->TPS; 00066 if(unboundedTPSADC > fixedConfigs2.sensorRanges.TPSMaximumADC){ 00067 boundedTPSADC = TPSADCRange; 00068 }else if(unboundedTPSADC > fixedConfigs2.sensorRanges.TPSMinimumADC){ // force secondary config to be used... TODO remove this 00069 boundedTPSADC = unboundedTPSADC - fixedConfigs2.sensorRanges.TPSMinimumADC; 00070 }else{ 00071 boundedTPSADC = 0; 00072 } 00073 00074 00075 /* Get BRV from ADC using transfer variables (all installations need this) */ 00076 unsigned short localBRV; 00077 if(TRUE){ /* If BRV connected */ 00078 localBRV = (((unsigned long)ADCArrays->BRV * fixedConfigs2.sensorRanges.BRVRange) / ADC_DIVISIONS) + fixedConfigs2.sensorRanges.BRVMinimum; 00079 }else if(FALSE){ /* Configured to be fixed value */ 00080 /* Get the preferred BRV figure from configuration settings */ 00081 localBRV = fixedConfigs2.sensorPresets.presetBRV; 00082 }else{ /* Fail safe if config is broken */ 00083 /* Default to normal alternator charging voltage 14.4V */ 00084 localBRV = runningVoltage; 00085 /* If anyone is listening, let them know something is wrong */ 00086 sendErrorIfClear(BRV_NOT_CONFIGURED_CODE); 00087 } 00088 00089 00090 unsigned short localCHT; 00091 /* Get CHT from ADC using the transfer table (all installations need this) */ 00092 if(TRUE){ /* If CHT connected */ 00093 localCHT = CHTTransferTable[ADCArrays->CHT]; 00094 }else if(FALSE){ /* Configured to be read From ADC as dashpot */ 00095 /* Transfer the ADC reading to an engine temperature in a reasonable way */ 00096 localCHT = (ADCArrays->CHT * 10) + freezingPoint; /* 0 ADC = 0C = 273.15K = 27315, 1023 ADC = 102.3C = 375.45K = 37545 */ 00097 }else if(FALSE){ /* Configured to be fixed value */ 00098 /* Get the preferred CHT figure from configuration settings */ 00099 localCHT = fixedConfigs2.sensorPresets.presetCHT; 00100 }else{ /* Fail safe if config is broken */ 00101 /* Default to normal running temperature of 85C/358K */ 00102 localCHT = runningTemperature; 00103 /* If anyone is listening, let them know something is wrong */ 00104 sendErrorIfClear(CHT_NOT_CONFIGURED_CODE); 00105 } 00106 00107 00108 unsigned short localIAT; 00109 /* Get IAT from ADC using the transfer table (all installations need this) */ 00110 if(TRUE){ /* If IAT connected */ /* using false here causes iat to default to room temp, useful with heatsoaked OEM sensors like the Volvo's... */ 00111 localIAT = IATTransferTable[ADCArrays->IAT]; 00112 }else if(FALSE){ /* Configured to be read From ADC as dashpot */ 00113 /* Transfer the ADC reading to an air temperature in a reasonable way */ 00114 localIAT = (ADCArrays->IAT * 10) + 27315; /* 0 ADC = 0C = 273.15K = 27315, 1023 ADC = 102.3C = 375.45K = 37545 */ 00115 }else if(FALSE){ /* Configured to be fixed value */ 00116 /* Get the preferred IAT figure from configuration settings */ 00117 localIAT = fixedConfigs2.sensorPresets.presetIAT; 00118 }else{ /* Fail safe if config is broken */ 00119 /* Default to normal air temperature of 20C/293K */ 00120 localIAT = roomTemperature; 00121 /* If anyone is listening, let them know something is wrong */ 00122 sendErrorIfClear(IAT_NOT_CONFIGURED_CODE); 00123 } 00124 00125 00126 unsigned short localMAT; 00127 /* Determine the MAT reading for future calculations */ 00128 if(TRUE){ /* If MAT sensor is connected */ 00129 /* Get MAT from ADC using same transfer table as IAT (too much space to waste on having two) */ 00130 localMAT = IATTransferTable[ADCArrays->MAT]; 00131 }else if(FALSE){ /* Configured to be fixed value */ 00132 /* Get the preferred MAT figure from configuration settings */ 00133 localMAT = fixedConfigs2.sensorPresets.presetMAT; 00134 }else{ /* Fail safe if config is broken */ 00135 /* If not, default to same value as IAT */ 00136 localMAT = localIAT; 00137 /* If anyone is listening, let them know something is wrong */ 00138 sendErrorIfClear(MAT_NOT_CONFIGURED_CODE); 00139 } 00140 00141 00142 unsigned short localMAP; 00143 unsigned short localIAP; 00144 /* Determine the MAP pressure to use for future calculations */ 00145 if(TRUE){ /* If MAP sensor is connected */ 00146 /* get MAP from ADC using transfer variables */ 00147 localMAP = (((unsigned long)ADCArrays->MAP * fixedConfigs2.sensorRanges.MAPRange) / ADC_DIVISIONS) + fixedConfigs2.sensorRanges.MAPMinimum; 00148 if(TRUE){ /* If Intercooler boost sensor connected */ 00149 /* Get IAP from ADC using the same transfer variables as they both need to read the same range */ 00150 localIAP = (((unsigned long)ADCArrays->IAP * fixedConfigs2.sensorRanges.MAPRange) / ADC_DIVISIONS) + fixedConfigs2.sensorRanges.MAPMinimum; 00151 } 00152 }else if(FALSE){ /* Configured for MAP to imitate TPS signal */ 00153 /* Get MAP from TPS via conversion */ 00154 localMAP = (((unsigned long)boundedTPSADC * TPSMAPRange) / TPSADCRange) + fixedConfigs2.sensorRanges.TPSClosedMAP; 00155 }else if(FALSE){ /* Configured for dash potentiometer on ADC */ 00156 /* Get MAP from ADC via conversion to internal kPa figure where 1023ADC = 655kPa */ 00157 localMAP = ADCArrays->MAP << 6; 00158 if(TRUE){ /* If Intercooler boost sensor enabled */ 00159 /* Get IAP from ADC via conversion to internal kPa figure where 1023ADC = 655kPa */ 00160 localIAP = ADCArrays->IAP << 6; 00161 } 00162 }else if(FALSE){ /* Configured for fixed MAP from config */ 00163 /* Get the preferred MAP figure from configuration settings */ 00164 localMAP = fixedConfigs2.sensorPresets.presetMAP; 00165 }else{ /* Fail safe if config is broken */ 00166 /* Default to zero to nulify all other calcs and effectively cut fuel */ 00167 localMAP = 0; 00168 /* If anyone is listening, let them know something is wrong */ 00169 sendErrorIfClear(MAP_NOT_CONFIGURED_CODE); // or maybe queue it? 00170 } 00171 00172 00173 /* Determine MAF variable if required */ 00174 unsigned short localMAF = 0; // Default to zero as it is not required for anything except main PW calcs optionally 00175 if(TRUE){ 00176 localMAF = MAFTransferTable[ADCArrays->MAF]; 00177 } 00178 00179 unsigned short localAAP; 00180 /* Determine the Atmospheric pressure to use for future calculations */ 00181 if(TRUE){ /* Configured for second sensor to read AAP */ 00182 /* get AAP from ADC using separate vars to allow 115kPa sensor etc to be used */ 00183 localAAP = (((unsigned long)ADCArrays->AAP * fixedConfigs2.sensorRanges.AAPRange) / ADC_DIVISIONS) + fixedConfigs2.sensorRanges.AAPMinimum; 00184 }else if(FALSE){ /* Configured for dash potentiometer on ADC */ 00185 /* Get AAP from ADC via conversion to internal kPa figure where 1023ADC = 102.3kPa */ 00186 localAAP = ADCArrays->AAP * 10; 00187 }else if(FALSE){ /* Configured for fixed AAP reading from pre start */ 00188 /* Get the AAP reading as saved during startup */ 00189 localAAP = bootTimeAAP; /* This is populated pre start up */ 00190 }else if(FALSE){ /* Configured for fixed AAP from config */ 00191 /* Get the preferred AAP figure from configuration settings */ 00192 localAAP = fixedConfigs2.sensorPresets.presetAAP; 00193 }else{ /* Fail safe if config is broken */ 00194 /* Default to sea level */ 00195 localAAP = seaLevelKPa; /* 100kPa */ 00196 /* If anyone is listening, let them know something is wrong */ 00197 sendErrorIfClear(AAP_NOT_CONFIGURED_CODE); // or maybe queue it? 00198 } 00199 00200 00201 unsigned short localEGO; 00202 /* Get main Lambda reading */ 00203 if(TRUE){ /* If WBO2-1 is connected */ 00204 /* Get EGO from ADCs using transfer variables */ 00205 localEGO = (((unsigned long)ADCArrays->EGO * fixedConfigs2.sensorRanges.EGORange) / ADC_DIVISIONS) + fixedConfigs2.sensorRanges.EGOMinimum; 00206 }else if(FALSE){ /* Configured for fixed EGO from config */ 00207 /* Get the preferred EGO figure from configuration settings */ 00208 localEGO = fixedConfigs2.sensorPresets.presetEGO; 00209 }else{ /* Default value if not connected incase other things are misconfigured */ 00210 /* Default to stoichiometric */ 00211 localEGO = stoichiometricLambda; /* EGO / 32768 = Lambda */ 00212 /* If anyone is listening, let them know something is wrong */ 00213 sendErrorIfClear(EGO_NOT_CONFIGURED_CODE); // or maybe queue it? 00214 } 00215 00216 00217 unsigned short localEGO2; 00218 /* Get second Lambda reading */ 00219 if(TRUE){ /* If WBO2-2 is connected */ 00220 /* Get EGO2 from ADCs using same transfer variables as EGO */ 00221 localEGO2 = (((unsigned long)ADCArrays->EGO2 * fixedConfigs2.sensorRanges.EGORange) / ADC_DIVISIONS) + fixedConfigs2.sensorRanges.EGOMinimum; 00222 }else if(FALSE){ /* Configured for fixed EGO2 from config */ 00223 /* Get the preferred EGO2 figure from configuration settings */ 00224 localEGO2 = fixedConfigs2.sensorPresets.presetEGO2; 00225 }else{ /* Default value if not connected incase other things are misconfigured */ 00226 /* Default to stoichiometric */ 00227 localEGO2 = stoichiometricLambda; 00228 /* If anyone is listening, let them know something is wrong */ 00229 sendErrorIfClear(EGO2_NOT_CONFIGURED_CODE); // or maybe queue it? 00230 } 00231 00232 00233 unsigned short localTPS; 00234 /* Get TPS percentage */ 00235 if(TRUE){ /* If TPS is connected */ 00236 /* Get TPS from ADC no need to add TPS min as we know it is zero by definition */ 00237 localTPS = ((unsigned long)boundedTPSADC * TPS_RANGE_MAX) / TPSADCRange; 00238 }else if(FALSE){ /* Configured for TPS to imitate MAP signal */ 00239 /* Get TPS from MAP via conversion */ 00240 /* Box MAP signal down */ 00241 if(localTPS > fixedConfigs2.sensorRanges.TPSOpenMAP){ /* Greater than ~95kPa */ 00242 localTPS = TPS_RANGE_MAX; /* 64000/640 = 100% */ 00243 }else if(localTPS < fixedConfigs2.sensorRanges.TPSClosedMAP){ /* Less than ~30kPa */ 00244 localTPS = 0; 00245 }else{ /* Scale MAP range to TPS range */ 00246 localTPS = localMAP - fixedConfigs2.sensorRanges.TPSClosedMAP; 00247 } 00248 // get TPS from MAP no need to add TPS min as we know it is zero by definition 00249 localTPS = ((unsigned long)localTPS * TPS_RANGE_MAX) / (fixedConfigs2.sensorRanges.TPSOpenMAP - fixedConfigs2.sensorRanges.TPSClosedMAP); 00250 }else if(FALSE){ /* Configured for dash potentiometer on ADC */ 00251 /* Get TPS from ADC as shown : 1023 ADC = 100%, 0 ADC = 0% */ 00252 localTPS = ((unsigned long)ADCArrays->TPS * TPS_RANGE_MAX) / ADC_DIVISIONS; 00253 }else if(FALSE){ /* Configured for fixed TPS from config */ 00254 /* Get the preferred TPS figure from configuration settings */ 00255 localTPS = fixedConfigs2.sensorPresets.presetTPS; 00256 }else{ /* Fail safe if config is broken */ 00257 /* Default to 50% to not trigger any WOT or CT conditions */ 00258 localTPS = halfThrottle; 00259 /* If anyone is listening, let them know something is wrong */ 00260 sendErrorIfClear(TPS_NOT_CONFIGURED_CODE); // or maybe queue it? 00261 } 00262 00263 00264 /* Get RPM by locking out ISRs for a second and grabbing the Tooth logging data */ 00265 //atomic start 00266 // copy rpm data 00267 //atomic end 00268 00269 // Calculate RPM and delta RPM and delta delta RPM from data recorded 00270 CoreVars->RPM = *RPM; // temporary!! 00271 unsigned short localDRPM = 0; 00272 unsigned short localDDRPM = 0; 00273 00274 00275 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 00276 00277 00278 00279 00280 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&& Average the variables as per the configuration &&&&&&&&&&&&&&&&&&&&&&&&&&*/ 00281 /* Strictly speaking only the primary variables need to be averaged. After that, the derived ones are */ 00282 /* already averaged in a way. However, there may be some advantage to some short term averaging on the */ 00283 /* derived ones also, so it is something to look into later. */ 00284 00286 00287 // newVal var word ' the value from the ADC 00288 // smoothed var word ' a nicely smoothed result 00289 // 00290 // if newval > smoothed then 00291 // smoothed = smoothed + (newval - smoothed)/alpha 00292 // else 00293 // smoothed = smoothed - (smoothed - newval)/alpha 00294 // endif 00295 00296 // from : http://www.tigoe.net/pcomp/code/category/code/arduinowiring/41 00297 00298 // for now just copy them in. 00299 CoreVars->IAT = localIAT; 00300 CoreVars->CHT = localCHT; 00301 CoreVars->TPS = localTPS; 00302 CoreVars->EGO = localEGO; 00303 CoreVars->BRV = localBRV; 00304 CoreVars->MAP = localMAP; 00305 CoreVars->AAP = localAAP; 00306 CoreVars->MAT = localMAT; 00307 00308 CoreVars->EGO2 = localEGO2; 00309 CoreVars->IAP = localIAP; 00310 CoreVars->MAF = localMAF; 00311 CoreVars->DRPM = localDRPM; 00312 CoreVars->DDRPM = localDDRPM; 00313 00314 // later... 00315 unsigned short i; 00316 for(i=0;i<CORE_VARS_LENGTH;i++){ // TODO 00317 /* Perform averaging on all primary variables as per the configuration array */ 00318 // get old value(s) 00319 // process new and old to produce result based on config array value */ 00320 // assign result to old value holder 00321 } // TODO 00322 00323 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ 00324 }