Datalogger - the rebooted reboot...

Tuesday, March 12, 2019 - 15:45

While things have been fairly quiet on the site recently, that hasn't really been a reflection of the level of work that has been going on at the DiscoTd5 Lab for last three or four months...

The datalogger had pretty much been dumped in parts bin as the level of work required to get it up to a useful state seemed to be overwhelming. Conversation with an enthusiastic D2 tuner convinced me to take another look - on the basis of build it or bin it for good.

Three months later, and hundreds of hours rewriting the code, it's slowly starting to come together.

The biggest chunk of effort - which has basically eaten the last 4 weeks - has gone into writing a SDCard // FAT32 library from the ground up. This was the obstacle that had resulted in the project being shelved previously so it's been a significant hurdle to overcome. There is still work to do but there is now light at the end of the tunnel.

It might seem a bit bizarre to be writing a FAT32 library from scratch when there are well established products like the ELM Chan FATFs available.
The main issue has been that the logger code is written in a way that requires components to be non-blocking. Blocking code will prevent any other code running while the blocking waits in a loop for something to happen - it literally blocks progress.
ELM Chan's FATFs is blocking in that it waits for SDCards to come out of busy state before proceeding. The issue here is that at times cards can be busy for extended periods - 50ms is not unusual even with a good quality card like a SanDisk Ultra. With poor quality cards wait times of 200ms+ are not uncommon.

Where this becomes a problem for a Td5 data logger is that the default time between an ECU response and the next "tester" request is 25ms.
The Nanocom Evo solves the problem by making a series of requests - one log line of data - then writing that line to file. There is a 600ms+ pause between the end of one block of data, and the start of the next which is plenty of time for even the slowest junk SDCard to finish writing and return to idle state. But this also means that the Nanocom is writing one line of log data every 1.25 seconds. Fine for some purposes but a lot of dynamic behavior "falls through the cracks" - the torque reduction of an auto shift completes in under 300ms for example, so is effectively invisible.

The approach I'm taking here is to use non-blocking code with DMA (direct memory access) transfers of data to the card. The DMA transfers effectively run in the background without processor intervention, so the combination means that the processor only needs to setup the write to the SDCard, and then can resume more important tasks like reading data from the ECU, or other sensors. The issue of wait times is dealt with by buffering the data waiting to be written to card. In theory all this will allow data rates 10-15 times faster than the Nanocom to be written to card without delays caused by slow card writes.

An excuse for new toys

One of the issues I'd have was that my old Saleae Logic - an original and now much cloned 8 channel 24Mhz job - is starting to show it's limitations when trying to capture communication with the SDCard at 20Mhz bus speed. To capture a signal you need at least twice the frequency of the signal - so 40Mhz at least - ideally you oversample at x4 so 80Mhz. With the old Logic I was flying blind.
As much as I love the Saleae and the software, a new Logic 8 Pro which has sufficient speed for this task was prohibitively expensive - 700-800USD.

So I've ended up with an open source design analyser that does either buffered or streaming captures. The buffered captures are made to internal memory, and have fairly limited length of capture. around 1 second @100MHz using 4 channels, and 300ms @ 400Mhz using 4 channels. Streaming captures are sent over usb to an open source, cross platform application based on Sigrok. The buffered captures are limited to 100Mhz with 3 channels, or 50MHz when using 6 channels. For the SDCard work I need 4 channels and long captures so need to use the 50MHz/6 Channel option. So not perfect but it's flexible enough to be quite useful. Best thing was that it's far more affordable at $150USD.

DSLogic Plus vs Saleae Logic original
The Logic is the small black square on the left, the DSLogic Plus on the right is significantly bigger but still fairly compact.

And the DSLogic proved it's worth within an 30 minutes of unboxing. I'd had an issue where the code would run perfectly with the Saleae connected but would then fail as soon as I disconnected.
It's a real catch22 - the bug occurs only when your debugging gear isn't connected... makes troubleshooting fun. The DSLogic has coaxial probe leads which significantly reduce the effect on the signal being monitored compared with the Saleae's flying leads. There is a great comparison of a Saleae clone and DSLogic on the OpenTechLab channel on YouTube - the sims of the effect of flying leads is quite an eye opener.

