Injector Staging Brainstorming Page
Current CVS implementation (since Aug 21, 2004) is from the stone-age. It will fire the configured injector FET's above a given throttle position and/or MAP value. Pulse rate is also configurable (but currently unusable).
config.inj_stage2_rate - Secondary injectors firing pulsewidth rate. Give it in 0.4 percents relative to primaries. Because a typo now 0x00 means 100%, 0xFF means 200%. (Will be corrected soon to 0-100%)
config.inj_stage2_start_tps - Secondary injectors will fire only above this engine.tps value
config.inj_stage2_start_map - Secondary injectors will fire only above this manifold pressure (given in kPas)
Define INJECTOR_STAGING in my_make, and (optionally) SECONDARY_INJ_CHANNELS_NUM (default: 1). Then adjust the last SECONDARY_INJ_CHANNELS_NUM element (in standard case the last one) in the h[0] table to the output FET of the second-stage injectors. See GenBoard/Manual/Config/HwMap for details.
So\n
inj_stage2_rate=00 inj_stage2_start_tps=00 inj_stage2_start_map=78
and
h[0] = xx xx xx xx xx xx xx 02
Will fire the secondary injectors at Injector channel "B" above 0.2 bar boost with the same pw as the primaries.
Note: Use at your own risk! Off engine-tests reveals a bug in the implementation, which cause the secondary channels "lockup" (FETs never switched off) sometimes under extreme conditions. Will be fixed soon.
What is staging?
Staging is a method to control fuel flow into engine separating the existing injectors into two sets. Primary injectors are used all the time when the engine is running, and the secondary set used only when the engine needs more fuel. The secondary set of injectors can be run in batch mode (but PWM-ing is often useful).
Staging also can be used in common turbocharged engine configurations to achieve finer fuel control in vacuum mode (stage 1).
Special and rare staging setups
An advanced setup with one injector that spray the valve and one that spray the throat would benefit from a full sequential configuration where the balance between the injectors can be mapped. It would even benefit from different timing on the two injectors!
But 99% of all staged setups is only built to be able to use cheap injectors that is already available, some is built to improve resolution for old engine management systems with bad injector control.
I definitely think that it is overkill to spend time on the mega advanced configurations, AFAIK only high end engine management systems support this. High end starts at around 10000euro.
It's definitely no design target for any board: they can later be supported with 2 (networked) controllers and some software, of course.
Discussion terminology - shorthands
- stage0: fuelcut
- stage1: only primary set of injectors (usually smaller and port injectors)
- stage12: primary AND secondary set of injectors
- stage2: only secondary set of injectors
questions:
stage2 is not allowed in many setups, and it's a question if it needs to be supported at all.
For stage12 the question is if there is a point for different pulsewidth for the 2 sets. They have to max out simultaneously (obviously) and IMHO the pulsewidth better be the same for both sets; otherwise the shorter pulsewidth would tend to have injector opening issues, and would also mean more config variables. But if different fuel is used in 2nd set... or stage1 is determined by alien ECU...
transition requires special consideration in any case. Maybe insert 1 cycle with special transition pulsewidths ? Hysteresys can be used to decrease the frequency of transitions. Proper transition between stage1 and stage2 would be extremely hard (for the end user to configure precisely, according to his engine-aerodynamics).
The most tough case
A 15000 RPM engine will still have 8ms to inject. Let's examine the switching threshold between stage1 and stage12: if stage1 duty is 80% the stage12 pw would be appr 3 msec (assuming slightly bigger 2nd set): this probably cannot be split to 4 shorter squirts.\n
Example: Primary injectors: 300cc Secondary injectors: 450cc pri_plus_sec =750cc pri_const=450/pri_plus_sec=0.6 sec_const=300/pri_plus_sec=0.4 // calculated_pw is what we call pw today. // pri_pw is the primary injectors pw // sec_pw is the secondary injectors pw. If calculated_pw>75 //75% duty of course Enable_2nd_stage_inj=1; else Enable_2nd_stage_inj=0; If Enable_2nd_stage_inj{ pri_pw=calculated_pw*pri_const; sec_pw=calculated_pw*sec_const; } else{ pri_pw=calculated_pw; sec_pw=0; }
Surely, the current code requires rework (eg. remove compile-time condition).
The rest of the comments is about the cvs version (August 22nd, 2004)
The tps condition is useless. The kpa is better, but it should be based on stage1 duty. Like stage2 should activate when stage1 would be > 80..85% duty.
config variables:
- max allowed stage1 duty 50..100% (16 steps)
- ratio: how much of the fuel should go to second set (in stage12) - normally same pulsewidth for the 2 sets
- ratio of stage2 fuel_req compared to stage1. 1..ff. 00 means that staging is off. This should support at least stage2 flow = 3 * flow of stage one. Support also needed for stage2 flow < stage1 (even though it's uncommon).
- injopen (+battfac + injocfuel) for stage2: since stage2 is never used alone, and never with very short pulsewidth, these can be replaced by a simple constant (~offset).
- locking for the injector pw values: with stage12, this is not critical, but with stage2 a mode change could be dangerous if stage1 reads the old value while stage2 the new value (smooth transition helps of course)
Let's see the ideal solution. This is not from an implementation point of view, but from user's. We have some inputs:
- fuelamount to inject (from fuelcalc, so it contains lambda, and total enrichment..)
- battery voltage
- available fuel: if second set's tank is empty, decreasing fuel amount when reaching stage12 is dummy.
- fuel price (if using BiFuel)
- heat stress (fuel also cools). Fortunately this is in close relationship with fuelamount (actually fuelamount * RPM) We would like to not mix cooling into the fuel calc, since in the common case it is simply adjusted with the lambdacorr table. But BiFuel would at least desire 2 separate cooling-enrichment (lambdacorr table) and injecting 0 Joule water with the second set the proper way requires that cooling is considered here, not in the lambdacorr. (lambdacorr does not apply to water, while water really does cool).
we need:
- stage1 pw
- stage2 pw
it is obvious, that we need to do simplifications, as 3-dimension table is hard to store or tune. As the battery voltage only effects opening (and closing), that is already implemented.
If we have 2 req_fuels (which is in msec dimension, so it also involves AFR of the given fuel mix) and 2 cooling-variables, a userspace routine could optimize to have 2 pw-s that has exact fuel and close to required cooling effect.
A few words about duty
Injectors could be driven by standard square pulse signal, or PWM signal. Open it all in the same time, alternating or sequentially. But how to define duty?
duty = topentime * 100% / ttotal.
Where ttotal is the time between two injector activation events (RPM and injector configuration dependent). Duty should be always under 100% because the injectors aren't planned to being open continously for a long period of time.
Calculate injector duty from the following formula (correct it, if you found mistakes):
duty = (calc_pw * squirts_number * 100%) / crank_time.
Where the squirts_number is the number of activations of a specific injector port in one crank rotation (crank_time).
I suggest to use the calc_pw independent pw_stagelimit:
pw_stagelimit = crank_time * stage1_maxduty / squirts_number.
Where the stage1_maxduty and squirts_number are both tuner configurable constants. Can we put these in one, wisely selected config variable?
External sites dealing with the subject:
- RX7 injector staging method: http://www.wvinter.net/~flanham/wlanham/rx7/fuel/staging.html
- Rotary/RX7 injector upgrade: http://www.scuderiaciriani.com/rx7/injector_upgrade.html