- Reading and averaging ADCs intelligently (one function with parameters for all inputs and possibly all vars to ensure minimal duplication)
- Use of transfer functions and tables to convert raw ADC readings to actual temperatures and pressures etc
- Ranges of inputs and outputs as it relates to maths and intermediate values etc
- Which correction tables are going to be included from the start and how they will be included
- How to do a master fuel trim setting
- How to combine the things we know about flow and combustion volume (rotaries/etc also, hence not cylinder) into fuel demand
- Other things?
- The ADCs are all to be read for each and every combustion event, and also on a timeout for when the engine isn't running.
- Some smoothing of the raw readings would be good to be consistent across all inputs (the smoothing should be tunable per input though)
- Should the smoothing be done in the ISR where the readings are taken or later in the fuel calcs section. If the former, needs to be fast, if the latter, we will lose data points inconsistently with RPM.
- Transfer functions should be in the form of a free table with appropriate ranges for each type of sensor and at an appropriate size to create a smooth enough curve
- OR should some of them be done with mathematic formulas with appropriate coefficients to manipulate the shape?
- The variables we need should emerge from this step appropriately scaled to make best use of the range they have and bit space they have
I've approached this from the perspective of minimising the range of sensor to realistic figures for all engines, and maximising that range inside the 16 bit variable. This approach could be wrong in that it means you can only put two 16 bit vars together before you need to divide back down again to avoid 32bit overflow. Thoughts?
- RPM = Revolutions Per Minute : 0 - 32768 RPM (0.5 RPM (/2)) [Will going with half rpm increments and 32k complicate the maths?]
- CHT = Coolant / Head Temperature : 0.0 - 655.35 K (0.01 Kelvin (/100)) [No one ever gets their engine hotter or colder than that, including air cooled guys. We are better off in degrees K so that we don't have negative numbers. Air coolers say 600F is the max they want to be able to watch.]
- MAP = Manifold Absolute Pressure : 0.0 - 655.35 (0.01 kPa (/100)) [Up to ~80psi of boost. Going with a /2 as well would limit max boost to 33psi which is marginal for a serious setup.]
- AAP = Atmospheric Absolute Barometric Pressure : 0.0 - 655.35 kPa (0.01 kPa (/100)) [Use same range as normal MAP despite not needing it.]
- IAT= Inlet Air Temperature : 0.0 - 655.35 K (0.01 Kelvin (/100)) [Be consistent with CHT despite never needing those figures.]
- MAT = Manifold Air Temperature : 0.0 - 655.35 K (0.01 Kelvin (/100)) [Corrected IAT, calculated from other values and used in the actual calculation.]
- TPS = Throttle Position Sensor : 0.0 - 102.398438 % (0.0015625 % (/640)) [This is equivalent to dividing the raw reading by 10. IE, bit shifted 6 places to the right and divided by 10 for the value.]
- EGO = Exhaust Gas Oxygen : 0.0 - 1.99996948 Lambda (0.0000305175781 Lambda (/32768)) [Not using AFR keeps it compatible with all fuel types.]
- LT = Lambda Target : 0.0 - 1.99996948 lambda (0.0000305175781 (/32768)) [Not using AFR keeps it compatible with all fuel types.]
- VE = Volumetric Efficiency : 0.0 - 127.998047 % (0.001953125 % (/512) [We want this close to 100% for the maximum range, but with some headroom.]
- PL = Percent Load : 0.0 - 655.35 % (0.01% (/100)) [Needs to match largest load type (MAP, TPS, MAF, etc)]
- MFT = Master Fuel Trim : -12.8 - 12.7 % (0.1% (/10)) [The range here doesn't need to be particularly large, perhaps +/- 10% or so and 8 bits of resolution. Is this enough?]
- PCFT = Per Cylinder Fuel Trim : -12.8 - 12.7 % (0.1% (/10)) [The range here doesn't need to be particularly large, perhaps +/- 10% or so and 8 bits of resolution. This is enough.]
- FPW = Fuel Pulse Width : 0.0 OR Minimum - Maximum OR 52428us (0.8us (*0.8)) [This one is fixed for now, though we COULD reduce or increase the resolution and the opposite for range if we wanted, though it should never ever be needed. It is OK for the calculation to output something between 0 and min and it will be pushed back to either end of that scale, probably requested = min, not zero, and same at the top end, obviously to max though as you can't have more than max!]
- EPW = Electrical Pulse Width : 0.0 OR Minimum - Maximum OR 52428us (0.8us (*0.8)) [Ditto]
- IDT = Injector Dead Time : 0.0 - 52428us (0.8us (*0.8)) [This needs to be in the region of 2000us/2ms max at normal operating voltage, but perhaps 3x larger at lower voltages. It will only be a small table, so 16bits per entry is fine.]
- BRV = Battery Reference Voltage : 0.0 - 65.535 V (0.001V (/1000)) [Measurement range will probably be 0 - 30v or so but the variable should be tweakable to handle a 24V system with ease and appropriate hardware. We don't want to cap the measurement such that real high figures with a failed alternator or something are outside it's range, BUT, we do want to keep the range minimal to maximise resolution from the ADC. 0-5V = 0 - 1023 raw ADC scaled externally with resistors : the half is not enough, 1/3 is enough for perfect conditions, 1/4 = 20v which is marginal for surge type conditions, but might be the best option. Double this for a 24v system.]
- ETE/CHE = Engine Temperature Enrichment / Coolant/Head Enrichment : (+) 0 - 655 % (enough?) [I'm not sure how much extra fuel the engine needs when it is cold worst case, help me out. I know that maybe 10% would be enough for over temp enrichment, and 0% for in range (maybe 80 - 100C for a water cooler)]
- PSE = Post Start Enrichment : 0 - 655 % (enough?) [How much extra fuel do your engines need post start?]
- TFC/DFC = Transient/Delta Fuel Correction : +/- 327 % (enough?) [This will be a single value having a source of many potential algorithms. This is only necessary for slow readings and inaccurate calculations of readings. In a perfect system (which we are aiming to approximate) it wouldn't be required at all]
- PCV = Per Cylinder Volume : 2.0 max = 32768 divisor and nothing will come close : http://en.wikipedia.org/wiki/List_of_au ... splacement and http://en.wikipedia.org/wiki/Single_cyl ... der_engine
- IFPC = Injector Flow Per Cylinder : biggest I could find was 1.6l/min so that could be a goer, THOUGH, we should be using mass it is fairly approximate anyway. 2.0 should be fine so divisor of 32768 is good here too
- etc. (what have I forgotten?)
- RPM : Calculated directly by the engine position/rpm interpretter/decoder.
- CHT : Transfer from raw ADC required. Options are : 8x2 table of user tunable conversion values OR mathematical formula with coefficients OR ?
- MAP : Linear with Max and Min ADC > kPa pairs.
- AAP : Linear with Max and Min ADC > kPa pairs. Obtained from separate sensor, or turn on time/rpm = zero /tps = open etc.
- IAT : Transfer from raw ADC required. Options are : 8x2 table of user tunable conversion values OR mathematical formula with coefficients OR ?
- MAT : Transfer might be just (MAT = IAT) or involve something more complex such as deriving from time after start and coolant temp at start and current airflow (rpm/load) etc.
- TPS : Linear with Max and Min ADC > % pairs.
- EGO : Linear with Max and Min ADC > Lambda pairs.
- LT : From lookup table of some size or other (probably lower res and size than the main tables 8x8x8bit perhaps)
- VE : From lookup function of some size and sort or other (possibly 24x24 for good boost resolution and mapping to zero RPM.
- PL : Taken straight from one of several load sources : MAP, TPS, MAF, ABP x MAP, etc
- MFT : From single cell value of 8 bits signed.
- PCFT : From single cell values of 8 bits signed.
- FPW : The single output of all the fueling calculations!
- IDT : From a lookup table of perhaps 8x2x16bits such that the user specifies the normal voltage point and behaviour on both sides themselves.
- BRV : Linear with Max and Min ADC > Voltage pairs. (min will usually be zero, but leave it open to be changed anyway)
- CHE : This should be a U shaped curve such that at low temps the engine runs rich (because it needs to), and at high temps it runs rich (to cool things off) and not affect things at all in the middle, so perhaps flat in the middle. It should be a user trimable table. Possibly with a % effectiveness table on rpm/load too? (non linear through load/rpm space?) OR alternatively two 8x8 tables, one for coolant vs rpm, and one for coolant vs load. Each has it's advantage, hard to know which is better.
- PSE : From lookup table of perhaps 8x2x16bit to allow curve over time of the users choice.
- TFC/DFC : From output of some algorithm or other. Many possible options, delta TPS, delta MAP, wall wetting, delta RPM etc.
- Read ADCs
- Average/smooth ADCs
- Transfer ADCs to usable values via various methods
- Look up the VE from the load and RPM
- Calculate the basic PW from all variables
- Calculate corrections and apply them one by one
- Add the opening time
- Schedule the start of INJECTION (not the start of the electrical pulse) for the angle specified by the tuner.
- What have I forgotten?
- ADCs will be read once for each combustion event syncronously (all of them). This does not mean we are stuck with this, switching sampling methods for different sensors should be simple. All of them can also be sampled at various other frequencies and a particular variable can be generated from any source.
- ADCs should probably be averaged right there and then in the ISR where they are read in otherwise samples will be taken and lost.
- When ADCs are read, a "do calcs now" flag is set. This is picked up by the calc section which only runs when the flag is set and clears the flag once it starts to run. The effect of this is that if a new sample comes in while calculating the calculation will be run again on the next iteration. If new vars don't come in, other things can be done instead and the latency to doing the calcs again will be lower for it.
- Generate the variables from ADCs with lookups etc
- For CHT and IAT we will get a 0 - 1023 10 bit number representing the voltage at the ADC. The ADC pin will be connected to a pull up and one side of a thermistor sensor. The other side will be connected to ground. In the case of the common ND sensor running temperature means a very low resistance across the sensor : 80C = 340 Ohms. At cold temps the resistance is very high : -10C = 10k Ohm. The middle of the curve rests at around the 2k region, so if we use that we will get 4.1666V and around 800ADC reading for -10C and 0.73V and 150ADC reading for 80C. Now, if we are to use my suggested scale of degrees K then our temps are actually 263K and 353K at each end of our range. 26300 / 150 = 175 coefficient for one end of the transfer scale and 35300 / 800 = 44 coefficient for the other. This indicates to me that the tuning table for transfer would have much worse resolution if we reduced the used range of the output vars. Using degrees K makes this better, not worse. This will be looked up from an array of values that are pre calculated on a PC with FreeTherm or similar.
- AAP/MAP/BRV/EGO : Linear interpolation from max reading and max adc to min reading and min adc
- TPS : Similar to above, but boxed between max and min readings first.
- etc
- etc, help me fill in the blanks.