The video above mentions the probe clip quality. The ones that came with mine seem to be cheap knock-offs of ez-hooks. Not quite as clunky as those seen in the video, but hook wire is pretty flimsy compared with ez-hooks.

The upshot was that even with the DSLogic connected the "undebugable" bug was occurring every time a card was inserted, and it was straight forward to isolate where and why the code was failing.

DSView

The software is fairly good but a bit rough around the edges at least under macOS. I have a bit of trouble with zooming using the trackpad - it's clearly designed for left and right buttons plus scroll wheel. Protocol decoding seems accurate but is slow compared with the Saleae app, although to be fair10 second captures at 20Mhz were regularly bringing that program to the point where a force quit was required, and in one instance a full reboot.

For the money it is pretty decent, and the cross platform software is a big plus in my book.
Worth noting that the DSLogics sold on eBay are not covered by a manufacturers warranty.
I opted to purchase direct.

EU3 MAF timeout disable

Tuesday, January 8, 2019 - 10:45

I've had a few requests for details on how to disable the timeout on EU3 maps when the MAF sensor is disconnected.
Without this mod the throttle on EU3 maps is unresponsive for 20-30 seconds when the engine is first started.

It's quite simple to do by altering the MAF "out of range" timeout check from a conditional "if timeout branch" to an unconditional "branch".

You'll need to use a HEX editor for this.

First open up you .map file in your favorite hex editor - I use Hex Fiend on macOS for stuff like this.

With the .map open search for a sequence of hex bytes: 66 30 31

Unmodified .map

There should be only one occurrence of this sequence in the .map file at an offset of somewhere around 0xD100 - 0xD400.

Next, change the 66 to 60 - this alters the conditional branch instruction to an unconditional branch, meaning the ECU always executes the "no MAF" code.

Modifed .map file

Save the modified .map file and you are done.

Be aware that this mod “lobotomizes" the EU3 maps to a EU2 style single smoke map configuration.
The ECU will only use the main high range smoke map (map 60).

This should work for all EU3 variants.
If you can't locate the byte sequence let me know which variant you are working with.

Note: The checksum needs to be updated if you are loading the .map using the Nanocom. This can be done by loading the .map file into Tuner Pro with the appropriate XDF and then saving the "bin". The checksum is updated on save. Td5 Map Editor will also update the checksum. If you are using Td5 ME you'll have to either make and the reverse a change to the map so the file is marked as "dirty" then save, or "save as". Thanks to Neil for mentioning this omission.

File under Nanocom Bugs

Monday, December 24, 2018 - 11:00

Is Front Left the new Right Rear?

Getting id of sensor values correct is just so last season...

I've had the 4 amigo's hanging about for a while and finally decided I better fit the replacement sensor that has been kicking around for the last month or two this morning.

Fault codes have been showing an intermittent fault in the right rear sensor.
Usual problem is knowing whether that is right facing the front of the vehicle or right facing the rear.
I'd been assuming right facing the front, but thought I'd double check before replacing.

Logical thing to do is pull the sensor connector and check the voltages with the Nanocom.

So I disconnect the sensor in the rear right wheel arch.
All good - unplugging the sensor is mechanical so Nanocom can't screw this up for us!!

Then check the sensor voltages...

Something doesn't look quite right!

Cyprus, We have a problem..

Fortunately the fault codes are correct, and a quick drive revealed a rear right electrical failure.

Hawkeye and Nanocom: The Case of the Wrong Fault Codes

Friday, November 23, 2018 - 12:30

We tend to assume that when you plug in a specialist fault code reader the codes that are reported are correct.

Unfortunately that faith seems to be misplaced.

Initially I thought this was a problem that only afflicted the Nanocom but a recent posting on a UK forum suggests that the Hawkeye suffers from the same problem.

The codes that had been posted will be familiar if anyone who as tried running an EU3 map on an EU2 vehicle.

Nanocom
- (4,3) Coolant temperature circuit. (Logged High).
- (6,3) Coolant temperature circuit. (Current).
- (24,7) Problems detected with auto gearbox. (Current).

Hawkeye
- Fault 3018 Coolant temperature High Fault logged
- Fault 3034 Coolant temperature Fault Active
- Fault 3174 Fault detected with automatic gearbox

