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:
This graph shows which files directly or indirectly include this file:

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 39 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 59 of file coreVarsGenerator.c.

Referenced by main().

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

Generated on Sat Oct 16 21:29:05 2010 for FreeEMS by  doxygen 1.6.3