coreVarsGenerator.c File Reference

Generate and average the core variables. More...

#include "inc/freeEMS.h"
#include "inc/commsCore.h"
#include "inc/coreVarsGenerator.h"

Include dependency graph for coreVarsGenerator.c:

Go to the source code of this file.

Defines

#define COREVARSGENERATOR_C

Functions

void generateCoreVars ()
 Generate the core variables and average them.


Detailed Description

Generate and average the core variables.

This file contains the function that transfers the raw ADC values to actual physical measurements and averages them.

Author:
Fred Cooke

Definition in file coreVarsGenerator.c.


Define Documentation

#define COREVARSGENERATOR_C

Definition at line 38 of file coreVarsGenerator.c.


Function Documentation

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.

Todo:
TODO incorporate averaging code, right now its a straight copy.

TODO change the way configuration is done and make sure the most common options are after the first if().

TODO add actual configuration options to the fixed config blocks for these items.

Author:
Fred Cooke

Todo:
TODO average the generated values here

Definition at line 57 of file coreVarsGenerator.c.

Referenced by main().

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


Generated on Mon Jan 26 00:16:34 2009 for FreeEMS by  doxygen 1.5.8