The three "phantom" faults reported are caused by the lack of Ambient Air Temp sensor which is part of the 4 wire AAP/AAT sensor used on the EU3 engines. And the codes can be eliminated by adding an extra wire and the EU3 airbox lid and sensor.

But that doesn't explain why the fault codes do not reflect the actual fault.

We investigate anomalies...

It's not widely known that the EU2 NNN maps include code to process the output of the Ambient Air Temp sensor, although the data is not used by the engine maps. I currently have an EU3 4 wire AAP/AAT sensor fitted but have gone back to running EU2 maps. With this setup I discovered the AAT readings are returned as part of the live data. Unfortunately the AAT sensor is completely ignored by the Nanocom, despite multiple requests that this be added.

Given that both EU2 and EU3 NNN maps are AAT aware, it would be fairly surprising if the ECU code was setting incorrect fault bits.

Looking at the ECU code for EU2 and EU3 NNN maps shows that the bits which correspond to faults 4-3, 6-3 and 24-7 are set by code that handles the AAT sensor. So these faults should actually be shown as AAT faults - logged high, active fault, and voltage out of range.

Let's go back, way back...

So at this point I started looking back at the MSB code....

Fault 4-3 corresponds with ECT sensor over voltage, check.
Fault 6-3 corresponds with ECT sensor active fault, check.
Fault 24,7 corresponds with Auto fault, check.

In other words the fault codes are correct on MSB ECU's, but wildly incorrect on NNN ECU's.

Oops...

Unfortunately this issue doesn't effect just the AAT sensor.

There was some internal reordering of ADC inputs done in the upgrade from MSB to NNN which means that 1 in 4 of the fault codes in the 1,x - 6,x range are incorrect. An additional fault in that range cannot be correctly identified without a code that is "invalid" for the MSB and therefore not reported by diagnostic tools.

Beyond the basic input checking codes (1,x - 6,x) there are additional errors and major omissions.

Checking out some of the faulty codes on forums I've seen at least one instance where someone was told to replace the throttle position sensor when the fault code actually related to the MAP sensor... It wasn't surprising to see that after forking out a few hundred for a new pedal the person reported back that the new pedal had not solved his problems.

Other problems with incorrect codes are deemed as "quirks" when it becomes obvious the "faulty" part is fine and advice descends rapidly into random part swapping recommendations.

You just have to wonder how much money has been wasted based on the these incorrect codes...

So if you own a vehicle with an MSB ECU count yourself lucky - any fault codes will be correct.
NNN owners will just have to console themselves with the fact that the codes will be correct about 75% of the time...

XDF progress update

Monday, November 5, 2018 - 11:30

Current Status

I'm currently working on new method for generating XDF's which is providing a chance to streamline the process.

One issue that has been bothering me is that significant portion of the NNN XDF's are redundant. This occurs because the XDF's are currently created based on the variant-fuel map pairs in each .map file.

The reality is that the only difference between the fuel maps in for example swdxe007-swtnp004.map and swdxe007-swtnp006.map is the number of the variant map in the fuel map. The fuel map checksum also changes by the difference between the variant map version numbers.

Neither of these differences have any impact on how the XDF defines the tables and constants within the fuel .map. A small number of NNN EU2 maps have additional differences in 5-6 constant values but again the structure of the fuel map is the same, so one XDF definition can edit both versions.

So the upshot is that the next release of the XDF's will be based on the fuel map identifier only, and this will reduce the number of NNN XDF by about 30-40%.

XDF auto loading

Tuner Pro has the ability to auto load XDF's when a .bin / .map is loaded. Unfortunately this must be manually configured but it saves a bit of messing around once it's configured. It's usable with current versions of the XDFs but will make more sense when the XDFs are consolidated.

The auto loading is configured under Tools > Preferences > Default XDFs by selecting enable default definitions.

XDF auto load

These are the offsets for the current NNN XDFs.

