From a4c9987e9933ae0593b27e86cb8537a19f57dbfd Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Fri, 28 Oct 2016 20:03:31 +1100 Subject: [PATCH 1/5] Add worst case fallback position to baro reading --- speeduino.ino | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/speeduino.ino b/speeduino.ino index 705897d..8b04c3f 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -238,7 +238,13 @@ void setup() currentStatus.baro = currentStatus.MAP; EEPROM.update(EEPROM_LAST_BARO, currentStatus.baro); } - else { currentStatus.baro = EEPROM.read(EEPROM_LAST_BARO); } //last baro correction + else + { + //Attempt to use the last known good baro reading from EEPROM + if ((EEPROM.read(EEPROM_LAST_BARO) >= BARO_MIN) && (EEPROM.read(EEPROM_LAST_BARO) <= BARO_MAX)) //Make sure it's not invalid (Possible on first run etc) + { currentStatus.baro = EEPROM.read(EEPROM_LAST_BARO); } //last baro correction + else { currentStatus.baro = 100; } //Final fall back position. + } //Perform all initialisations initialiseSchedulers(); From f0dcb0c7560f8a3d3ea0aff56b7c8f08aa1ca418 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Tue, 1 Nov 2016 10:11:15 +1100 Subject: [PATCH 2/5] Minor sequential fixes --- reference/speeduino.ini | 8 ++++++-- speeduino.ino | 20 ++++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/reference/speeduino.ini b/reference/speeduino.ini index 750be0c..45fe8ef 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -381,9 +381,13 @@ page = 6 boostKI = scalar, U08, 58, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte) boostKD = scalar, U08, 59, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte) - lnchPullRes = bits, U08, 60 [0:1], "Float" , "Pullup", "INVALID", "INVALID" + lnchPullRes = bits, U08, 60, [0:1], "Float" , "Pullup", "INVALID", "INVALID" fuelTrimEnabled= bits, U08, 60, [2:2], "No", "Yes" - unused6-60 = bits, U08, 60, [3:7], "ONE", "INVALID" + unused6-60d = bits, U08, 60, [3:3], "ONE", "INVALID" + unused6-60e = bits, U08, 60, [4:4], "ONE", "INVALID" + unused6-60f = bits, U08, 60, [5:5], "ONE", "INVALID" + unused6-60g = bits, U08, 60, [6:6], "ONE", "INVALID" + unused6-60h = bits, U08, 60, [7:7], "ONE", "INVALID" unused6-61 = scalar, U08, 61, "RPM", 100.0, 0.0, 100, 25500, 0 unused6-62 = scalar, U08, 62, "RPM", 100.0, 0.0, 100, 25500, 0 unused6-63 = scalar, U08, 63, "RPM", 100.0, 0.0, 100, 25500, 0 diff --git a/speeduino.ino b/speeduino.ino index 8b04c3f..ca9bb26 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -524,7 +524,7 @@ void setup() channel1InjDegrees = 0; channel2InjDegrees = channel2IgnDegrees; //Set to the same as the ignition degrees (Means there's no need for another if to check for oddfire) } - else { channel1InjDegrees = channel2InjDegrees = 0; } //For simultaneous, all squirts happen at the same time + if (!configPage1.injTiming) { channel1InjDegrees = channel2InjDegrees = 0; } //For simultaneous, all squirts happen at the same time channel1InjEnabled = true; channel2InjEnabled = true; @@ -558,7 +558,7 @@ void setup() CRANK_ANGLE_MAX_INJ = 720; req_fuel_uS = req_fuel_uS * 2; } - else { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = 0; } //For simultaneous, all squirts happen at the same time + if (!configPage1.injTiming) { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = 0; } //For simultaneous, all squirts happen at the same time channel1InjEnabled = true; channel2InjEnabled = true; @@ -605,7 +605,7 @@ void setup() CRANK_ANGLE_MAX_INJ = 720; req_fuel_uS = req_fuel_uS * 2; } - else { channel1InjDegrees = channel2InjDegrees = 0; } //For simultaneous, all squirts happen at the same time + if (!configPage1.injTiming) { channel1InjDegrees = channel2InjDegrees = 0; } //For simultaneous, all squirts happen at the same time channel1InjEnabled = true; channel2InjEnabled = true; @@ -628,7 +628,7 @@ void setup() } //For alternatiing injection, the squirt occurs at different times for each channel - if(configPage1.injLayout == INJ_SEMISEQUENTIAL) + if(configPage1.injLayout == INJ_SEMISEQUENTIAL || configPage1.injLayout == INJ_PAIRED) { channel1InjDegrees = 0; channel2InjDegrees = 72; @@ -646,7 +646,7 @@ void setup() CRANK_ANGLE_MAX_INJ = 720; } - else { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = channel4InjDegrees = channel5InjDegrees = 0; } //For simultaneous, all squirts happen at the same time + if (!configPage1.injTiming) { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = channel4InjDegrees = channel5InjDegrees = 0; } //For simultaneous, all squirts happen at the same time channel1InjEnabled = true; channel2InjEnabled = true; @@ -660,13 +660,15 @@ void setup() channel3IgnDegrees = 240; //For alternatiing injection, the squirt occurs at different times for each channel - if(configPage1.injLayout == INJ_SEMISEQUENTIAL || configPage1.injLayout == INJ_SEQUENTIAL) //No full sequential for more than 4 cylinders + /* + if(configPage1.injLayout == INJ_SEMISEQUENTIAL || configPage1.injLayout == INJ_SEQUENTIAL || configPage1.injLayout == INJ_PAIRED) //No full sequential for more than 4 cylinders { channel1InjDegrees = 0; channel2InjDegrees = 120; channel3InjDegrees = 240; } - else { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = 0; } //For simultaneous, all squirts happen at the same time + */ + if (!configPage1.injTiming) { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = 0; } //For simultaneous, all squirts happen at the same time configPage1.injLayout = 0; //This is a failsafe. We can never run semi-sequential with more than 4 cylinders @@ -681,6 +683,7 @@ void setup() channel4IgnDegrees = 270; //For alternatiing injection, the squirt occurs at different times for each channel + /* if(configPage1.injLayout == INJ_SEMISEQUENTIAL || configPage1.injTiming == INJ_SEQUENTIAL) //No full sequential for more than 4 cylinders { channel1InjDegrees = 0; @@ -688,7 +691,8 @@ void setup() channel3InjDegrees = 180; channel4InjDegrees = 270; } - else { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = channel4InjDegrees = 0; } //For simultaneous, all squirts happen at the same time + */ + if (!configPage1.injTiming) { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = channel4InjDegrees = 0; } //For simultaneous, all squirts happen at the same time configPage1.injLayout = 0; //This is a failsafe. We can never run semi-sequential with more than 4 cylinders From 30a48dc364d5f16dc3e2450dea356f777ead8acc Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Tue, 1 Nov 2016 12:37:00 +1100 Subject: [PATCH 3/5] Fixes for trim table comms misalignment --- comms.ino | 23 ++++++++++++----------- globals.h | 2 +- reference/speeduino.ini | 18 +++++++++++------- storage.h | 22 +++++++++++----------- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/comms.ino b/comms.ino index ceaa055..0d90560 100644 --- a/comms.ino +++ b/comms.ino @@ -678,34 +678,35 @@ void sendPage(bool useChar) break; } case seqFuelPage: - { + { if(useChar) { currentTable = trim1Table; currentTitleIndex = 121; + return; //Do.... Something? } else { //Need to perform a translation of the values[MAP/TPS][RPM] into the MS expected format byte response[192]; //Bit hacky, but the size is: (6x6 + 6 + 6) * 4 = 192 - + //trim1 table for (int x = 0; x < 36; x++) { response[x] = trim1Table.values[5 - x / 6][x % 6]; } for (int x = 36; x < 42; x++) { response[x] = byte(trim1Table.axisX[(x - 36)] / 100); } for (int y = 42; y < 48; y++) { response[y] = byte(trim1Table.axisY[5 - (y - 42)]); } //trim2 table - for (int x = 48; x < 84; x++) { response[x] = trim2Table.values[5 - x / 6][x % 6]; } - for (int x = 84; x < 90; x++) { response[x] = byte(trim2Table.axisX[(x - 84)] / 100); } - for (int y = 90; y < 96; y++) { response[y] = byte(trim2Table.axisY[5 - (y - 90)]); } + for (int x = 0; x < 36; x++) { response[x + 48] = trim2Table.values[5 - x / 6][x % 6]; } + for (int x = 36; x < 42; x++) { response[x + 48] = byte(trim2Table.axisX[(x - 36)] / 100); } + for (int y = 42; y < 48; y++) { response[y + 48] = byte(trim2Table.axisY[5 - (y - 42)]); } //trim3 table - for (int x = 96; x < 132; x++) { response[x] = trim3Table.values[5 - x / 6][x % 6]; } - for (int x = 132; x < 138; x++) { response[x] = byte(trim3Table.axisX[(x - 132)] / 100); } - for (int y = 138; y < 144; y++) { response[y] = byte(trim3Table.axisY[5 - (y - 138)]); } + for (int x = 0; x < 36; x++) { response[x + 96] = trim3Table.values[5 - x / 6][x % 6]; } + for (int x = 36; x < 42; x++) { response[x + 96] = byte(trim3Table.axisX[(x - 36)] / 100); } + for (int y = 42; y < 48; y++) { response[y + 96] = byte(trim3Table.axisY[5 - (y - 42)]); } //trim4 table - for (int x = 144; x < 180; x++) { response[x] = trim4Table.values[5 - x / 6][x % 6]; } - for (int x = 180; x < 186; x++) { response[x] = byte(trim4Table.axisX[(x - 180)] / 100); } - for (int y = 186; y < 192; y++) { response[y] = byte(trim4Table.axisY[5 - (y - 186)]); } + for (int x = 0; x < 36; x++) { response[x + 144] = trim4Table.values[5 - x / 6][x % 6]; } + for (int x = 36; x < 42; x++) { response[x + 144] = byte(trim4Table.axisX[(x - 36)] / 100); } + for (int y = 42; y < 48; y++) { response[y + 144] = byte(trim4Table.axisY[5 - (y - 42)]); } Serial.write((byte *)&response, sizeof(response)); return; } diff --git a/globals.h b/globals.h index e967511..3f4d3bc 100644 --- a/globals.h +++ b/globals.h @@ -360,7 +360,7 @@ struct config3 { byte boostKD; byte lnchPullRes : 2; - bool fuelTrimEnabled : 1; + byte fuelTrimEnabled : 1; byte unused60 : 5; byte unused61; byte unused62; diff --git a/reference/speeduino.ini b/reference/speeduino.ini index 45fe8ef..a21b7e2 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -163,6 +163,11 @@ page = 2 alternate = bits, U08, 26, [0:0], "Simultaneous", "Alternating" multiplyMAP= bits, U08, 26, [1:1], "No", "Yes" includeAFR = bits, U08, 26, [2:2], "No", "Yes" + unused2-26d= bits, U08, 26, [3:3], "No", "Yes" + unused2-26e= bits, U08, 26, [4:4], "No", "Yes" + unused2-26f= bits, U08, 26, [5:5], "No", "Yes" + unused2-26g= bits, U08, 26, [6:6], "No", "Yes" + unused2-26h= bits, U08, 26, [7:7], "No", "Yes" injOpen = scalar, U08, 27, "ms", 0.1, 0.0, 0.1, 25.5, 1 inj1Ang = scalar, U16, 28, "deg", 1.0, 0.0, 0.0, 360, 0 inj2Ang = scalar, U16, 30, "deg", 1.0, 0.0, 0.0, 360, 0 @@ -185,7 +190,7 @@ page = 2 flexEnabled= bits, U08, 38, [1:1], "Off", "On" algorithm = bits, U08, 38, [2:2], "Speed Density", "Alpha-N" baroCorr = bits, U08, 38, [3:3], "Off", "On" - injLayout = bits, U08, 38, [4:5], "Paired", "Semi-Sequential", "INVALID", "Sequential" + injLayout = bits, U08, 38, [4:5], "Paired", "Semi-Sequential", "Bank", "Sequential" canEnable = bits, U08, 38, [6:6], "Disable", "Enable" primePulse = scalar, U08, 39, "ms", 0.1, 0.0, 0.0, 25.5, 1 @@ -735,7 +740,6 @@ menuDialog = main ; dialogs can be nested and can be mixed with fields dialog = engine_constants_southwest, "Speeduino Board" - topicHelp = Mhelp field = "Stoichiometric ratio", stoich field = "Injector Layout", injLayout, { nCylinders <= 4 } field = "Board Layout", pinLayout @@ -752,7 +756,7 @@ menuDialog = main dialog = engine_constants_east, "" panel = engine_constants_northeast, North - field = "", South + field = "" dialog = engine_constants, "", border panel = engine_constants_west, West @@ -1197,7 +1201,7 @@ menuDialog = main upDownLabel = "HIGHER", "LOWER" ;--------- Sequential fuel trim maps ----------- - table = fuelTrimTable1Tbl, fuelTrimTable1Map, "Fuel trim Table", 9 + table = fuelTrimTable1Tbl, fuelTrimTable1Map, "Fuel trim Table 1", 9 topicHelp = "http://speeduino.com/wiki/index.php/Tuning" xBins = fuelTrim1rpmBins, rpm #if SPEED_DENSITY @@ -1211,7 +1215,7 @@ menuDialog = main gridOrient = 250, 0, 340 ; Space 123 rotation of grid in degrees. upDownLabel = "(RICHER)", "(LEANER)" - table = fuelTrimTable2Tbl, fuelTrimTable2Map, "Fuel trim Table", 9 + table = fuelTrimTable2Tbl, fuelTrimTable2Map, "Fuel trim Table 2", 9 topicHelp = "http://speeduino.com/wiki/index.php/Tuning" xBins = fuelTrim2rpmBins, rpm #if SPEED_DENSITY @@ -1225,7 +1229,7 @@ menuDialog = main gridOrient = 250, 0, 340 ; Space 123 rotation of grid in degrees. upDownLabel = "(RICHER)", "(LEANER)" - table = fuelTrimTable3Tbl, fuelTrimTable3Map, "Fuel trim Table", 9 + table = fuelTrimTable3Tbl, fuelTrimTable3Map, "Fuel trim Table 3", 9 topicHelp = "http://speeduino.com/wiki/index.php/Tuning" xBins = fuelTrim3rpmBins, rpm #if SPEED_DENSITY @@ -1239,7 +1243,7 @@ menuDialog = main gridOrient = 250, 0, 340 ; Space 123 rotation of grid in degrees. upDownLabel = "(RICHER)", "(LEANER)" - table = fuelTrimTable4Tbl, fuelTrimTable4Map, "Fuel trim Table", 9 + table = fuelTrimTable4Tbl, fuelTrimTable4Map, "Fuel trim Table 4", 9 topicHelp = "http://speeduino.com/wiki/index.php/Tuning" xBins = fuelTrim4rpmBins, rpm #if SPEED_DENSITY diff --git a/storage.h b/storage.h index d929aff..ac5c599 100644 --- a/storage.h +++ b/storage.h @@ -73,6 +73,7 @@ Current layout of EEPROM data (Version 3) is as follows (All sizes are in bytes) #define EEPROM_CONFIG8_XBINS2 1275 #define EEPROM_CONFIG8_YBINS2 1283 #define EEPROM_CONFIG8_END 1291 + #define EEPROM_CONFIG9_XSIZE1 1291 #define EEPROM_CONFIG9_YSIZE1 1292 #define EEPROM_CONFIG9_MAP1 1293 @@ -83,17 +84,16 @@ Current layout of EEPROM data (Version 3) is as follows (All sizes are in bytes) #define EEPROM_CONFIG9_MAP2 1343 #define EEPROM_CONFIG9_XBINS2 1379 #define EEPROM_CONFIG9_YBINS2 1385 -//BELOW VALUES NOT YET RIGHT!! -#define EEPROM_CONFIG9_XSIZE3 1341 -#define EEPROM_CONFIG9_YSIZE3 1342 -#define EEPROM_CONFIG9_MAP3 1343 -#define EEPROM_CONFIG9_XBINS3 1379 -#define EEPROM_CONFIG9_YBINS3 1385 -#define EEPROM_CONFIG9_XSIZE4 1341 -#define EEPROM_CONFIG9_YSIZE4 1342 -#define EEPROM_CONFIG9_MAP4 1343 -#define EEPROM_CONFIG9_XBINS4 1379 -#define EEPROM_CONFIG9_YBINS4 1385 +#define EEPROM_CONFIG9_XSIZE3 1391 +#define EEPROM_CONFIG9_YSIZE3 1392 +#define EEPROM_CONFIG9_MAP3 1393 +#define EEPROM_CONFIG9_XBINS3 1429 +#define EEPROM_CONFIG9_YBINS3 1435 +#define EEPROM_CONFIG9_XSIZE4 1441 +#define EEPROM_CONFIG9_YSIZE4 1442 +#define EEPROM_CONFIG9_MAP4 1443 +#define EEPROM_CONFIG9_XBINS4 1479 +#define EEPROM_CONFIG9_YBINS4 1485 //Calibration data is stored at the end of the EEPROM (This is in case any further calibration tables are needed as they are large blocks) #define EEPROM_LAST_BARO 2558 From 7aeff0cbdaaa5bdab55007eca607ee37dd392a35 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Tue, 1 Nov 2016 23:19:16 +1100 Subject: [PATCH 4/5] Further memory fixes for sequential trims --- comms.ino | 20 +++++++++++--------- globals.h | 1 + reference/speeduino.ini | 33 +++++++++++++++++---------------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/comms.ino b/comms.ino index 0d90560..0febea1 100644 --- a/comms.ino +++ b/comms.ino @@ -303,7 +303,7 @@ void receiveValue(int valueOffset, byte newValue) //For some reason, TunerStudio is sending offsets greater than the maximum page size. I'm not sure if it's their bug or mine, but the fix is to only update the config page if the offset is less than the maximum size if (valueOffset < page_size) { - *((byte *)pnt_configPage + (byte)valueOffset) = newValue; //Need to subtract 80 because the map and bins (Which make up 80 bytes) aren't part of the config pages + *((byte *)pnt_configPage + (byte)valueOffset) = newValue; } break; @@ -432,6 +432,7 @@ void receiveValue(int valueOffset, byte newValue) else if (valueOffset < 192) { valueOffset = valueOffset - 186; trim4Table.axisY[(5 - valueOffset)] = int(newValue) * TABLE_LOAD_MULTIPLIER; } //New value is on the Y (Load) axis of the table break; + default: break; } @@ -666,11 +667,11 @@ void sendPage(bool useChar) //Boost table for (int x = 0; x < 64; x++) { response[x] = boostTable.values[7 - x / 8][x % 8]; } - for (int x = 64; x < 72; x++) { response[x] = byte(boostTable.axisX[(x - 64)] / 100); } + for (int x = 64; x < 72; x++) { response[x] = byte(boostTable.axisX[(x - 64)] / TABLE_RPM_MULTIPLIER); } for (int y = 72; y < 80; y++) { response[y] = byte(boostTable.axisY[7 - (y - 72)]); } //VVT table for (int x = 0; x < 64; x++) { response[x + 80] = vvtTable.values[7 - x / 8][x % 8]; } - for (int x = 64; x < 72; x++) { response[x + 80] = byte(vvtTable.axisX[(x - 64)] / 100); } + for (int x = 64; x < 72; x++) { response[x + 80] = byte(vvtTable.axisX[(x - 64)] / TABLE_RPM_MULTIPLIER); } for (int y = 72; y < 80; y++) { response[y + 80] = byte(vvtTable.axisY[7 - (y - 72)]); } Serial.write((byte *)&response, sizeof(response)); return; @@ -792,12 +793,12 @@ void sendPage(bool useChar) //MS format has origin (0,0) in the bottom left corner, we use the top left for efficiency reasons byte response[map_page_size]; - for (int x = 0; x < 256; x++) { response[x] = currentTable.values[15 - x / 16][x % 16]; if ( (x & 15) == 1) { loop(); } } //This is slightly non-intuitive, but essentially just flips the table vertically (IE top line becomes the bottom line etc). Columns are unchanged. Every 16 loops, manually call loop() to avoid potential misses - loop(); - for (int x = 256; x < 272; x++) { response[x] = byte(currentTable.axisX[(x - 256)] / 100); } //RPM Bins for VE table (Need to be dvidied by 100) - loop(); + for (int x = 0; x < 256; x++) { response[x] = currentTable.values[15 - x / 16][x % 16]; } //This is slightly non-intuitive, but essentially just flips the table vertically (IE top line becomes the bottom line etc). Columns are unchanged. Every 16 loops, manually call loop() to avoid potential misses + //loop(); + for (int x = 256; x < 272; x++) { response[x] = byte(currentTable.axisX[(x - 256)] / TABLE_RPM_MULTIPLIER); } //RPM Bins for VE table (Need to be dvidied by 100) + //loop(); for (int y = 272; y < 288; y++) { response[y] = byte(currentTable.axisY[15 - (y - 272)]); } //MAP or TPS bins for VE table - loop(); + //loop(); Serial.write((byte *)&response, sizeof(response)); } } @@ -820,8 +821,9 @@ void sendPage(bool useChar) for (byte x = 0; x < page_size; x++) { response[x] = *((byte *)pnt_configPage + x); //Each byte is simply the location in memory of the configPage + the offset + the variable number (x) - if ( (x & 31) == 1) { loop(); } //Every 32 loops, do a manual call to loop() to ensure that there is no misses + //if ( (x & 31) == 1) { loop(); } //Every 32 loops, do a manual call to loop() to ensure that there is no misses } + Serial.write((byte *)&response, sizeof(response)); // } } diff --git a/globals.h b/globals.h index 3f4d3bc..9631c93 100644 --- a/globals.h +++ b/globals.h @@ -226,6 +226,7 @@ struct config1 { byte baroCorr : 1; byte injLayout : 2; byte canEnable : 1; //is can interface enabled + byte unused2_38h : 1; byte primePulse; byte dutyLim; diff --git a/reference/speeduino.ini b/reference/speeduino.ini index a21b7e2..1a242e9 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -97,7 +97,7 @@ pageSize = 288, 64, 288, 64, 288, 64, 64, 160, 192 pageActivationDelay = 10 pageActivate = "P\001", "P\002", "P\003", "P\004", "P\005", "P\006", "P\007", "P\010", "P\011" - pageReadCommand = "V", "V", "V", "V", "V", "V", "V", "V", "V" + pageReadCommand = "V", "V", "V", "V", "V", "V", "V", "V", "V" pageValueWrite = "W%2o%v", "W%o%v", "W%2o%v", "W%o%v", "W%2o%v", "W%o%v", "W%o%v", "W%o%v", "W%o%v" ; pageChunkWrite = "" ; No chunk write for standard MS @@ -106,8 +106,8 @@ delayAfterPortOpen=1000 ;validateArrayBounds = true blockReadTimeout = 2000 - ;tsWriteBlocks = on -; writeBlocks = on + ;tsWriteBlocks = off + ;writeBlocks = off interWriteDelay = 10 ;Page 1 is the fuel map and axis bins only @@ -138,7 +138,7 @@ page = 2 aseCount = scalar, U08, 3, "s", 1.0, 0.0, 0.0, 255, 0 wueRates = array, U08, 4, [10], "%", 1.0, 0.0, 0.0, 255, 0 crankingPct= scalar, U08, 14, "%", 1.0, 0.0, 0.0, 255, 0 - pinLayout = bits, U08, 15, [0:7], "Speeduino v0.1", "Speeduino v0.2", "Speeduino v0.3", "Speeduino v0.4", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "NA6 MX5 PNP", "Turtana PCB", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Plazomat I/O 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Daz V6 Shield 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", + pinLayout = bits, U08, 15, [0:7], "Speeduino v0.1", "Speeduino v0.2", "Speeduino v0.3", "Speeduino v0.4", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "NA6 MX5 PNP", "Turtana PCB", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Plazomat I/O 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Daz V6 Shield 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" tachoPin = bits, U08, 16, [0:5], "Board Default", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" unused2-16f= bits, U08, 16, [6:7], "One", "Two", "INVALID", "INVALID" tdePct = scalar, U08, 17, "ms", 0.1, 0.0, 0.0, 25.5, 1 @@ -183,20 +183,21 @@ page = 2 ; Config2 cltType = bits, U08, 37, [0:1], "GM", "Unknown1", "Unknown2", "Unknown3" matType = bits, U08, 37, [2:3], "GM", "Unknown1", "Unknown2", "Unknown3" - nInjectors = bits, U08, 37, [4:7+1] + nInjectors = bits, U08, 37, [4:7], "INVALID","1","2","3","4","INVALID","6","INVALID","8","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID" ; Config3 engineType = bits, U08, 38, [0:0], "Even fire", "Odd fire" flexEnabled= bits, U08, 38, [1:1], "Off", "On" algorithm = bits, U08, 38, [2:2], "Speed Density", "Alpha-N" baroCorr = bits, U08, 38, [3:3], "Off", "On" - injLayout = bits, U08, 38, [4:5], "Paired", "Semi-Sequential", "Bank", "Sequential" + injLayout = bits, U08, 38, [4:5], "Paired", "Semi-Sequential", "INVALID", "Sequential" canEnable = bits, U08, 38, [6:6], "Disable", "Enable" + unused2-38h= bits, U08, 38, [7:7], "No", "Yes" primePulse = scalar, U08, 39, "ms", 0.1, 0.0, 0.0, 25.5, 1 dutyLim = scalar, U08, 40, "%", 1.0, 0.0, 0.0, 100.0, 0 - unused41 = scalar, U08, 41, "RPM", 100.0, 0.0, 100, 25500, 0 - egoSwitch = scalar, U08, 42, "v", 0.0196, 0.0, 0.0, 5.0, 3 + unused41 = scalar, U08, 41, "RPM", 100.0, 0.0, 100, 25500, 0 + unused42 = scalar, U08, 42, "RPM", 100.0, 0.0, 100, 25500, 0 taeColdM = scalar, U08, 43, "%", 1.0, 0.0, 0.0, 250.0, 0 tpsMin = scalar, U08, 44, "ADC", 1.0, 0.0, 0.0, 255.0, 0 tpsMax = scalar, U08, 45, "ADC", 1.0, 0.0, 0.0, 255.0, 0 @@ -204,9 +205,9 @@ page = 2 mapMax = scalar, U16, 47, "kpa", 1.0, 0.0, 0.0, 25500, 0 fpPrime = scalar, U08, 49, "s", 1.0, 0.0, 0.0, 255.0, 0 stoich = scalar, U08, 50, ":1", 0.1, 0.0, 0.0, 25.5, 1 - oddfire2 = scalar, U16, 51, "", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte) - oddfire3 = scalar, U16, 53, "", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte) - oddfire4 = scalar, U16, 55, "", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte) + oddfire2 = scalar, U16, 51, "deg", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte) + oddfire3 = scalar, U16, 53, "deg", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte) + oddfire4 = scalar, U16, 55, "deg", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte) unused2-57 = scalar, U08, 57, "RPM", 100.0, 0.0, 100, 25500, 0 unused2-58 = scalar, U08, 58, "RPM", 100.0, 0.0, 100, 25500, 0 unused2-59 = scalar, U08, 59, "RPM", 100.0, 0.0, 100, 25500, 0 @@ -649,7 +650,7 @@ menuDialog = main ;subMenu = battcalib, "Calibrate Battery Voltage" ;subMenu = std_separator ;---------------------------------------------- ;subMenu = flash_unlock, "Un/Lock calibrations" - subMenu = std_ms2gentherm, "Calibrate T&hermistor Tables", 0 ;, {flashlock} + subMenu = std_ms2gentherm, "Calibrate Thermistor Tables", 0 ;, {flashlock} subMenu = std_ms2geno2, "Calibrate &AFR Table", 0;, {flashlock} menuDialog = main @@ -673,14 +674,14 @@ menuDialog = main nInjectors = "Number of primary injectors." mapSample = "The method used for calculating the MAP reading\nFor 1-2 Cylinder engines, Cycle Minimum is recommended.\nFor more than 2 cylinders Cycle Average is recommended" stoich = "The stoichiometric ration of the fuel being used. For flex fuel, choose the primary fuel" - injLayout = "The injector layout and timing to be used. Options are: \n 1. Paired - 2 injectors per output. Outputs active is equal to half the number of cylinders. Outputs are timed over 1 crank revolution. \n 2. Semi-sequential: Same as paired except that injector channels are mirrored (1&4, 2&3) meaning the number of outputs used are equal to the number of cylinders. Only valid for 4 cylinders or less. \n 3. Banked: 2 outputs only used. \n 4. Sequential: 1 injector per output and outputs used equals the number of cylinders. Injection is timed over full cycle. + injLayout = "The injector layout and timing to be used. Options are: \n 1. Paired - 2 injectors per output. Outputs active is equal to half the number of cylinders. Outputs are timed over 1 crank revolution. \n 2. Semi-sequential: Same as paired except that injector channels are mirrored (1&4, 2&3) meaning the number of outputs used are equal to the number of cylinders. Only valid for 4 cylinders or less. \n 3. Banked: 2 outputs only used. \n 4. Sequential: 1 injector per output and outputs used equals the number of cylinders. Injection is timed over full cycle. " TrigPattern = "The type of input trigger decoder to be used." numteeth = "Number of teeth on Primary Wheel." TrigSpeed = "Primary trigger speed." onetwo = "Number of Missing teeth on Primary Wheel." TrigAng = "The Angle ATDC when tooth No:1 on the primary wheel passes the primary sensor." - TrigAngMul = "A multiplier used by non-360 degree tooth wheels (i.e. Wheels where the tooth count doesn't divide evenly into 360. Usage: (360 * ) / tooth_count = Whole number + TrigAngMul = "A multiplier used by non-360 degree tooth wheels (i.e. Wheels where the tooth count doesn't divide evenly into 360. Usage: (360 * ) / tooth_count = Whole number" StgCycles = "The number of revolutions that will be skipped during cranking before the injectors and coils are fired." TrigEdge = "The Trigger edge of the primary sensor.\nLeading.\nTrailing." TrigFilter = "Tuning of the trigger filter algorithm. The more aggressive the setting, the more noise will be removed, however this increases the chance of some true readings being filtered out (False positive). Medium is safe for most setups. Only select 'Aggressive' if no other options are working" @@ -1019,7 +1020,7 @@ menuDialog = main panel = inj_trim4TblTitle dialog = inj_trimad,"Injector Cyl 1-4 Trims", yAxis - field = "Individual fuel trim enabled", fuelTrimEnabled + field = "Individual fuel trim enabled", fuelTrimEnabled, { injLayout == 3 } panel = inj_trimadt, North panel = inj_trimadb, South @@ -1531,7 +1532,7 @@ menuDialog = main ;cycleTime = { 60000.0 / rpm * (2.0-twoStroke) } cycleTime = { 60000.0 / rpm } - nSquirts = { nCylinders/divider } + ;nSquirts = { nCylinders/divider } dutyCycle = { 100.0*pulseWidth/cycleTime } boostCutOut = { boostCutFuel || boostCutSpark } From f9e226d828dd712a0c6deac6cc5c97d395eaa12a Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Wed, 2 Nov 2016 12:13:17 +1100 Subject: [PATCH 5/5] Complete and tested fuel trim --- comms.ino | 32 ++++++++++++++++++++++++++++++-- globals.h | 1 + reference/speeduino.ini | 8 ++++---- speeduino.ino | 10 +++++----- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/comms.ino b/comms.ino index 0febea1..507764e 100644 --- a/comms.ino +++ b/comms.ino @@ -683,8 +683,36 @@ void sendPage(bool useChar) if(useChar) { currentTable = trim1Table; - currentTitleIndex = 121; - return; + for (int y = 0; y < currentTable.ySize; y++) + { + byte axisY = byte(currentTable.axisY[y]); + if (axisY < 100) + { + Serial.write(" "); + if (axisY < 10) + { + Serial.write(" "); + } + } + Serial.print(axisY);// Vertical Bins + Serial.write(" "); + for (int x = 0; x < currentTable.xSize; x++) + { + byte value = currentTable.values[y][x]; + if (value < 100) + { + Serial.write(" "); + if (value < 10) + { + Serial.write(" "); + } + } + Serial.print(value); + Serial.write(" "); + } + Serial.println(""); + } + return; //Do.... Something? } else diff --git a/globals.h b/globals.h index 9631c93..6531340 100644 --- a/globals.h +++ b/globals.h @@ -74,6 +74,7 @@ const byte packetSize = 35; //Table sizes #define CALIBRATION_TABLE_SIZE 512 #define CALIBRATION_TEMPERATURE_OFFSET 40 // All temperature measurements are stored offset by 40 degrees. This is so we can use an unsigned byte (0-255) to represent temperature ranges from -40 to 215 +#define OFFSET_FUELTRIM 127 //The fuel trim tables are offset by 128 to allow for -128 to +128 values #define SERIAL_BUFFER_THRESHOLD 32 // When the serial buffer is filled to greater than this threshold value, the serial processing operations will be performed more urgently in order to avoid it overflowing. Serial buffer is 64 bytes long, so the threshold is set at half this as a reasonable figure diff --git a/reference/speeduino.ini b/reference/speeduino.ini index 1a242e9..4f20e4f 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -475,7 +475,7 @@ page = 8 ;Sequential fuel trim tables (Page 9) ;-------------------------------------------------- page = 9 - fuelTrim1Table = array, U08, 0,[6x6], "%", 1.0, -128, -128, 128, 0 + fuelTrim1Table = array, U08, 0,[6x6], "%", 1.0, -128, -50, 50, 0 fuelTrim1rpmBins = array, U08, 36,[ 6], "RPM", 100.0, 0.0, 100, 25500, 0 #if SPEED_DENSITY fuelTrim1loadBins = array, U08, 42,[ 6], "kPa", 1.0, 0.0, 0.0, 255.0, 0 @@ -483,7 +483,7 @@ page = 9 fuelTrim1loadBins = array, U08, 42,[ 6], "TPS", 1.0, 0.0, 0.0, 255.0, 0 #endif - fuelTrim2Table = array, U08, 48,[6x6], "%", 1.0, -128, -128, 128, 0 + fuelTrim2Table = array, U08, 48,[6x6], "%", 1.0, -128, -50, 50, 0 fuelTrim2rpmBins = array, U08, 84,[ 6], "RPM", 100.0, 0.0, 100, 25500, 0 #if SPEED_DENSITY fuelTrim2loadBins = array, U08, 90,[ 6], "kPa", 1.0, 0.0, 0.0, 255.0, 0 @@ -491,7 +491,7 @@ page = 9 fuelTrim2loadBins = array, U08, 90,[ 6], "TPS", 1.0, 0.0, 0.0, 255.0, 0 #endif - fuelTrim3Table = array, U08, 96,[6x6], "%", 1.0, -128, -128, 128, 0 + fuelTrim3Table = array, U08, 96,[6x6], "%", 1.0, -128, -50, 50, 0 fuelTrim3rpmBins = array, U08, 132,[ 6], "RPM", 100.0, 0.0, 100, 25500, 0 #if SPEED_DENSITY fuelTrim3loadBins = array, U08, 138,[ 6], "kPa", 1.0, 0.0, 0.0, 255.0, 0 @@ -499,7 +499,7 @@ page = 9 fuelTrim3loadBins = array, U08, 138,[ 6], "TPS", 1.0, 0.0, 0.0, 255.0, 0 #endif - fuelTrim4Table = array, U08, 144,[6x6], "%", 1.0, -128, -128, 128, 0 + fuelTrim4Table = array, U08, 144,[6x6], "%", 1.0, -128, -50, 50, 0 fuelTrim4rpmBins = array, U08, 180,[ 6], "RPM", 100.0, 0.0, 100, 25500, 0 #if SPEED_DENSITY fuelTrim4loadBins = array, U08, 186,[ 6], "kPa", 1.0, 0.0, 0.0, 255.0, 0 diff --git a/speeduino.ino b/speeduino.ino index ca9bb26..1500467 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -1052,7 +1052,7 @@ void loop() //*********************************************************************************************** //BEGIN INJECTION TIMING //Determine next firing angles - currentStatus.PW2, currentStatus.PW3, currentStatus.PW4 = currentStatus.PW1; // Initial state is for all pulsewidths to be the same (This gets changed below) + currentStatus.PW2 = currentStatus.PW3 = currentStatus.PW4 = currentStatus.PW1; // Initial state is for all pulsewidths to be the same (This gets changed below) int PWdivTimerPerDegree = div(currentStatus.PW1, timePerDegree).quot; //How many crank degrees the calculated PW will take at the current speed injector1StartAngle = configPage1.inj1Ang - ( PWdivTimerPerDegree ); //This is a little primitive, but is based on the idea that all fuel needs to be delivered before the inlet valve opens. See http://www.extraefi.co.uk/sequential_fuel.html for more detail if(injector1StartAngle < 0) {injector1StartAngle += CRANK_ANGLE_MAX_INJ;} @@ -1085,10 +1085,10 @@ void loop() if(configPage3.fuelTrimEnabled) { - unsigned long pw1percent = 100 + get3DTableValue(&trim1Table, currentStatus.MAP, currentStatus.RPM); - unsigned long pw2percent = 100 + get3DTableValue(&trim2Table, currentStatus.MAP, currentStatus.RPM); - unsigned long pw3percent = 100 + get3DTableValue(&trim3Table, currentStatus.MAP, currentStatus.RPM); - unsigned long pw4percent = 100 + get3DTableValue(&trim4Table, currentStatus.MAP, currentStatus.RPM); + unsigned long pw1percent = 100 + (byte)get3DTableValue(&trim1Table, currentStatus.MAP, currentStatus.RPM) - OFFSET_FUELTRIM; + unsigned long pw2percent = 100 + (byte)get3DTableValue(&trim2Table, currentStatus.MAP, currentStatus.RPM) - OFFSET_FUELTRIM; + unsigned long pw3percent = 100 + (byte)get3DTableValue(&trim3Table, currentStatus.MAP, currentStatus.RPM) - OFFSET_FUELTRIM; + unsigned long pw4percent = 100 + (byte)get3DTableValue(&trim4Table, currentStatus.MAP, currentStatus.RPM) - OFFSET_FUELTRIM; if (pw1percent != 100) { currentStatus.PW1 = (pw1percent * currentStatus.PW1) / 100; } if (pw2percent != 100) { currentStatus.PW2 = (pw2percent * currentStatus.PW2) / 100; }