{"id":47,"date":"2019-03-02T21:02:32","date_gmt":"2019-03-02T21:02:32","guid":{"rendered":"http:\/\/tangentmotorsport.com\/?p=47"},"modified":"2019-03-07T15:32:27","modified_gmt":"2019-03-07T15:32:27","slug":"bosch-edc15-mapswitch","status":"publish","type":"post","link":"https:\/\/blogs.tangentmotorsport.com\/?p=47","title":{"rendered":"Bosch EDC15 MapSwitch"},"content":{"rendered":"\n<p>So for years tuners have tried various different techniques to have multiple tunes in one ECU. There are several advantages to this:<br>1. Multiple tunes with different output power levels<br>2. One tune can be tuned so that engine won&#8217;t start: sort of like an added level of security as the driver needs to switch into the tune which will start the engine<br>3. Different fuels need different ignition parameters such as ignition timing and duration to name a couple.<\/p>\n\n\n\n<p>The present method to achieve this was with methods that involved opening the ECU and changing the hardware(flash memory with double the size to have 2 tunes as an example). In this post I am going to write about my journey to achieve a software based solution on the Bosch EDC15 ECUs.<\/p>\n\n\n\n<p>Here is a video of it in action: <\/p>\n\n\n\n<figure><iframe loading=\"lazy\" src=\"https:\/\/www.youtube.com\/embed\/7tuTOx9vNXM\" allowfullscreen=\"\" width=\"560\" height=\"315\"><\/iframe><\/figure>\n<!--more Keep on Reading!-->\n\n\n\n<p> <\/p>\n\n\n\n<p>The basic idea is to have the ECU switch between the different datablocks(this is unique to the EDC15, they have 3 datablocks for different variants such as Automatic, manual and 4&#215;4). The condition to switch between datablocks could be as simple as a brake pedal and cruise control button being pressed simultaneously. The selected map can be visualized using the available outputs, such as:<br>1. Glow lamp<br>2. Engine malfunction lamp<br>3. Cruise control lamp<br>4. RPM indication in cluster<\/p>\n\n\n\n<p>I chose the last one as I found it to be a clear indicator(1000rpm for 1st datablock, 2000 for 2nd, etc)  whereas if I were to use any of the lamps, I would have to count the number of blinks(2 blinks for 2nd datablock, 3 for 3rd, etc)<\/p>\n\n\n\n<p>Now for the boring details on the magic trick:<\/p>\n\n\n\n<p>1st step is to find how the CANBUS is handled. There is a buffer in RAM in which the messages are stored before they are transmitted.<br>On edc15, finding the buffer is easy. Example: Search for sequence of  bytes: 0x280 or 0x288 or any other CAN id used by the ecu. This will point you to the code which handles comms:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ROM:00094156 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mov \u00a0 \u00a0 r5, #280h\nROM:0009415A \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mov \u00a0 \u00a0 CAN_280, r5 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ;CAN_280- RAM buffer handling id -0x280\nROM:0009415E \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 movb \u00a0 \u00a0rl4, #8\nROM:00094160 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 movb \u00a0 \u00a0byte_C743, rl4\nROM:00094164 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mov \u00a0 \u00a0 r4, #288h\nROM:00094168 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mov \u00a0 \u00a0 CAN_288, r4\nROM:0009416C \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 movb \u00a0 \u00a0rl4, #8\nROM:0009416E \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 movb \u00a0 \u00a0byte_C74F, rl4\nROM:00094172 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mov \u00a0 \u00a0 r4, #380h\nROM:00094176 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mov \u00a0 \u00a0 CAN_380, r4\nROM:0009417A \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 movb \u00a0 \u00a0rl4, #8\nROM:0009417C \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 movb \u00a0 \u00a0byte_C75B, rl4\nROM:00094180 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mov \u00a0 \u00a0 r4, #480h<\/code><\/pre>\n\n\n\n<p>Now that you&#8217;ve found the CAN buffer, I referred to the CAN section in the publicly available Bosch documents for this ECU. Below, Ive shown the CANBUS buffer handling ID 0x280 in my ECU.<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MEM_EXT:0000C744 CAN_280: \u00a0 \u00a0 \u00a0 \u00a0ds 2 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0; DATA XREF: ROM:0009415Aw\nMEM_EXT:0000C746 byte_C746: \u00a0 \u00a0 \u00a0ds 1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0; DATA XREF: ROM:000945DCw\nMEM_EXT:0000C746 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ; ROM:0009463Ew ...\nMEM_EXT:0000C747 byte_C747: \u00a0 \u00a0 \u00a0ds 1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0; DATA XREF: ROM:0009468Aw\nMEM_EXT:0000C747 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ; ROM:0009475Ew\nMEM_EXT:0000C748 can_nmot_low: \u00a0 ds 1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0; DATA XREF: ROM:0009468Ew\nMEM_EXT:0000C748 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ; ROM:00094788w\nMEM_EXT:0000C749 can_nmot_high: \u00a0ds 1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0; DATA XREF: ROM:00094692w\nMEM_EXT:0000C749 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ; ROM:00094790w\nMEM_EXT:0000C74A byte_C74A: \u00a0 \u00a0 \u00a0ds 1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0; DATA XREF: ROM:00094696w\nMEM_EXT:0000C74A \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ; ROM:00094814w ...\nMEM_EXT:0000C74B byte_C74B: \u00a0 \u00a0 \u00a0ds 1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0; DATA XREF: ROM:loc_948A0w\nMEM_EXT:0000C74B \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ; ROM:000948CAw\nMEM_EXT:0000C74C byte_C74C: \u00a0 \u00a0 \u00a0ds 1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0; DATA XREF: ROM:00094D2Ew\nMEM_EXT:0000C74C \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ; ROM:loc_94DB6w\nMEM_EXT:0000C74D byte_C74D: \u00a0 \u00a0 \u00a0ds 1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0; DATA XREF: ROM:0009469Ew\nMEM_EXT:0000C74D \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ; ROM:000947E6w\nMEM_EXT:0000C74E byte_C74E: \u00a0 \u00a0 \u00a0ds 1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0; DATA XREF: ROM:000945C0w\nMEM_EXT:0000C74F byte_C74F: \u00a0 \u00a0 \u00a0ds 1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0; DATA XREF: ROM:0009416Ew\n<\/code><\/pre>\n\n\n\n<p>To use the rpm gauge for showing the present map(or any other parameter  like boost, SOI,etc), you&#8217;ll have to modify the subroutine writing to  bytes 3 and 4 of the CAN id 0x280<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ROM:00094780 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 calls \u00a0 9, sub_94002\nROM:00094784 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 add \u00a0 \u00a0 r0, #4\nROM:00094786 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mov \u00a0 \u00a0 r9, r4\nROM:00094788 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 movb \u00a0 \u00a0can_nmot_low, rl4\nROM:0009478C \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mov \u00a0 \u00a0 r4, r9\nROM:0009478E \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ashr \u00a0 \u00a0r4, #8\nROM:00094790 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 movb \u00a0 \u00a0can_nmot_high, rl4\nROM:00094794 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mov \u00a0 \u00a0 r1, word_C420\nROM:00094798 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 add \u00a0 \u00a0 r1, word_C426\nROM:0009479C \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 cmp \u00a0 \u00a0 r1, word_F962\nROM:000947A0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 jmpr \u00a0 \u00a0cc_SGE, loc_947A6\nROM:000947A2 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mov \u00a0 \u00a0 r9, r1\nROM:000947A4 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 jmpr \u00a0 \u00a0cc_UC, loc_947AA\n<\/code><\/pre>\n\n\n\n<p>r4 contains the actual RPM. We will modify this value to whatever we want; to show the map selected in our case.<br>I inserted my call at 94784, to my routine. Its upto you to decide where  to insert this call, but make sure you don&#8217;t change the original logic.<br><br> Next step is to take inputs like clutch, brake or cruise control.<br> This can also be inferenced from the CAN buffer.<br> example: id 0x280, byte 0, bit 4 is B_kuppl(clutch pedal).<br> Find the code which writes to this bit, and you will find B_kuppl<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ROM:00094EBC \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 movb \u00a0 \u00a0rl4, word_C49A+1\nROM:00094EC0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 jmpr \u00a0 \u00a0cc_NZ, loc_94ED0\nROM:00094EC2 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 mov \u00a0 \u00a0 r4, word_14D6\nROM:00094EC6 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 movb \u00a0 \u00a0rl5, [r4]\nROM:00094EC8 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 jmpr \u00a0 \u00a0cc_NZ, loc_94ED0\nROM:00094ECA \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 movb \u00a0 \u00a0rl4, #8\nROM:00094ECC \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 orb \u00a0 \u00a0 byte_C746, rl4\n<\/code><\/pre>\n\n\n\n<p>As seen in above code, 0xC94B contains the status of the clutch pedal.  But this is not the global variable. I suppose, this is a temporary RAM  address to which the clutch switch status is copied when this subroutine starts(so that as long as the subroutine is still being executed, any change in the clutch status will not be updated. Otherwise, it&#8217;s possible that at the start of the subroutine the status of the clutch is different from that when the subroutine ends, resulting in unpredictable behavior) <br>Finding the global variable by searching for xrefs to 0xC94<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ROM:0009433E \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 movb \u00a0 \u00a0rl2, byte_C370\nROM:00094342 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 movb \u00a0 \u00a0word_C49B, rl2\n<\/code><\/pre>\n\n\n\n<p> 0xC370 is the global variable for B_kuppl.<br>Repeat this for other variables you want to use(cruise control status is on id 0x388\/0x38A and brake pedals on 0x288)<br><\/p>\n\n\n\n<p>Now, for mapswitching on EDC15, you need to change the DPP&#8217;s <br>Each datablock is referred using DPP0, DPP1 and DPP2. DPP3 is used for CAN.<br><br> datablock 1: <br> DPP0- 0x34<br> DPP1- 0x35<br> DPP2- 0x36<br><br> datablock 2:<br> DPP0- 0x38<br> DPP1- 0x39<br> DPP2- 0x3A<br><br> datablock 3:<br> DPP0- 0x3C<br> DPP1- 0x3D<br> DPP2- 0x3E<br>This is the code I wrote for switching between maps and displaying boost on RPM gauge.<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$MOD167 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ; Define C167 mode\n$SEGMENTED\t\t\t\t\t; Segemented memory mode\n$CASE\t\t\t\t\t\t; Symbols case sensitive\n$include (reg167.inc)\n\tNAME\tMINIMON\n\tASSUME\tDPP3:system\nStackData0\tSECTION DATA SYSSTACK\t\t; Data Section to reserve \n\t\t\t\t\t\t; Stack-Memory \u00a0\n\tDSB\t20H\t\t\t\t; 32 Byte \nStackData0\tENDS\t\t\t\t; End of Dummy-Section\nDriverCode0\tSECTION CODE PUBLIC 'CDRIVER'\nDriverProc \tPROC FAR\n\nmov r4, 0xc036 \u00a0;boost\nshl r4,#2\nmovb rl1,0xc370 \u00a0;b_kuppl\njnb r1.0, needle\nmovb rl1,0xc379 \u00a0;cc_cancel toggle button\njnb r1.0, xyz\nmovb rl1,#1\nmovb 0xc76e,rl1\t ;cc_off debounce\njmpr cc_uc, needle\nxyz:\nmovb rl1,0xc76e\njmpr cc_z, needle\nmovb rl1,#0\nmovb 0xc76e,rl1\nmovb rl1,0xc76f \u00a0;delay counter\njmpr cc_nz, dpp\nmovb rl1,#0x7f \u00a0; initialize delay counter so that r4 isnt updated by the ECU for atleast ~ 40ms * 0x7F= 5080ms ~ 5sec\nmovb 0xc76f,rl1\njmpr cc_uc, needle\n\ndpp:\ncmp dpp0,#0x3c\njmpr cc_eq, dppl\nmov dpp0,#0x3c\nmov dpp1,#0x3d\nmov dpp2,#0x3e\njmpr cc_uc,needle\n\ndppl:\nmov dpp0,#0x34\nmov dpp1,#0x35\nmov dpp2,#0x36\n\nneedle:\nmov rl1,0xc76f\njmpr cc_z,end1\nsubb rl1,#1\nmov 0xc76f,rl1\ncmp dpp0,#0x3c\njmpr cc_ne, n1\nmov r4,#0x2ee0\njmpr cc_uc, end1\nn1:\nmov r4,#0x3e80\nend1:\nadd r0,#4\nmov r9,r4\nrets\n\n\nDriverProc\tENDP\nDriverCode0\tENDS\n\t\tEND\n<\/code><\/pre>\n\n\n\n<p>I suggest writing your own code, as mine can be a bit difficult to follow <\/p>\n\n\n\n<p> Basically, my code does this:<br> &#8211; check if clutch is pressed, if yes then continue.<br> &#8211; check if cruice control cancel button is pressed. If yes, store 1 in a  free ram byte ( lots of free ram in this ECU, 0xC820-0xC82F is free on  all the edc15&#8217;s I&#8217;ve worked on, enough for our small subroutine) and  exit the subroutine<br>This is done to &#8220;debounce&#8221; the button press (as long as the button is pressed, no change will take place)<br>&#8211; check if the &#8220;debounce&#8221; ram byte is 1, if yes, set it to 0 and switch maps( by changing the DPP&#8217;s)<br>&#8211; To display the map selected understand how the rpm is displayed on the instrument cluster.<br>Lets say you want the rpm needle to show 2000rpm. There is a factor of 4.<br>So the transmitted CAN message for rpm is 2000*4= 8000 which corresponds to 0x1F40 in hex<br>All we need to do is replace the value in r4 with the value you want to display.<br>&#8211; Setup a counter for displaying the selected map. This is necessary  because replacing r4 with the desired value once is not enough. The main  loop takes around 40ms to execute. So after 40ms r4 will get overwritten by RPM and the needle will not show the value you wanted it to show. Look at my code for a better understanding&#8230;<br><br>Compile using Uvision or a compiler of your choice. Load the output hex  file into a hexeditor, search where your code begins, and copy it to a free  space in your flash. Then insert a call to your new function. I chose to insert my call at 0x94784(0x14784 in Hexeditor) Free space in my file &#8211; 0x1A000 which translates to 0x9A000 <br>Hence, opcode for call: DA 09 00 A0<\/p>\n\n\n\n<p>PS: Yes, the posts on <a href=\"http:\/\/nefariousmotorsports.com\/forum\/index.php?topic=12637.0title=\">nefmoto<\/a> and <a href=\"http:\/\/www.ecuconnections.com\/forum\/viewtopic.php?f=211&amp;t=51373\">ecuconnections<\/a>are by me. I am @nihalot \ud83d\ude42<br><\/p>\n\n\n\n<p><br><\/p>\n","protected":false},"excerpt":{"rendered":"<p>So for years tuners have tried various different techniques to have multiple tunes in one ECU. There are several advantages to this:1. Multiple tunes with different output power levels2. One tune can be tuned so that engine won&#8217;t start: sort of like an added level of security as the driver needs to switch into the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[5],"tags":[19,37,31,30,34,35,29,33,24,36,32,12,14],"class_list":["post-47","post","type-post","status-publish","format-standard","hentry","category-re","tag-audi","tag-cruise-control","tag-disassembly","tag-ecu","tag-edc15","tag-edc16","tag-engine","tag-engineering","tag-mapswitch","tag-multimap","tag-reverse-engineering","tag-skoda","tag-vw"],"aioseo_notices":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Bosch EDC15 MapSwitch -<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blogs.tangentmotorsport.com\/?p=47\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Bosch EDC15 MapSwitch -\" \/>\n<meta property=\"og:description\" content=\"So for years tuners have tried various different techniques to have multiple tunes in one ECU. There are several advantages to this:1. Multiple tunes with different output power levels2. One tune can be tuned so that engine won&#8217;t start: sort of like an added level of security as the driver needs to switch into the [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blogs.tangentmotorsport.com\/?p=47\" \/>\n<meta property=\"article:published_time\" content=\"2019-03-02T21:02:32+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-03-07T15:32:27+00:00\" \/>\n<meta name=\"author\" content=\"nihalot\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"nihalot\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blogs.tangentmotorsport.com\/?p=47\",\"url\":\"https:\/\/blogs.tangentmotorsport.com\/?p=47\",\"name\":\"Bosch EDC15 MapSwitch -\",\"isPartOf\":{\"@id\":\"https:\/\/blogs.tangentmotorsport.com\/#website\"},\"datePublished\":\"2019-03-02T21:02:32+00:00\",\"dateModified\":\"2019-03-07T15:32:27+00:00\",\"author\":{\"@id\":\"https:\/\/blogs.tangentmotorsport.com\/#\/schema\/person\/d90d31ae9d843a5f8308048a2f2d19f0\"},\"breadcrumb\":{\"@id\":\"https:\/\/blogs.tangentmotorsport.com\/?p=47#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blogs.tangentmotorsport.com\/?p=47\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blogs.tangentmotorsport.com\/?p=47#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blogs.tangentmotorsport.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Bosch EDC15 MapSwitch\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blogs.tangentmotorsport.com\/#website\",\"url\":\"https:\/\/blogs.tangentmotorsport.com\/\",\"name\":\"\",\"description\":\"Custom Code for ECUs\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blogs.tangentmotorsport.com\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blogs.tangentmotorsport.com\/#\/schema\/person\/d90d31ae9d843a5f8308048a2f2d19f0\",\"name\":\"nihalot\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blogs.tangentmotorsport.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cbff731b9289c11fc7eeba59d92f76462697573bbfb1b8b22fe4e2a20558750c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cbff731b9289c11fc7eeba59d92f76462697573bbfb1b8b22fe4e2a20558750c?s=96&d=mm&r=g\",\"caption\":\"nihalot\"},\"url\":\"https:\/\/blogs.tangentmotorsport.com\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Bosch EDC15 MapSwitch -","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blogs.tangentmotorsport.com\/?p=47","og_locale":"en_US","og_type":"article","og_title":"Bosch EDC15 MapSwitch -","og_description":"So for years tuners have tried various different techniques to have multiple tunes in one ECU. There are several advantages to this:1. Multiple tunes with different output power levels2. One tune can be tuned so that engine won&#8217;t start: sort of like an added level of security as the driver needs to switch into the [&hellip;]","og_url":"https:\/\/blogs.tangentmotorsport.com\/?p=47","article_published_time":"2019-03-02T21:02:32+00:00","article_modified_time":"2019-03-07T15:32:27+00:00","author":"nihalot","twitter_card":"summary_large_image","twitter_misc":{"Written by":"nihalot","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blogs.tangentmotorsport.com\/?p=47","url":"https:\/\/blogs.tangentmotorsport.com\/?p=47","name":"Bosch EDC15 MapSwitch -","isPartOf":{"@id":"https:\/\/blogs.tangentmotorsport.com\/#website"},"datePublished":"2019-03-02T21:02:32+00:00","dateModified":"2019-03-07T15:32:27+00:00","author":{"@id":"https:\/\/blogs.tangentmotorsport.com\/#\/schema\/person\/d90d31ae9d843a5f8308048a2f2d19f0"},"breadcrumb":{"@id":"https:\/\/blogs.tangentmotorsport.com\/?p=47#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blogs.tangentmotorsport.com\/?p=47"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blogs.tangentmotorsport.com\/?p=47#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blogs.tangentmotorsport.com\/"},{"@type":"ListItem","position":2,"name":"Bosch EDC15 MapSwitch"}]},{"@type":"WebSite","@id":"https:\/\/blogs.tangentmotorsport.com\/#website","url":"https:\/\/blogs.tangentmotorsport.com\/","name":"","description":"Custom Code for ECUs","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blogs.tangentmotorsport.com\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blogs.tangentmotorsport.com\/#\/schema\/person\/d90d31ae9d843a5f8308048a2f2d19f0","name":"nihalot","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blogs.tangentmotorsport.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/cbff731b9289c11fc7eeba59d92f76462697573bbfb1b8b22fe4e2a20558750c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cbff731b9289c11fc7eeba59d92f76462697573bbfb1b8b22fe4e2a20558750c?s=96&d=mm&r=g","caption":"nihalot"},"url":"https:\/\/blogs.tangentmotorsport.com\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/blogs.tangentmotorsport.com\/index.php?rest_route=\/wp\/v2\/posts\/47","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.tangentmotorsport.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.tangentmotorsport.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.tangentmotorsport.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.tangentmotorsport.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=47"}],"version-history":[{"count":0,"href":"https:\/\/blogs.tangentmotorsport.com\/index.php?rest_route=\/wp\/v2\/posts\/47\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.tangentmotorsport.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=47"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.tangentmotorsport.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=47"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.tangentmotorsport.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=47"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}