Map Offset ID Byte
svlne004-svtnp003 0x1cfe6 0x8f
swdxe007-swtnp004 0x1cfe6 0x9b
swdxr004-swtnp004 0x1cfe6 0xdf
swdxr004-swtnp006 0x1cfe6 0xdf
swdxe007-swtnp006 0x1cfe6 0x9b
sthdr009-sttdp009 0x1ba26 0x3d
suhde036-sutdp014 0x1ba26 0x44
swdxr002-swtnp004 0x1cfe6 0xb8
svdxe008-svtnp006 0x1cfe6 0x30
suhdr009-sutzp005 0x1ba26 0x3f
svdxe008-svtnp005 0x1cfe6 0x30
suhde036-sutdp012 0x1ba26 0x44
suhdr009-sutzp004 0x1ba26 0x3f
svloe005-svtnp005 0x1cfe6 0xca
svloj002-svtnp006 0x1cfe6 0xbd
svdxe004-svtnp003 0x1cfe6 0xe6
svloe004-svtnp003 0x1cfe6 0xd1
svdxe003-svtnp003 0x1cfe6 0xad
sthle022-sttlp010 0x1b98e 0xee
swdxk001-swtnp004 0x1cfe6 0x33
svloe005-svtnp006 0x1cfe6 0xca
svdxr007-svtnp005 0x1cfe6 0x51
sthde021-sttdp010 0x1ba26 0xa1
svloe002-svtnp003 0x1cfe6 0x8b
svdxr007-svtnp006 0x1cfe6 0x51
svloj002-svtnp003 0x1cfe6 0xbd
svlor005-svtnp005 0x1cfe6 0x9
svlor004-svtnp003 0x1cfe6 0xf
sthde021-sttdp009 0x1ba26 0xa2
svlor002-svtnp003 0x1cfe6 0x10
svdxr005-svtnp003 0x1cfe6 0x4d
svdxr002-svtnp003 0x1cfe6 0x4e
swdxk003-swtnp006 0x1cfe6 0x86
svdxe006-svtnp003 0x1cfe6 0x2c
sthle022-sttlp009 0x1b98e 0xef
svdxg003-svtnp006 0x1cfe6 0x7b
swdxk003-swtnp004 0x1cfe6 0x86
surdk004-sutzp004 0x1ba26 0x3b
svlnr004-svtnp003 0x1cfe6 0x16
svlnr005-svtnp005 0x1cfe6 0xff
swdxe004-swtnp004 0x1cfe6 0x5a
surdk004-sutzp005 0x1ba26 0x3b
svlnr005-svtnp006 0x1cfe6 0xff
svlne006-svtnp003 0x1cfe6 0xd5
sthdr009-sttdp010 0x1ba26 0x3c
svlne007-svtnp005 0x1cfe6 0xbb
svlnr002-svtnp003 0x1cfe6 0x18
svlne007-svtnp006 0x1cfe6 0xbb

Wastegate Modulator Control

Thursday, August 17, 2017 - 13:15

A couple of months ago I posted on how the Wastegate Modulator operates when energised and de-energised.

That research was necessary because the “common forum wisdom” that the WGM operated to reduce boost seemed to be completely at odds with what the WGM control code appeared to be doing.

To quickly recap, when active the Wastegate Modulator rapidly switches between boost pressure and turbo intake pressure to regulate the pressure at the wastegate actuator. When the Modulator is inactive boost pressure flows directly to the wastegate actuator.

The effect of the switching between intake and boost pressures at 16 times per seconds is to create a blended pressure which related to current value of the two pressures and to the amount of PWM applied. Because the intake is always pressure is always lower than boost pressure (assuming the Turbo is producing boost) the WGM can only reduce pressure at the Wastegate Actuator when there is a PWM signal.

With no PWM modulation applied to the modulator boost pressure flows directly to the wastegate actuator meaning the wastegate behaves as it would if the modulator was not present.

This is absolutely fundamental to the way the WGM maps work, so
if you have any doubts I’d recommend (re)reading the post on WGM operation, and if necessary doing some testing to verify this is correct for yourself.

The WGM Controller

I’ve had a bit of difficulty trying to decide how best to write up the WGM. The software contains support for a full blown PID controller, however the WGM implementation uses only Integral component. The Proportional and Derivative components are both disabled.

For the moment I’ve decided to stick to what is actually used in the standard implementation, but keep there is a huge amount of hidden flexibility and the full PID setup should prove useful for full-blown Boost Controller applications down the track.

