|
||||||
| Software Tuning Discuss all software tuning topics. |
![]() |
|
|
Thread Tools | Search this Thread |
|
|
#15 |
|
Senior Member
Join Date: Nov 2021
Drives: 2019 Subaru BRZ
Location: PNW, US
Posts: 109
Thanks: 88
Thanked 88 Times in 46 Posts
Mentioned: 4 Post(s)
Tagged: 0 Thread(s)
|
I uploaded two logs to datazap from this week; learning clearly hasn't stabilized yet, but at least it's not all offset by -4% like my previous round of work. This isn't logs of the actual memory-stored 'learned' LTFT but instead of the 'live' LTFT value, which I assume is more variable than what's stored (as is apparent across multiple driving sessions shown):
LTFT by bucket over time; or, LTFT+STFT by bucket over time, to see total trims. (Very grateful to datazap for scatter+groupby support!) I'll redo these with a couple more fields (CL_OL and MAF) eventually but it's a useful preview. Bucket 5 (low MAF, some PI) is extremely sparse but I somehow managed to get Any Time At All in it, which is surprising, more to research there. Next step, updating logcfg to log the specific fuel trim buckets and identifying precisely how the 4 learning buckets (x2 for DI,PI) tie into the 6 learning buckets (A-F) specified in the Airflow Ranges A/B tables. Closing in on the answer to the original question of the thread at long last
|
|
|
|
|
|
#16 |
|
Senior Member
Join Date: Nov 2021
Drives: 2019 Subaru BRZ
Location: PNW, US
Posts: 109
Thanks: 88
Thanked 88 Times in 46 Posts
Mentioned: 4 Post(s)
Tagged: 0 Thread(s)
|
Alright, I can at least document where and how the LTFT #1 memory buckets are stored and selected. The table defs for the 6 buckets are slightly misleading; the first value isn't used during bucket selection, as far as I can tell.
The LTFT #1 ranges are written as 6 buckets total, stored as the dividing values between each bucket A..F, across two tables A/F Learning #1 Airflow Ranges A/B: Code:
A (max): 1.60 | 5.00 | 12.00 | 20.00 | 60.00 B (mid): 0.80 | 3.40 | 8.50 | 16.00 | 45.00 Code:
C (min): 0.00 | 1.80 | 5.00 | 12.00 | 30.00 The LTFT #1 memory array is 10 buckets total, stored in this pattern (with the corresponding LTFT airflow ranges shown above each column): Code:
A B C D E F
| | | | | |
0 ------------- X1=true & X2=true
| | | | |
1 2 3 4 ----- 0% port injection
| | | | |
5 6 7 8 ----- <70% port injection
|
9 --- >=70% port injection
A B C D E F
The LTFT #1 memory bucket selection proceeds like this order:
Then, the logic determines whether LTFT learning is active:
The logging addresses referred to above are:
Since LTFT array #1 is stored in the pattern { 4 bytes of learning status; 4-byte float }, Tactrix logcfg.txt ends up looking like this: Code:
; mass airflow sensor raw voltage, 0-5V (should not exceed MAF CEL limits)
paramname = MAF_v
paramid = 0xfff845ec ; K00G, or 0xfff843ac
scalingrpn = x,0.000076293945,*
; mass airflow sensor result (g/s) after scaling from 0-5V
paramname = MAF
paramid = 0xfff89470 ; K00G, or 0xfff890d4 ; V00C
isfloat = 1
; unknown boolean values; false=0, true=1+
paramname = X1
paramid = 0xfff892fc ; K00G, or 0xfff88f4c ; V00C
databits = 8
paramname = X2
paramid = 0xfff8aa98 ; K00G, or 0xfff8a7ec ; V00C
databits = 8
; current MAF learning-allowed ranges
paramname = LTFT_Learning_min
paramid = 0xfff8aad0 ; K00G, or 0xfff8a824
isfloat = 1
paramname = LTFT_Learning_max
paramid = 0xfff8aad4 ; K00G, or 0xfff8a828
isfloat = 1
; LTFT learning is allowed? false=0, true=1
paramname = LTFT_Learning
paramid = 0xfff8aae4 ; K00G, or 0xfff8a838 ; V00C
databits = 8
; DI/PI table lookup result after thresholds. for example: 0.7 = 70% port injection.
paramname = DiPi_ratio_result
paramid = 0xfff8a448 ; K00G, or 0xfff8a178 ; V00C
isfloat = 1
; LTFT bucket selected by the airflow min/max logic. 0, 1-4 (PI=0%) or 5-8 (PI<70%), or 9 (PI>=70%).
paramname = LTFT_bucket
paramid = 0xfff8aae0 ; K00G, or 0xfff8a834 ; V00C
databits = 8
; LTFT array #1, 10 buckets of { 4-byte learning status; 4-byte float } each.
;paramname = LTFT1_0L
;paramid = 0xfff80f60 ; K00G, or 0xfff81468 ; V00C
;databits = 16
paramname = LTFT1_0
paramid = 0xfff80f64 ; K00G, or 0xfff8146c ; V00C
isfloat = 1
;paramname = LTFT1_1L
;paramid = 0xfff80f68 ; K00G, or 0xfff81470 ; V00C
;databits = 16
paramname = LTFT1_1
paramid = 0xfff80f6c ; K00G, or 0xfff81474 ; V00C
isfloat = 1
;paramname = LTFT1_2L
;paramid = 0xfff80f70 ; K00G, or 0xfff81478 ; V00C
;databits = 16
paramname = LTFT1_2
paramid = 0xfff80f74 ; K00G, or 0xfff8147c ; V00C
isfloat = 1
;paramname = LTFT1_3L
;paramid = 0xfff80f78 ; K00G, or 0xfff81480 ; V00C
;databits = 16
paramname = LTFT1_3
paramid = 0xfff80f7c ; K00G, or 0xfff81484 ; V00C
isfloat = 1
;paramname = LTFT1_4L
;paramid = 0xfff80f80 ; K00G, or 0xfff81488 ; V00C
;databits = 16
paramname = LTFT1_4
paramid = 0xfff80f84 ; K00G, or 0xfff8148c ; V00C
isfloat = 1
;paramname = LTFT1_5L
;paramid = 0xfff80f88 ; K00G, or 0xFFF81490 ; V00C
;databits = 16
paramname = LTFT1_5
paramid = 0xfff80f8c ; K00G, or 0xfff81494 ; V00C
isfloat = 1
;paramname = LTFT1_6L
;paramid = 0xfff80f90 ; K00G, or 0xfff81498 ; V00C
;databits = 16
paramname = LTFT1_6
paramid = 0xfff80f94 ; K00G, or 0xfff8149c ; V00C
isfloat = 1
;paramname = LTFT1_7L
;paramid = 0xfff80f98 ; K00G, or 0xfff814a0 ; V00C
;databits = 16
paramname = LTFT1_7
paramid = 0xfff80f9c ; K00G, or 0xfff814a4 ; V00C
isfloat = 1
;paramname = LTFT1_8L
;paramid = 0xfff80fa0 ; K00G, or 0xfff814a8 ; V00C
;databits = 16
paramname = LTFT1_8
paramid = 0xfff80fa4 ; K00G, or 0xfff814ac ; V00C
isfloat = 1
;paramname = LTFT1_9L
;paramid = 0xfff80fa8 ; K00G, or 0xfff814b0 ; V00C
;databits = 16
paramname = LTFT1_9
paramid = 0xfff80fac ; K00G, or 0xfff814b4 ; V00C
isfloat = 1
Good news, everyone! There's a second LTFT learning system! Complete with its own Airflow Ranges A/B and everything. The LTFT #2 ranges are written as 6 buckets total, stored as the dividing values between each bucket A..F, across two tables A/F Learning #1 Airflow Ranges A/B: Code:
A (max): 1.0 | 280.0 | 290.0 | 300.0 B (mid): 0.5 | 140.5 | 285.0 | 295.0
And the code is .. difficult .. to follow still. When the stored value is loaded, it's immediately truncated to between -0.5 and +0.5. The calculations are intricate and seem to involve STFT, LTFT #1, and more things that I haven't explained yet. But the table exists, and it has the same storage format as LTFT #1. So: The logging addresses referred to above for LTFT #2 are:
And the logcfg.txt for LTFT #2 is: Code:
; LTFT bucket selected by the airflow min/max logic. 0 (MAF < 1.0), 1 (MAF < 280.0), 2 (MAF < 290.0), or 3.
paramname = LTFT2_bucket
paramid = 0xfff8ab70 ; K00G, or 0xfff8a8c4 ; V00C
databits = 8
; LTFT array #2, 4 buckets of { 4-byte learning status; 4-byte float } each.
;paramname = LTFT2_0L
;paramid = 0xfff80fb4 ; K00G, or 0xfff814bc ; V00C
;databits = 16
paramname = LTFT2_0
paramid = 0xfff80fb8 ; K00G, or 0xfff814c0 ; V00C
isfloat = 1
;paramname = LTFT2_1L
;paramid = 0xfff80fbc ; K00G, or 0xfff814c4 ; V00C
;databits = 16
paramname = LTFT2_1
paramid = 0xfff80fc0 ; K00G, or 0xfff814c8 ; V00C
isfloat = 1
;paramname = LTFT2_2L
;paramid = 0xfff80fc4 ; K00G, or 0xfff814cc ; V00C
;databits = 16
paramname = LTFT2_2
paramid = 0xfff80fc8 ; K00G, or 0xfff814d0 ; V00C
isfloat = 1
;paramname = LTFT2_3L
;paramid = 0xfff80fcc ; K00G, or 0xfff814d4 ; V00C
;databits = 16
paramname = LTFT2_3
paramid = 0xfff80fd0 ; K00G, or 0xfff814d8 ; V00C
isfloat = 1
This work was done on V00C. I've done my best to produce valid K00G logging addresses, but questions/corrections invited in case something looks confusing or broken. Please confirm the above logcfg segments work when pasted into a valid ZA1J logcfg before going on a long drive; I'll validate it and fix it myself as time permits, but I've been writing this post for hours and that won't be tonight. I still don't understand the exact nature of the learning-status field (i.e. LTFT1_4L) but my initial data suggests that the smaller the value, the more 'trained' this bucket is. It isn't clear what the normal limit is, but my logs range between 50555 (0xC57B) and 17404 (0x43FC) — except for LTFT1 bucket 0, which shows 255 (0x00FF) — and so I think that, were I trying to pin down my fuel trims on a given tank of gas, I would want to spend more time in the MAF buckets with large (>32000) learning-status values. In a sample log I pulled up, that highlights LTFT #1 buckets 0% PI: 1, 3 and <70% PI: 6, 7, 8, 9; so, given the bucket diagram above and the min/max ranges A=0.0-1.6, B=1.8-5.0, C=5.0-12.0, D=12.0-20.0, E=30.0-60.0, F=30.0-200.0, I need more MAF learning time in 1=B and 3=D within the 0% segment of PI ratios; more MAF learning time at in 6,7,8=CDE, so in each MAF range 5-12, 12-20, 30-60, either below 3200 rpm or above load 1.0 where PI is >0%; and in 9=F, which in stock config only occurs very occasionally at idle under circumstances that I don't have an explanation for yet (i.e. when the engine flips over to 100% port injection for a bit). I haven't done the research yet to figure out what the lowest speed I can hit each of those buckets in is yet, but that's next. For those interested in exploring this further, note that LTFTx_yL is actually .. sort of .. a 32-bit field rather than an 16-bit field; the above logcfg only logs the first 16 bits for easy consideration of "is learning dialed in yet", but I suspect that the second 16 bits represent the current learning 'amount' (which gets smaller as learning gets more dialed in, until it reaches the minimum configured in RomRaider). Understanding this field is at the core of all of my efforts to decode these ECUs, because I wanted to know if I'd driven 'enough' to test out a tune or not. This same learning-status field is used for the 5x7 FLKC table, too, so if I can pin down exactly what it means, then in theory this lets us be more definitive about what driving patterns are required to completely finish knock, fuel, etc. learning on a new tune. --- So, to show my work on how I'm planning to use this — Looking at this log I have from a few weeks ago of Speed x MAF by Gear: https://datazap.me/u/callisto/logs/j...0%2C30%3A0%3A0 Bucket 1, range B, MAF 1.8-5.0: This log sucks for determining good training ranges. But, I can see likely maximums for this MAF range at 2nd @ 29, 3rd @ 38, 4th @ 45, 5th @ 75, 6th @ 80. Hmm. I think the new scatterplot isn't applying filter-trims yet. So, next, DiPi ratio result x MAF by Gear: https://datazap.me/u/callisto/logs/j...0%2C30%3A0%3A0 There are approximately contiguous 0% PI ranges at 2nd @ 30-87, 3rd @ 35-67, 4th @ 51-75, 5th @ 30-105, 6th @ 2-67 (?!). Combined with the above, 2nd is ruled out (29<30), 3rd is only viable for a tiny window (38>35), 4th is ruled out (45<51); 5th is OK (75>30); and 6th can do anything (80>2-67). So, for bucket 1, focus above MAF 1.8 on 5th below 75kmh, and 6th below 80kmh. Hmm. https://datazap.me/u/callisto/logs/j...0%2C22%3A5%3A5 5th only shows deceleration in the relevant interval; I'm not sure there are any acceleration events matching this MAF=1.8-5.0, PI=0% range in this log at all. Same with all six gears. If I'm to train this ranges, I'll have to use deceleration, or I'll have to accelerate very lightly in 6th on a very significant downhill — unless I can prove that LTFT learning works during deceleration using logging. Welp. Bucket 3, range D, MAF 12.0-20.0: Now that I know to use the filter chart first to look for speed-increasing events: https://datazap.me/u/callisto/logs/j...0%2C22%3A5%3A5 4th from 52-56, 5th from 60-65, 75-77, not much else. Next, DiPi x MAF by Gear: 4th from 51-74, 5th from 40-105; so these are both viable. Next, Speed x MAF by Gear: 4th crosses the target MAF range regularly but doesn't seem to stay in it; 5th, however, spends a considerable amount of time there. The answer is in the scatter of Accel x MAF by Gear, which shows that Accel >= 10 is a good metric for filtering gears 4 and 5 into the right zones. Hmm, I should start with Accel and work backwards. https://datazap.me/u/callisto/logs/j...0%2C30%3A0%3A0 MAF 12-20, 0% PI, graphing Speed, Accel, Gear. All logged results are Accel >= 10, so that's a sound filter to add. Then, very approximately, 4th from 52-55, 5th from 55-65 and 75-76. So I can reasonably expect to train LTFT bucket 3, which is lacking in my sample, in 5th gear at 35-50mph — and now that I have a sensible way to find those, let's repeat it for Bucket 1. https://datazap.me/u/callisto/logs/j...0%2C30%3A0%3A0 MAF 1.8-5, 0% PI. Filtered for Accel > 0, there are no instances of bucket 1 in this log at all, which at least confirms the earlier result. Onward. The next three buckets are for non-zero PI <70%, so updating the filter for that: https://datazap.me/u/callisto/logs/j...A0.00001%3A0.7 Bucket 7, MAF 12-20, <70% PI. This is all 5th gear. Okay. There's probably a load component to this, but in essence, if I spend a lot of variable drive time in 5th gear softly accelerating up and down various sorts of hills between 35-50mph, Bucket 3's learning-status value should decrease as it dials in the trim further. https://datazap.me/u/callisto/logs/j...A0.00001%3A0.7 Bucket 8, MAF 30-60, <70% PI. Plainly obvious accelerations here. 2nd gear, 32-48 (medium acceleration), 4th gear, 51-57; 5th, 78-87; 3rd, 49-70. This should be an easy bucket to train so long as I'm accelerating more than softly; 3rd from 30-43mph, 4th from 31-35mph, 5th from 48-55mph at medium acceleration is absolutely doable and easy to remember: 3rd from 30mph, 5th from 45mph, done at 55mph; softly for Buckets 3 and 7, medium for Bucket 8. https://datazap.me/u/callisto/logs/j...A0.00001%3A0.7 Bucket 6, MAF 5-12, <70% PI. Almost nothing useful here in acceleration, and it's all 5th from 55-65 at medium-soft acceleration. This will get training data as a side effect of pursuing bucket 7, so nothing special needs to be done here yet; the existing pattern holds. I don't have any data for bucket 9 in this log, which suggests it's a cold start thing rather than a hot start thing. Going back to an older cold start, which happens to also have a complete set of 'current LTFT stored values' for arrays #1 and #2: https://datazap.me/u/callisto/logs/x...21-34-40-42-43 Yeah, that's a cold start. 22 seconds of logging with LTFT learning theoretically enabled, bucket 9, but stored value 0 even though LTFT is all the way up at 8+. There is clearly more to understand about bucket 9, but I'm not going to train that bucket by repeatedly cold-starting the vehicle. So, that's how I would use the training data and logic to evaluate which LTFT buckets need more time. Next step for me is to merge the new work into my logcfg and start tracking current data rather than past Datazap samples, and then repeat this process to see how learning-status responds as I traverse learning-ranges that seem to need it. Excellent! Last edited by callisto; 03-21-2026 at 04:31 AM. |
|
|
|
|
|
#17 |
|
Senior Member
Join Date: Jan 2017
Drives: brz 2017 hksv2
Location: italy
Posts: 2,292
Thanks: 517
Thanked 1,125 Times in 815 Posts
Mentioned: 70 Post(s)
Tagged: 0 Thread(s)
|
what ahould happen if you put that table to 0 overall?
|
|
|
|
|
|
#18 |
|
Senior Member
Join Date: Nov 2021
Drives: 2019 Subaru BRZ
Location: PNW, US
Posts: 109
Thanks: 88
Thanked 88 Times in 46 Posts
Mentioned: 4 Post(s)
Tagged: 0 Thread(s)
|
“How does LTFT work?” will take more time, but I have enough now to capture a log after battery pull so I can monitor the table evolving and start tracing the log back through the system. For example, I’m not sure the tables start at zero — there are reset functions all over the ECU that detect ‘empty’ memory and replace it with ‘initial state’ values, so it might just reset learning. I also want to see if the WOT process clears the entire table. So much to do, so little time
|
|
|
|
|
|
|
|
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Crazy high LTFT, lean codes, e85... | nickw14 | Software Tuning | 18 | 06-23-2015 08:55 PM |
| high ltft at idle, my how to fix it(not fixed yet) | trdric | Software Tuning | 16 | 06-18-2015 10:27 PM |
| LTFT increased over 10% after oil change (new E85 user) | tracerit | Software Tuning | 19 | 05-21-2015 04:35 PM |
| FRS/BRZ used to deliver Sysco food stored in sheds | BRZY | Northern California | 3 | 09-01-2014 07:03 AM |
| Temperature Swing = Large LTFT Swing? | joneze93tsi | Software Tuning | 5 | 07-30-2014 11:10 PM |