1 /* FreeEMS - the open source engine management system
3 * Copyright 2008-2013 Fred Cooke
5 * This file is part of the FreeEMS project.
7 * FreeEMS software is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * FreeEMS software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with any FreeEMS software. If not, see http://www.gnu.org/licenses/
20 * We ask that if you make any changes to this file you email them upstream to
21 * us at admin(at)diyefi(dot)org or, even better, fork the code on github.com!
23 * Thank you for choosing FreeEMS to run your engine!
29 * @ingroup measurementsAndCalculations
31 * @brief Generate and average the core variables.
33 * This file contains the function that transfers the raw ADC values to actual
34 * physical measurements and averages them.
38 #define COREVARSGENERATOR_C
39 #include "inc/freeEMS.h"
40 #include "inc/commsCore.h"
41 #include "inc/coreVarsGenerator.h"
42 #include "inc/decoderInterface.h"
46 * Calculate and obtain the core variables. Each raw ADC value is converted to a
47 * usable measurement via a variety of methods. They are then stored in a struct
48 * and used as input to the next phase.
50 void generateCoreVars(){
51 // Battery Reference Voltage
52 unsigned short localBRV
;
53 if(!(fixedConfigs2
.sensorSources
.BRV
)){
54 localBRV
= (((unsigned long)ADCBuffers
->BRV
* fixedConfigs2
.sensorRanges
.BRVRange
) / ADC_DIVISIONS
) + fixedConfigs2
.sensorRanges
.BRVMinimum
;
55 }else if(fixedConfigs2
.sensorSources
.BRV
== SOURCE_PRESET
){
56 localBRV
= fixedConfigs2
.sensorPresets
.presetBRV
;
57 }else if(fixedConfigs2
.sensorSources
.BRV
== SOURCE_LINEAR
){
58 localBRV
= (ADCBuffers
->BRV
* 14) + VOLTS(7.2); // 0 ADC = 7.2V, 1023 ADC = 21.522C
59 }else{ // Default to normal alternator charging voltage 14.4V
60 localBRV
= VOLTS(14.4);
63 // Coolant/Head Temperature
64 unsigned short localCHT
;
65 if(!(fixedConfigs2
.sensorSources
.CHT
)){
66 localCHT
= CHTTransferTable
[ADCBuffers
->CHT
];
67 }else if(fixedConfigs2
.sensorSources
.CHT
== SOURCE_PRESET
){
68 localCHT
= fixedConfigs2
.sensorPresets
.presetCHT
;
69 }else if(fixedConfigs2
.sensorSources
.CHT
== SOURCE_LINEAR
){
70 localCHT
= (ADCBuffers
->CHT
* 10) + DEGREES_C(0); // 0 ADC = 0C, 1023 ADC = 102.3C
71 }else{ // Default to slightly cold and therefore rich: 65C
72 localCHT
= DEGREES_C(65);
75 // Inlet Air Temperature
76 unsigned short localIAT
;
77 if(!(fixedConfigs2
.sensorSources
.IAT
)){
78 localIAT
= IATTransferTable
[ADCBuffers
->IAT
];
79 }else if(fixedConfigs2
.sensorSources
.IAT
== SOURCE_PRESET
){
80 localIAT
= fixedConfigs2
.sensorPresets
.presetIAT
;
81 }else if(fixedConfigs2
.sensorSources
.IAT
== SOURCE_LINEAR
){
82 localIAT
= (ADCBuffers
->IAT
* 10) + DEGREES_C(0); // 0 ADC = 0C, 1023 ADC = 102.3C
83 }else{ // Default to room temperature
84 localIAT
= DEGREES_C(20);
87 // Throttle Position Sensor
88 /* Bound the TPS ADC reading and shift it to start at zero */
89 unsigned short unboundedTPSADC
= ADCBuffers
->TPS
;
90 unsigned short boundedTPSADC
= 0;
91 if(unboundedTPSADC
> fixedConfigs2
.sensorRanges
.TPSMaximumADC
){
92 boundedTPSADC
= TPSADCRange
;
93 }else if(unboundedTPSADC
> fixedConfigs2
.sensorRanges
.TPSMinimumADC
){
94 boundedTPSADC
= unboundedTPSADC
- fixedConfigs2
.sensorRanges
.TPSMinimumADC
;
97 /* Get TPS from ADC no need to add TPS min as we know it is zero by definition */
98 unsigned short localTPS
= ((unsigned long)boundedTPSADC
* PERCENT(100)) / TPSADCRange
;
99 // TODO fail safe mode, only if on the ADC rails AND configured to do so
100 // Default to a low value that will get you home if you are in Alpha-N mode
103 /* Get RPM by locking out ISRs for a second and grabbing the Tooth logging data */
108 // Calculate RPM and delta RPM and delta delta RPM from data recorded
109 if(*ticksPerDegree
!= 0){
110 CoreVars
->RPM
= (unsigned short)(degreeTicksPerMinute
/ *ticksPerDegree
);
115 CoreVars
->DRPM
= *ticksPerDegree
;
116 // unsigned short localDRPM = 0;
117 // unsigned short localDDRPM = 0;
120 // TODO This might get done somewhere else, separation of concerns, etc
121 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&& Average the variables as per the configuration &&&&&&&&&&&&&&&&&&&&&&&&&&*/
122 /* Strictly speaking only the primary variables need to be averaged. After that, the derived ones are */
123 /* already averaged in a way. However, there may be some advantage to some short term averaging on the */
124 /* derived ones also, so it is something to look into later. */
126 /// @todo TODO average the generated values here
128 // newVal var word ' the value from the ADC
129 // smoothed var word ' a nicely smoothed result
131 // if newval > smoothed then
132 // smoothed = smoothed + (newval - smoothed)/alpha
134 // smoothed = smoothed - (smoothed - newval)/alpha
137 // from : http://www.tigoe.net/pcomp/code/category/code/arduinowiring/41
139 // for now just copy them in.
140 CoreVars
->BRV
= localBRV
;
141 CoreVars
->CHT
= localCHT
;
142 CoreVars
->IAT
= localIAT
;
143 CoreVars
->TPS
= localTPS
;
144 CoreVars
->EGO
= (((unsigned long)ADCBuffers
->EGO
* fixedConfigs2
.sensorRanges
.EGORange
) / ADC_DIVISIONS
) + fixedConfigs2
.sensorRanges
.EGOMinimum
;
145 CoreVars
->MAP
= (((unsigned long)ADCBuffers
->MAP
* fixedConfigs2
.sensorRanges
.MAPRange
) / ADC_DIVISIONS
) + fixedConfigs2
.sensorRanges
.MAPMinimum
;
146 CoreVars
->AAP
= (((unsigned long)ADCBuffers
->AAP
* fixedConfigs2
.sensorRanges
.AAPRange
) / ADC_DIVISIONS
) + fixedConfigs2
.sensorRanges
.AAPMinimum
;
147 CoreVars
->MAT
= IATTransferTable
[ADCBuffers
->MAT
];
150 // Not actually used, feed raw values for now TODO migrate these to a SpecialVars struct or similar not included in default datalog
151 CoreVars
->EGO2
= ADCBuffers
->EGO2
;
152 CoreVars
->IAP
= ADCBuffers
->IAP
;
153 CoreVars
->MAF
= MAFTransferTable
[ADCBuffers
->MAF
];
155 // CoreVars->DRPM = localDRPM;
156 // CoreVars->DDRPM = localDDRPM;
157 // CoreVars->DTPS = localDTPS;