As a note of explanation, the parameter names I'm using below come from a list of Td5 System Constants from offical Land Rover engineering docs that were posted to a Spanish forum. While they are not natural language they have the distinct advantage of accurately defining the purpose of the value.

So let’s look at the details.

WGM Enable and Disable

The first thing to note is that the Wastegate Modulator is not “always on”. The control code is only enabled when the engine is operating above specific RPM and IQ thresholds.

The enable thresholds are set by two system constants:
- tb_fuel_mass_enbl = 24.00 mg/fire
- tb_engine_speed_enbl = 1900 rpm

Once the fuel mass (IQ) requested is greater than 24mg/fire and engine speed is greater than 1900rpm the Wastegate Modulator controller is switched on. The controller remain in the “on” state until either engine speed or IQ falls below the disable threshold.

The two system constants for the disable threshold are:
- tb_fuel_mass_disd = 20.00 mg/fire
- tb_engine_speed_disd = 1750 rpm

This state diagram illustrates what is occuring. The controller remains in either an on or off state until the conditions required to switch to the other state are met.

WGM Enable-Disable State Machine

These on/off thresholds are confirmed by data logging. I've filtered a log with just under 1000 data points to extract the lines that have a Wastegate Modulator Duty greater than zero, then plotted RPM vs IQ. The colour bar shows the WGM Duty %.

RPM vs IQ, WGM greater than zero

This shows quite clearly the WGM is only active above the operational thresholds described above.

Narrowing the focus to the “off -> on” transition, I’ve selected rows where a 0% WGM Duty is followed by a non-0 WGM duty %.

Off to On Transition

You can see the engine speed values are mainly +/-100 rpm around 1900rpm, and the IQ values appear to be generally above 24mg/fire.

Looking at the “on -> off” transition, I’ve selected all non-0 WGM Duty % values preceeding a 0% WGM Duty.

On to Off Transition

While the engine speed values are still above 1850rpm, the IQ values between 20 and 24 mg/fire are apparent.

To further illustrate the off -> on transition ploting the log data in more familiar way shows the behaviour of Wastegate Modulator duty, RPM and IQ. In both cases IQ is around 33mg/fire.

The first plot shows behaviour at 1690rpm with IQ of 33mg/fire, and WGM duty at 0%.
RPM = 1690

The second data point 290ms later shows engine speed of 1970rpm, with WGM duty at 31%.
RPM = 1970

Current Boost and Target Boost

These two parameters are calculated each cycle regardless of whether they are used in WGM operation.

Current Boost is a calculated value equal to Manifold Absolute Pressure (MAP) - Ambient Absolute Pressure (AAP).

Target Boost is a value looked up using the final table in all Td5 engine fuel maps.

Target Boost

The X-axis value is IQ (or fuel mass) mg/fire and the Y axis is RPM and the Z-value is Target Boost in kPa.

The Target Boost table is identical across Euro, ROW, Japanese and Korean tunes, on Eu2 and Eu3 motors and Manual and Auto D2’s despite the variation in driver demand tables, and smoke and torque limiters which suggests that this table is not precisely controlling the boost to match fuelling.

I’ve highlighted the region where engine speed is above 1750 and the IQ requested is above 20 mg/fire in a stock D2 Auto driver demand map to illustrate the region where the Wastegate Modulator is operating in an unmodified map.

EU2 Auto Driver Demand

It should be apparent that when you start increasing the duration in the driver demand, smoke and torque limiters that the values returned from the Target Boost table will come from further to the right - in other words the target boost will tend to be higher than for stock driver demand.

Wastegate Modulator Duty Ratio Bias

This map is has Target Boost as the X-axis and RPM as the Y-axis. Z-Axis values are WGM Duty Ratio.

WGM Duty Ratio Bias

This is the underlying amount of WGM Duty Ratio for a given target boost level. Because the ECU map lookup “clips” axis values to maximum or minimum, anything below 100kPa uses the left column, and anything above 120kPa uses the right hand column.
Adapation to higher boost levels will require modification of the header values.

WGM Integral Gain

The Integral Gain map has RPM as the X-axis, Boost Error as the Y-axis, and Integral Gain as the Z-axis.
This is used in the ECU when calculating the Integral (summed value over time) of the error.
WGM Integral Gain

WGM Proportional Amnt

Not Used in factory maps.
X-axis is Boost Error, Y-axis is WGM Duty Ratio.
WGM Proportional Amnt

Boost Error

Boost Error is calculated as the difference between the current boost and the target boost:

Boost Error =  Current Boost - Target Boost  

Note that if current boost is below target boost the error is negative, and positive if current boost is higher than target boost.

Controller code

The integral map described above should give you a big clue as to what we are dealing with here - a Proportional-Integral-Derivative Controller (PID). This is a type of feedback controller that is widely used to regulate “plant” to a steady state.

Fortunately Land Rover has disabled most of the Proportional and Derivative code so what is left is far simpler. However, the fact all the PID controller is still in place does open up the possibility of some fairly advanced boost control implementations in future. At this point I’ll stick to what is actually used.

Integral Calculation

The WGM controller has a “dead band” of +/- 2kPa which is set by the tb_intgl_enbl. Boost Error values of less than this amount are ignored.

If the Boost Error is greater that +/-2kPa, it is limited to the value set by tb_max_err_intgl which is given as 10kPa, but looks more like it should be 1kPa from my reading of the code. Regardless the constant used has a raw value of 100. Given that the raw boost error figures the constant is applied to are kPa * 100, this has the effect of limiting the max error amount to +/- 1 kPa.

The limited Boost Error is then multiplied by the Integral Gain and then divided by 1000 (raw value) to give the required adjustment to WGM Duty Ratio. You’ll note the Integral Gain table values are all negative, and as previously noted current boost values below target boost result in negative boost error values.

100 * -50 / 1000 = -5   
-100 * -200 / 1000 = 20  

This plot of logged engine data shows how the Boost Error and Integral behave. As Boost Error becomes postive the Integral amount decreases, and vice versa. The other point of note is that the values are not calulated when the WGM is not currently enabled.

Boost Err and Integral

The adjustment amount is then added to the accumlated value (Integral) of the Wastegate Duty Ratio adjustment. The maximum adjustment to Duty Ratio is +/-0.2% each time the code is executed.

The WGM controller code runs at 10ms intervals which is set by the scalar tb_intgl_deriv_rate. At this rate the controller can adjust the Duty Ratio by up to 20% in 1 second.

The final step in calculating the Integral is limting checking against tb_clamp_intgl_hi which is set at 10%, and tb_clamp_intgl_lo which is set at -30%.

Total WGM Duty Ratio

The final step is to sum the component values of the PID controller. Because the Proportional and Deriviative amounts are set to zero in this implementaiton this is becomes effectively

 Duty Ratio % = Bias + Integral

You can see this in practise in this plot of log data.
The Duty Ratio Bias is 25.64%, and the Integral is -1.54% and the total WGM Duty Ratio is 24.1%.

This amount is then checked against tb_max_duty_ratio which is set at 82%, and tb_min_duty_ratio set at 16%.

WGM Module Disable

The WGM module can be disabled by setting the scalar which controls the PWM frequency tb_turbo_pwm_freq to 0. Defenders have a fully configured WGM which only requires setting this scalar to 16 to enable.

Header editing in Tuner Pro

Wednesday, April 5, 2017 - 13:45

Update I've added a short video giving a run through on adding a column header editor to a table.

A few people have asked how to edit headers for map tables, so this is quick how-to on setting up header edit maps.

The screen shots are for a EU2 map, so don't assume that the values in the screen shots will work for you - they most likely won't.

  1. Open up the smoke map definition (right click / F2) and noted the Address, Data Size and Number of Columns under the Columns tab.

Find column details

  1. Add a new table (right click, Insert new XDF parameter), On the general tab add a name, the address from the columns tab of the original map and the data size.

New Table - General Tab

  1. Add the number of columns under the columns tab.

 Columns Tab

And save.

This will give you a “table” which looks like this...

 Completed header editor

You can now edit the header values in the cells of the new table.

This video gives a quick run through of the process, and should hopefully fill in any gaps.

Site updates

Tuesday, August 7, 2018 - 21:00

While it shouldn't be obvious, I've moved the website to a new host. The process has been fairly problem free but if anything is acting up let me know.

On a related topic Google Chrome and other browsers have started marking sites that aren't secured will SSL certificates as "not secure". It's really a bit of overkill for a site like this, but as the Not Secure warning is kind of off putting I've moved the site across to the secure protocol.

Chrome is currently still complaining because the images in a lot of the posts are hard coded to the insecure address. I'm slowing working my way through and fixing up the links.

For the moment the front page and the donor login pages are now flagged as "Secure".

The Mysterious MAF Patch

Thursday, August 31, 2017 - 17:15

From the earliest versions the donor XDF’s have included an undocumented patch which is simply named MAF Patch.

A few people have asked what it does, and my response always includes something along the lines of “I really should document that!”.
So here it is finally - the documentation...

What it does: short version

The MAF Patch alters the MAF Calibration curve and ai_analg_multip: MAF parameters to extend the usable range of the stock MAF sensor.
With this patch the stock can read out to around 850kg/hr before going out of range.

What it does: tl;dr version

As you’ll be aware from the MAP recalibration tech note the ECU uses a resistor divider to reduce the voltage entering the Analog Digital Convertor (ADC) to 90.7046% of the original value. This is primarly to protect the ADC inputs from over voltage damage.

The ADC uses a reference voltage of 5000mV, so can convert an analog voltage in the range of 0 - 5000mV into a digital value between 0 - 1023. These digital values are known as ADC codes.

A voltage greater than 5000mV will result in an ADC output of 1023.

The following plot shows the relationship between sensor output in mV and ADC codes.

Sensor Voltage to ADC Codes

It should be apparent that the maximum ADC code output of 1023 corresponds to a sensor output of somewhere around 5500mV.

More precisely the maximum sensor output that can be represented without clipping is:

1023 / 0.2046 / 0.907046 or 5512mV

The ADC codes and “magic numbers” are covered in detail in the MAP Recalibration post so I won’t go into detail again here.

The stock map parameters use an ai_analg_multip: MAF of 5388 and ai_analg_divisor: MAF of 1000.
Working backwards from the default MAF limiter voltage of 4950mV we can determine the ADC output in codes

4950 * 1000 / 5388 = 918

And the corresponding sensor output voltage is therefore

918 / 0.2046 / 0.907046 = 4946mV

So the ai_analg_multip: MAF of 5388 reverses the scaling of the hardware and ADC, and the MAF Calibration Curve map is used to determine the Airflow value in kg/hrs.

The obvious thing here is that there is a bit of untapped range available in the ADC convertor. And we know the MAF can output much more than 5000mV.

For the patch I decided to use 5000 as the ai_analg_multip: MAF scalar. So lets assume the same 4950mV limiter and calcuate the ADC Codes:

4950 * 1000 / 5000 = 990

The sensor output that produces 990 ADC codes is

990 / 0.2046 / 0.907046 = 5334mV

You could probably go higher, but I’m keeping it on the safe side. After all range that we are using is quite literally uncharted territory beyond the calibration range of the stock MAF.

The problem now is that the a MAF output of 4950mV now produces

4950mV * (5000/5388) = 4593mV

I resorted to MATLAB’s Curve Fitting Toolbox to come up with a best fit for the stock curve, and then extrapolated the curve out to 5334mV.

Obviously extrapolating a curve in this way comes with no guarantees of accuracy, and the further you move away from the known the more quesitonable the extrapolated value. This is another reason I was reluctant to push to 5500mV with the stock MAF sensor.

Once the curve had been extrapolated the next problem was that retaining the standard column header values made it very difficult to obtain smooth integration of the new maximum flow values.

To solve this problem I used a table optimisation toolbox for MATLAB. The toolbox allows you to load a curve and then specify a required number of columns. It then optimises the breakpoints to minimise the deviation from the orginal curve.

Stock and Patch MAF Curves

The result is of all this was a new MAF curve that reads out to over 850kg/hr, and has a maximum error of +/-1% when compared to the stock MAF curve.

Patch Error

The error plot is slightly misleading - the maximum error is at lower sensor outputs of around 100kg/hr. The larger deviations of 2.5kg/hr occur at flows of 500kg/hr and above, so are in the range of +/-0.5%.

So there you have it.

The MAF patch is basically a take it or leave it affair due to the fact that it’s been optimised to minimise error as far as possible compared with stock.

I’ll look at adding MAF limiter editors in the next revision of the XDF’s which will allow the MAF sensor to saturate at the maximum rather than limiting.

Using the USBBDM as a remap interface

Saturday, September 2, 2017 - 13:00

The Nanocom .map and .tun formats is pretty much a standard for distributing remaps and loading different stock maps.

It should be fairly obvious that this was not just accidental. The support for Nanocom ID and VIN locked files plus respecting the NO READ attribute which prevents tunes being read back out of an ECU are clearly aimed at establishing the Nanocom as an acceptable remap delivery tool.

And this probably the key weakness of the Nanocom as a programmer - it is designed for uploading completed tunes to a customers vehicle.

This has become glaringly obvious over the past week when I've been trying to test mods to the Wastegate Modulator control maps. The testing requires repeated increment and test cycles, and this is where the Nanocom shows just how unsuited it is to the task.

As many are aware the ECU uses a variant map and fuel map pair. The variant is basically the program code and the fuel map is the configuration data. The variant code is only very, very rarely modified, and in most cases only the fuel map is touched. The XDF's only modify the fuel map.

The variant map is approximately 100Kb and the fuel map is 16Kb. The Nanocom erases and programs both maps each and every time it does a .map upload. That little bit at the end of the upload that takes 10-20 seconds to complete is the fuel map being programmed.

Each time you program with the Nanocom it goes something like this..

  • Copy tune to SDCard
  • Place SDCard in Nanocom
  • Connect Nanocom to OBD port
  • Wait for Nanocom to boot
  • Navigate to Td5 Map module
  • Select .map
  • Wait for Nanocom to verify checksum and "protection"
  • Turn on ignition, then push button on Nanocom
  • Turn ignition off, then push button on Nanocom
  • Wait 15 seconds
  • Turn ignition on, then push button on Nanocom
  • Wait while Nanocom erases then programs variant and fuel maps ( approximately 2 minutes)
  • Cycle ignition

If all goes well - and it often doesn't - that process takes at least 4 - 5 minutes.

And yesterday when I was trying to upload a small mod and the Nanocom repeatedly failed at the "protection" check I decided that it was time to bite the bullet.

Enter the BDM

I've had a USBBDM interface for a few years, primarily to recover ECU's bricked by failed Nanocom uploads, but I've been conscious of the fact that tools like WinOLS offer BDM programming interfaces for remapping. BDM is typically used in bench programming setups, however I've added a 10-pin header to my ECU to make debricking a bit more straight forward.

So the simple solution was to connect a short ribbon cable with IDC sockets to the BDM port on the ECU and then feed the cable out under the edge of the lid. It's not perfect as the cable can be damaged by the lid, so I'll probably file a shallow notch in the case so there is less pressure on the wires.

USBBDM

The setup works reasonably well as the BDM port is near the upper edge of the case when installed in a D2.
Ideally I need a longer USB cable so I can reprogram from the drivers seat with bonnet down but this was basically a quick test to see how practical the idea was, so I popped the bonnet to do the reprogramming.

And the result was: very practical

Program Done

There is currently a little to much "are you really sure" checking in the recovery scripts which makes things a little slower than necessary. Once you have the USBBDM interface hooked up it's pretty quick. It takes less than a minute to select and program a new fuel map. The actual programming is done in a couple of seconds and there is no worry about the upload freezing.

A month later...

I first started writing this post about a month ago, and I haven't even considered using the Nanocom to upload a tune since then. The main fiddle at the moment is popping the bonnet to plug in the USBBDM but even with this the fact that you know the tune will program first time makes it a winner. Normally I wouldn't load a map if I was away from home, but loading using BDM is so reliable I don't even hesitate to make adjustments and upload the modded map.

The scripts

Information about the script package can be found in this post. I've made a "remap" version of the recovery scripts that prompts for a .bin fuel map as soon as it runs and only asks once if you want to program.

Working with fuel maps

There are a few minor changes that need to be made to adapt the XDF's for use with fuel map .bins. I'd recommend making a copy of the original.

Open up the XDF header information. You'll see something that looks like this. XDF Header

Change the Bin Size (Hex) to 3FFF and the Base Offset (Hex) to 0, then click apply. Modified XDF Header

Click the checksums tab, and delete the map checksum. That is Nanocom specific and not required.

Pages