commit
b515058cc7
15
comms.h
15
comms.h
|
@ -10,13 +10,24 @@
|
||||||
#define iacPage 7
|
#define iacPage 7
|
||||||
#define boostvvtPage 8
|
#define boostvvtPage 8
|
||||||
|
|
||||||
byte currentPage;
|
byte currentPage = 1;
|
||||||
|
boolean isMap = true;
|
||||||
|
const char pageTitles[] PROGMEM
|
||||||
|
{
|
||||||
|
"\nVolumetric Efficiancy Map\0"
|
||||||
|
"\nPage 1 Config\0"
|
||||||
|
"\nIgnition Map\0"
|
||||||
|
"\nPage 2 Config\0"
|
||||||
|
"\nAir/Fuel Ratio Map\0"
|
||||||
|
"\nPage 3 Config\0"
|
||||||
|
"\nPage 4 Config"
|
||||||
|
};
|
||||||
|
|
||||||
void command();
|
void command();
|
||||||
void sendValues();
|
void sendValues();
|
||||||
void receiveValue(int offset, byte newValue);
|
void receiveValue(int offset, byte newValue);
|
||||||
void saveConfig();
|
void saveConfig();
|
||||||
void sendPage();
|
void sendPage(bool useChar);
|
||||||
void receiveCalibration(byte tableID);
|
void receiveCalibration(byte tableID);
|
||||||
void sendToothLog(bool useChar);
|
void sendToothLog(bool useChar);
|
||||||
void testComm();
|
void testComm();
|
||||||
|
|
401
comms.ino
401
comms.ino
|
@ -29,11 +29,28 @@ void command()
|
||||||
testComm();
|
testComm();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'L':
|
||||||
|
sendPage(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'N':
|
||||||
|
Serial.println();
|
||||||
|
break;
|
||||||
|
|
||||||
case 'P': // set the current page
|
case 'P': // set the current page
|
||||||
//A 2nd byte of data is required after the 'P' specifying the new page number.
|
//A 2nd byte of data is required after the 'P' specifying the new page number.
|
||||||
//This loop should never need to run as the byte should already be in the buffer, but is here just in case
|
//This loop should never need to run as the byte should already be in the buffer, but is here just in case
|
||||||
while (Serial.available() == 0) { }
|
while (Serial.available() == 0) { }
|
||||||
currentPage = Serial.read();
|
currentPage = Serial.read();
|
||||||
|
if (currentPage >= '0') {
|
||||||
|
currentPage -= '0';
|
||||||
|
}
|
||||||
|
if (currentPage == veMapPage || currentPage == ignMapPage || currentPage == afrMapPage) {
|
||||||
|
isMap = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
isMap = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'R': // send 39 bytes of realtime values
|
case 'R': // send 39 bytes of realtime values
|
||||||
|
@ -50,14 +67,14 @@ void command()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'V': // send VE table and constants
|
case 'V': // send VE table and constants
|
||||||
sendPage();
|
sendPage(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'W': // receive new VE or constant at 'W'+<offset>+<newbyte>
|
case 'W': // receive new VE or constant at 'W'+<offset>+<newbyte>
|
||||||
int offset;
|
int offset;
|
||||||
while (Serial.available() == 0) { }
|
while (Serial.available() == 0) { }
|
||||||
|
|
||||||
if(currentPage == veMapPage || currentPage == ignMapPage || currentPage == afrMapPage )
|
if (isMap)
|
||||||
{
|
{
|
||||||
byte offset1, offset2;
|
byte offset1, offset2;
|
||||||
offset1 = Serial.read();
|
offset1 = Serial.read();
|
||||||
|
@ -94,29 +111,28 @@ void command()
|
||||||
digitalWrite(pinInjector1, LOW);
|
digitalWrite(pinInjector1, LOW);
|
||||||
digitalWrite(pinInjector2, LOW);
|
digitalWrite(pinInjector2, LOW);
|
||||||
return;
|
return;
|
||||||
|
Serial.println(F("Coolant"));
|
||||||
Serial.println("Coolant");
|
|
||||||
for (int x = 0; x < CALIBRATION_TABLE_SIZE; x++)
|
for (int x = 0; x < CALIBRATION_TABLE_SIZE; x++)
|
||||||
{
|
{
|
||||||
Serial.print(x);
|
Serial.print(x);
|
||||||
Serial.print(", ");
|
Serial.print(", ");
|
||||||
Serial.println(cltCalibrationTable[x]);
|
Serial.println(cltCalibrationTable[x]);
|
||||||
}
|
}
|
||||||
Serial.println("Inlet temp");
|
Serial.println(F("Inlet temp"));
|
||||||
for (int x = 0; x < CALIBRATION_TABLE_SIZE; x++)
|
for (int x = 0; x < CALIBRATION_TABLE_SIZE; x++)
|
||||||
{
|
{
|
||||||
Serial.print(x);
|
Serial.print(x);
|
||||||
Serial.print(", ");
|
Serial.print(", ");
|
||||||
Serial.println(iatCalibrationTable[x]);
|
Serial.println(iatCalibrationTable[x]);
|
||||||
}
|
}
|
||||||
Serial.println("O2");
|
Serial.println(F("O2"));
|
||||||
for (int x = 0; x < CALIBRATION_TABLE_SIZE; x++)
|
for (int x = 0; x < CALIBRATION_TABLE_SIZE; x++)
|
||||||
{
|
{
|
||||||
Serial.print(x);
|
Serial.print(x);
|
||||||
Serial.print(", ");
|
Serial.print(", ");
|
||||||
Serial.println(o2CalibrationTable[x]);
|
Serial.println(o2CalibrationTable[x]);
|
||||||
}
|
}
|
||||||
Serial.println("WUE");
|
Serial.println(F("WUE"));
|
||||||
for (int x = 0; x < 10; x++)
|
for (int x = 0; x < 10; x++)
|
||||||
{
|
{
|
||||||
Serial.print(configPage2.wueBins[x]);
|
Serial.print(configPage2.wueBins[x]);
|
||||||
|
@ -134,6 +150,40 @@ void command()
|
||||||
sendToothLog(true); //Sends tooth log values as chars
|
sendToothLog(true); //Sends tooth log values as chars
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
Serial.println
|
||||||
|
(F(
|
||||||
|
"\n"
|
||||||
|
"===Command Help===\n\n"
|
||||||
|
"All commands are single character and are concatenated with their parameters \n"
|
||||||
|
"without spaces. Some parameters are binary and cannot be entered through this \n"
|
||||||
|
"prompt by conventional means. \n"
|
||||||
|
"Syntax: <command>+<parameter1>+<parameter2>+<parameterN>\n\n"
|
||||||
|
"===List of Commands===\n\n"
|
||||||
|
"A - Displays 31 bytes of currentStatus values in binary (live data)\n"
|
||||||
|
"B - Burn current map and configPage values to eeprom\n"
|
||||||
|
"C - Test COM port. Used by Tunerstudio to see whether an ECU is on a given serial \n"
|
||||||
|
" port. Returns a binary number.\n"
|
||||||
|
"L - Displays map page (aka table) or configPage values. Use P to change page (not \n"
|
||||||
|
" every page is a map)\n"
|
||||||
|
"N - Print new line.\n"
|
||||||
|
"P - Set current page. Syntax: P+<pageNumber>\n"
|
||||||
|
"R - Same as A command\n"
|
||||||
|
"S - Display signature number\n"
|
||||||
|
"Q - Same as S command\n"
|
||||||
|
"V - Display map or configPage values in binary\n"
|
||||||
|
"W - Set one byte in map or configPage. Expects binary parameters. \n"
|
||||||
|
" Syntax: W+<offset>+<newbyte>\n"
|
||||||
|
"t - Set calibration values. Expects binary parameters. Table index is either 0, \n"
|
||||||
|
" 1, or 2. Syntax: t+<tble_idx>+<newValue1>+<newValue2>+<newValueN>\n"
|
||||||
|
"Z - Display calibration values\n"
|
||||||
|
"T - Displays 256 tooth log entries in binary\n"
|
||||||
|
"r - Displays 256 tooth log entries\n"
|
||||||
|
"? - Displays this help page"
|
||||||
|
));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -151,7 +201,7 @@ void sendValues(int length)
|
||||||
response[1] = currentStatus.squirt; //Squirt Bitfield
|
response[1] = currentStatus.squirt; //Squirt Bitfield
|
||||||
response[2] = currentStatus.engine; //Engine Status Bitfield
|
response[2] = currentStatus.engine; //Engine Status Bitfield
|
||||||
response[3] = (byte)(divu100(currentStatus.dwell)); //Dwell in ms * 10
|
response[3] = (byte)(divu100(currentStatus.dwell)); //Dwell in ms * 10
|
||||||
response[4] = (byte)(currentStatus.MAP >> 1); //map value is divided by 2
|
response[4] = currentStatus.MAP; //map
|
||||||
response[5] = (byte)(currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET); //mat
|
response[5] = (byte)(currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET); //mat
|
||||||
response[6] = (byte)(currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //Coolant ADC
|
response[6] = (byte)(currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //Coolant ADC
|
||||||
response[7] = currentStatus.tpsADC; //TPS (Raw 0-255)
|
response[7] = currentStatus.tpsADC; //TPS (Raw 0-255)
|
||||||
|
@ -192,7 +242,7 @@ void sendValues(int length)
|
||||||
void receiveValue(int offset, byte newValue)
|
void receiveValue(int offset, byte newValue)
|
||||||
{
|
{
|
||||||
|
|
||||||
byte* pnt_configPage;
|
void* pnt_configPage;
|
||||||
|
|
||||||
switch (currentPage)
|
switch (currentPage)
|
||||||
{
|
{
|
||||||
|
@ -208,7 +258,7 @@ void receiveValue(int offset, byte newValue)
|
||||||
if (offset < 272)
|
if (offset < 272)
|
||||||
{
|
{
|
||||||
//X Axis
|
//X Axis
|
||||||
fuelTable.axisX[(offset-256)] = ((int)(newValue) * 100); //The RPM values sent by tunerstudio are divided by 100, need to multiple it back by 100 to make it correct
|
fuelTable.axisX[(offset - 256)] = ((int)(newValue) * 100); //The RPM values sent by megasquirt are divided by 100, need to multiple it back by 100 to make it correct
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -221,11 +271,11 @@ void receiveValue(int offset, byte newValue)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case veSetPage:
|
case veSetPage:
|
||||||
pnt_configPage = (byte *)&configPage1; //Setup a pointer to the relevant config page
|
pnt_configPage = &configPage1; //Setup a pointer to the relevant config page
|
||||||
//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
|
//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 ( offset < page_size)
|
if ( offset < page_size)
|
||||||
{
|
{
|
||||||
*(pnt_configPage + (byte)offset) = 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)offset) = newValue; //Need to subtract 80 because the map and bins (Which make up 80 bytes) aren't part of the config pages
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -241,7 +291,7 @@ void receiveValue(int offset, byte newValue)
|
||||||
if (offset < 272)
|
if (offset < 272)
|
||||||
{
|
{
|
||||||
//X Axis
|
//X Axis
|
||||||
ignitionTable.axisX[(offset-256)] = (int)(newValue) * int(100); //The RPM values sent by TunerStudio are divided by 100, need to multiple it back by 100 to make it correct
|
ignitionTable.axisX[(offset - 256)] = (int)(newValue) * int(100); //The RPM values sent by megasquirt are divided by 100, need to multiple it back by 100 to make it correct
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -253,11 +303,11 @@ void receiveValue(int offset, byte newValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
case ignSetPage:
|
case ignSetPage:
|
||||||
pnt_configPage = (byte *)&configPage2;
|
pnt_configPage = &configPage2;
|
||||||
//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
|
//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 ( offset < page_size)
|
if ( offset < page_size)
|
||||||
{
|
{
|
||||||
*(pnt_configPage + (byte)offset) = 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)offset) = newValue; //Need to subtract 80 because the map and bins (Which make up 80 bytes) aren't part of the config pages
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -273,7 +323,7 @@ void receiveValue(int offset, byte newValue)
|
||||||
if (offset < 272)
|
if (offset < 272)
|
||||||
{
|
{
|
||||||
//X Axis
|
//X Axis
|
||||||
afrTable.axisX[(offset-256)] = int(newValue) * int(100); //The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct
|
afrTable.axisX[(offset - 256)] = int(newValue) * int(100); //The RPM values sent by megasquirt are divided by 100, need to multiply it back by 100 to make it correct
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -286,23 +336,22 @@ void receiveValue(int offset, byte newValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
case afrSetPage:
|
case afrSetPage:
|
||||||
pnt_configPage = (byte *)&configPage3;
|
pnt_configPage = &configPage3;
|
||||||
//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
|
//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 ( offset < page_size)
|
if ( offset < page_size)
|
||||||
{
|
{
|
||||||
*(pnt_configPage + (byte)offset) = 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)offset) = newValue; //Need to subtract 80 because the map and bins (Which make up 80 bytes) aren't part of the config pages
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iacPage: //Idle Air Control settings page (Page 4)
|
case iacPage: //Idle Air Control settings page (Page 4)
|
||||||
pnt_configPage = (byte *)&configPage4;
|
pnt_configPage = &configPage4;
|
||||||
//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
|
//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 ( offset < page_size)
|
if ( offset < page_size)
|
||||||
{
|
{
|
||||||
*(pnt_configPage + (byte)offset) = newValue;
|
*((byte *)pnt_configPage + (byte)offset) = newValue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case boostvvtPage: //Boost and VVT maps (8x8)
|
case boostvvtPage: //Boost and VVT maps (8x8)
|
||||||
if (offset < 64) //New value is part of the boost map
|
if (offset < 64) //New value is part of the boost map
|
||||||
{
|
{
|
||||||
|
@ -337,7 +386,6 @@ void receiveValue(int offset, byte newValue)
|
||||||
vvtTable.axisY[(7 - offset)] = int(newValue);
|
vvtTable.axisY[(7 - offset)] = int(newValue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -347,102 +395,204 @@ void receiveValue(int offset, byte newValue)
|
||||||
sendPage() packs the data within the current page (As set with the 'P' command)
|
sendPage() packs the data within the current page (As set with the 'P' command)
|
||||||
into a buffer and sends it.
|
into a buffer and sends it.
|
||||||
Note that some translation of the data is required to lay it out in the way Megasqurit / TunerStudio expect it
|
Note that some translation of the data is required to lay it out in the way Megasqurit / TunerStudio expect it
|
||||||
|
useChar - If true, all values are send as chars, this is for the serial command line interface. TunerStudio expects data as raw values, so this must be set false in that case
|
||||||
*/
|
*/
|
||||||
void sendPage()
|
void sendPage(bool useChar)
|
||||||
{
|
{
|
||||||
byte* pnt_configPage;
|
void* pnt_configPage;
|
||||||
|
struct table3D currentTable;
|
||||||
|
byte currentTitleIndex = 0;
|
||||||
|
|
||||||
switch (currentPage)
|
switch (currentPage)
|
||||||
{
|
{
|
||||||
case veMapPage:
|
case veMapPage:
|
||||||
{
|
{
|
||||||
//Need to perform a translation of the values[MAP/TPS][RPM] into the MS expected format
|
currentTitleIndex = 0;
|
||||||
//MS format has origin (0,0) in the bottom left corner, we use the top left for efficiency reasons
|
currentTable = fuelTable;
|
||||||
byte response[map_page_size];
|
|
||||||
|
|
||||||
for(int x=0;x<256;x++) { response[x] = fuelTable.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
|
|
||||||
for(int x=256;x<272;x++) { response[x] = byte(fuelTable.axisX[(x-256)] / 100); } //RPM Bins for VE table (Need to be dvidied by 100)
|
|
||||||
for(int y=272;y<288;y++) { response[y] = byte(fuelTable.axisY[15-(y-272)]); } //MAP or TPS bins for VE table
|
|
||||||
Serial.write((byte *)&response, sizeof(response));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case veSetPage:
|
case veSetPage:
|
||||||
{
|
{
|
||||||
//All other bytes can simply be copied from the config table
|
// currentTitleIndex = 27;
|
||||||
byte response[page_size];
|
if (useChar)
|
||||||
|
|
||||||
pnt_configPage = (byte *)&configPage1; //Create a pointer to Page 1 in memory
|
|
||||||
for(byte x=0; x<page_size; x++)
|
|
||||||
{
|
{
|
||||||
response[x] = *(pnt_configPage + x); //Each byte is simply the location in memory of configPage1 + the offset + the variable number (x)
|
//To Display Values from Config Page 1
|
||||||
|
Serial.println((const __FlashStringHelper *)&pageTitles[27]);
|
||||||
|
for (pnt_configPage = &configPage1; pnt_configPage < &configPage1.wueValues[0]; pnt_configPage = (byte *)pnt_configPage + 1) Serial.println(*((byte *)pnt_configPage));
|
||||||
|
for (byte x = 10; x; x--)
|
||||||
|
{
|
||||||
|
Serial.print(configPage1.wueValues[10 - x]);
|
||||||
|
Serial.print(' ');
|
||||||
}
|
}
|
||||||
Serial.write((byte *)&response, sizeof(response));
|
Serial.println();
|
||||||
|
for (pnt_configPage = (byte *)&configPage1.wueValues[9] + 1; pnt_configPage < &configPage1.inj1Ang; pnt_configPage = (byte *)pnt_configPage + 1) {
|
||||||
|
Serial.println(*((byte *)pnt_configPage));
|
||||||
|
}
|
||||||
|
for (pnt_configPage = &configPage1.inj1Ang; pnt_configPage < (unsigned int *)&configPage1.inj4Ang + 1; pnt_configPage = (unsigned int *)pnt_configPage + 1) Serial.println(*((unsigned int *)pnt_configPage));
|
||||||
|
for (pnt_configPage = (unsigned int *)&configPage1.inj4Ang + 1; pnt_configPage < (byte *)&configPage1 + page_size; pnt_configPage = (byte *)pnt_configPage + 1) Serial.println(*((byte *)pnt_configPage));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else pnt_configPage = &configPage1; //Create a pointer to Page 1 in memory
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ignMapPage:
|
case ignMapPage:
|
||||||
{
|
{
|
||||||
//Need to perform a translation of the values[MAP/TPS][RPM] into the MS expected format
|
currentTitleIndex = 42;
|
||||||
byte response[map_page_size];
|
currentTable = ignitionTable;
|
||||||
|
|
||||||
for(int x=0;x<256;x++) { response[x] = ignitionTable.values[15-x/16][x%16]; }
|
|
||||||
for(int x=256;x<272;x++) { response[x] = byte(ignitionTable.axisX[(x-256)] / 100); }
|
|
||||||
for(int y=272;y<288;y++) { response[y] = byte(ignitionTable.axisY[15-(y-272)]); }
|
|
||||||
Serial.write((byte *)&response, sizeof(response));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ignSetPage:
|
case ignSetPage:
|
||||||
{
|
{
|
||||||
//All other bytes can simply be copied from the config table
|
//currentTitleIndex = 56;
|
||||||
byte response[page_size];
|
if (useChar)
|
||||||
|
|
||||||
pnt_configPage = (byte *)&configPage2; //Create a pointer to Page 2 in memory
|
|
||||||
for(byte x=0; x<page_size; x++)
|
|
||||||
{
|
{
|
||||||
response[x] = *(pnt_configPage + x); //Each byte is simply the location in memory of configPage2 + the offset + the variable number (x)
|
//To Display Values from Config Page 2
|
||||||
|
Serial.println((const __FlashStringHelper *)&pageTitles[56]);
|
||||||
|
Serial.println(configPage2.triggerAngle);
|
||||||
|
|
||||||
|
for (pnt_configPage = (int *)&configPage2 + 1; pnt_configPage < &configPage2.taeBins[0]; pnt_configPage = (byte *)pnt_configPage + 1) Serial.println(*((byte *)pnt_configPage));
|
||||||
|
for (byte y = 2; y; y--)
|
||||||
|
{
|
||||||
|
byte * currentVar;
|
||||||
|
if (y == 2) {
|
||||||
|
currentVar = configPage2.taeBins;
|
||||||
}
|
}
|
||||||
Serial.write((byte *)&response, sizeof(response));
|
else {
|
||||||
|
currentVar = configPage2.taeValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (byte x = 4; x; x--)
|
||||||
|
{
|
||||||
|
Serial.print(currentVar[4 - x]);
|
||||||
|
Serial.print(' ');
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
for (byte x = 10; x ; x--)
|
||||||
|
{
|
||||||
|
Serial.print(configPage2.wueBins[10 - x]);
|
||||||
|
Serial.print(' ');
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
Serial.println(configPage2.dwellLimit);
|
||||||
|
for (byte x = 6; x; x--)
|
||||||
|
{
|
||||||
|
Serial.print(configPage2.dwellCorrectionValues[6 - x]);
|
||||||
|
Serial.print(' ');
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
for (pnt_configPage = (byte *)&configPage2.dwellCorrectionValues[5] + 1; pnt_configPage < (byte *)&configPage2 + page_size; pnt_configPage = (byte *)pnt_configPage + 1)
|
||||||
|
{
|
||||||
|
Serial.println(*((byte *)pnt_configPage));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else pnt_configPage = &configPage2; //Create a pointer to Page 2 in memory
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case afrMapPage:
|
case afrMapPage:
|
||||||
{
|
{
|
||||||
//Need to perform a translation of the values[MAP/TPS][RPM] into the MS expected format
|
currentTitleIndex = 71;
|
||||||
byte response[map_page_size];
|
currentTable = afrTable;
|
||||||
|
|
||||||
for(int x=0;x<256;x++) { response[x] = afrTable.values[15-x/16][x%16]; }
|
|
||||||
for(int x=256;x<272;x++) { response[x] = byte(afrTable.axisX[(x-256)] / 100); }
|
|
||||||
for(int y=272;y<288;y++) { response[y] = byte(afrTable.axisY[15-(y-272)]); }
|
|
||||||
Serial.write((byte *)&response, sizeof(response));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case afrSetPage:
|
case afrSetPage:
|
||||||
{
|
{
|
||||||
//All other bytes can simply be copied from the config table
|
//currentTitleIndex = 91;
|
||||||
byte response[page_size];
|
if (useChar)
|
||||||
|
|
||||||
pnt_configPage = (byte *)&configPage3; //Create a pointer to Page 2 in memory
|
|
||||||
for(byte x=0; x<page_size; x++)
|
|
||||||
{
|
{
|
||||||
response[x] = *(pnt_configPage + x); //Each byte is simply the location in memory of configPage2 + the offset + the variable number (x)
|
//To Display Values from Config Page 3
|
||||||
|
Serial.println((const __FlashStringHelper *)&pageTitles[91]);
|
||||||
|
for (pnt_configPage = &configPage3; pnt_configPage < &configPage3.voltageCorrectionBins[0]; pnt_configPage = (byte *)pnt_configPage + 1)
|
||||||
|
{
|
||||||
|
Serial.println(*((byte *)pnt_configPage));
|
||||||
}
|
}
|
||||||
Serial.write((byte *)&response, sizeof(response));
|
for (byte y = 2; y; y--)
|
||||||
|
{
|
||||||
|
byte * currentVar;
|
||||||
|
if (y == 2) { currentVar = configPage3.voltageCorrectionBins; }
|
||||||
|
else { currentVar = configPage3.injVoltageCorrectionValues; }
|
||||||
|
|
||||||
|
for (byte x = 6; x; x--)
|
||||||
|
{
|
||||||
|
Serial.print(currentVar[6 - x]);
|
||||||
|
Serial.print(' ');
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
for (byte y = 2; y; y--)
|
||||||
|
{
|
||||||
|
byte* currentVar;
|
||||||
|
if (y == 2) currentVar = configPage3.airDenBins;
|
||||||
|
else currentVar = configPage3.airDenRates;
|
||||||
|
for (byte x = 9; x; x--)
|
||||||
|
{
|
||||||
|
Serial.print(currentVar[9 - x]);
|
||||||
|
Serial.print(' ');
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
for (pnt_configPage = (byte *)&configPage3.airDenRates[8] + 1; pnt_configPage < (byte *)&configPage3 + page_size; pnt_configPage = (byte *)pnt_configPage + 1)
|
||||||
|
{
|
||||||
|
Serial.println(*((byte *)pnt_configPage));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else pnt_configPage = &configPage3; //Create a pointer to Page 3 in memory
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case iacPage:
|
case iacPage:
|
||||||
{
|
{
|
||||||
byte response[page_size];
|
//currentTitleIndex = 106;
|
||||||
|
//To Display Values from Config Page 4
|
||||||
pnt_configPage = (byte *)&configPage4; //Create a pointer to Page 2 in memory
|
if (useChar)
|
||||||
for(byte x=0; x<page_size; x++)
|
|
||||||
{
|
{
|
||||||
response[x] = *(pnt_configPage + x); //Each byte is simply the location in memory of configPage2 + the offset + the variable number (x)
|
Serial.println((const __FlashStringHelper *)&pageTitles[106]);
|
||||||
|
for (byte y = 4; y; y--)
|
||||||
|
{
|
||||||
|
byte * currentVar;
|
||||||
|
switch (y)
|
||||||
|
{
|
||||||
|
case 1: currentVar = configPage4.iacBins; break;
|
||||||
|
case 2: currentVar = configPage4.iacOLPWMVal; break;
|
||||||
|
case 3: currentVar = configPage4.iacOLStepVal; break;
|
||||||
|
case 4: currentVar = configPage4.iacCLValues; break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
Serial.write((byte *)&response, sizeof(response));
|
for (byte x = 10; x; x--)
|
||||||
|
{
|
||||||
|
Serial.print(currentVar[10 - x]);
|
||||||
|
Serial.print(' ');
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
for (byte y = 3; y; y--)
|
||||||
|
{
|
||||||
|
byte * currentVar;
|
||||||
|
switch (y)
|
||||||
|
{
|
||||||
|
case 1: currentVar = configPage4.iacCrankBins; break;
|
||||||
|
case 2: currentVar = configPage4.iacCrankDuty; break;
|
||||||
|
case 3: currentVar = configPage4.iacCrankSteps; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
for (byte x = 4; x; x--)
|
||||||
|
{
|
||||||
|
Serial.print(currentVar[4 - x]);
|
||||||
|
Serial.print(' ');
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
for (pnt_configPage = (byte *)&configPage4.iacCrankBins[3] + 1; pnt_configPage < (byte *)&configPage4 + page_size; pnt_configPage = (byte *)pnt_configPage + 1) Serial.println(*((byte *)pnt_configPage));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else pnt_configPage = &configPage4; //Create a pointer to Page 4 in memory
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,17 +610,102 @@ void sendPage()
|
||||||
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)] / 100); }
|
||||||
for (int y = 72; y < 80; y++) { response[y + 80] = byte(vvtTable.axisY[7 - (y - 72)]); }
|
for (int y = 72; y < 80; y++) { response[y + 80] = byte(vvtTable.axisY[7 - (y - 72)]); }
|
||||||
Serial.write((byte *)&response, sizeof(response));
|
Serial.write((byte *)&response, sizeof(response));
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
|
Serial.println(F("\nPage has not been implemented yet. Change to another page."));
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isMap)
|
||||||
|
{
|
||||||
|
if (useChar)
|
||||||
|
{
|
||||||
|
const char spaceChar = ' ';
|
||||||
|
/*while(pageTitles[currentTitleIndex])
|
||||||
|
{
|
||||||
|
Serial.print(pageTitles[currentTitleIndex]);
|
||||||
|
currentTitleIndex++;
|
||||||
|
}*/
|
||||||
|
Serial.println((const __FlashStringHelper *)&pageTitles[currentTitleIndex]);
|
||||||
|
Serial.print(F("\n "));
|
||||||
|
for (int x = 0; x < currentTable.xSize; x++)
|
||||||
|
{
|
||||||
|
byte axisX = byte(currentTable.axisX[x] / 100);
|
||||||
|
if (axisX < 100)
|
||||||
|
{
|
||||||
|
Serial.write(spaceChar);
|
||||||
|
if (axisX < 10)
|
||||||
|
{
|
||||||
|
Serial.write(spaceChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Serial.print(axisX);
|
||||||
|
Serial.write(spaceChar);
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
for (int y = 0; y < currentTable.ySize; y++)
|
||||||
|
{
|
||||||
|
Serial.print(byte(currentTable.axisY[y]));
|
||||||
|
Serial.write(spaceChar);
|
||||||
|
for (int x = 0; x < currentTable.xSize; x++)
|
||||||
|
{
|
||||||
|
byte value = currentTable.values[y][x];
|
||||||
|
if (value < 100)
|
||||||
|
{
|
||||||
|
Serial.write(spaceChar);
|
||||||
|
if (value < 10)
|
||||||
|
{
|
||||||
|
Serial.write(spaceChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Serial.print(value);
|
||||||
|
Serial.write(spaceChar);
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Need to perform a translation of the values[yaxis][xaxis] into the MS expected format
|
||||||
|
//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]; } //This is slightly non-intuitive, but essentially just flips the table vertically (IE top line becomes the bottom line etc). Columns are unchanged
|
||||||
|
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)
|
||||||
|
for (int y = 272; y < 288; y++) { response[y] = byte(currentTable.axisY[15 - (y - 272)]); } //MAP or TPS bins for VE table
|
||||||
|
Serial.write((byte *)&response, sizeof(response));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*if(useChar)
|
||||||
|
{
|
||||||
|
while(pageTitles[currentTitleIndex])
|
||||||
|
{
|
||||||
|
Serial.print(pageTitles[currentTitleIndex]);
|
||||||
|
currentTitleIndex++;
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
for(byte x=0;x<page_size;x++) Serial.println(*((byte *)pnt_configPage + x));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{*/
|
||||||
|
//All other bytes can simply be copied from the config table
|
||||||
|
byte response[page_size];
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
Serial.write((byte *)&response, sizeof(response));
|
||||||
|
// }
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This function is used to store calibration data sent by Tuner Studio.
|
This function is used to store calibration data sent by Tuner Studio.
|
||||||
*/
|
*/
|
||||||
|
@ -540,8 +775,12 @@ void receiveCalibration(byte tableID)
|
||||||
|
|
||||||
if (every2nd) //Only use every 2nd value
|
if (every2nd) //Only use every 2nd value
|
||||||
{
|
{
|
||||||
if (tempValue > 255) { tempValue = 255; } // Cap the maximum value to prevent overflow when converting to byte
|
if (tempValue > 255) {
|
||||||
if (tempValue < 0) { tempValue = 0; }
|
tempValue = 255; // Cap the maximum value to prevent overflow when converting to byte
|
||||||
|
}
|
||||||
|
if (tempValue < 0) {
|
||||||
|
tempValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
pnt_TargetTable[(x / 2)] = (byte)tempValue;
|
pnt_TargetTable[(x / 2)] = (byte)tempValue;
|
||||||
int y = EEPROM_CALIBRATION_O2 + counter;
|
int y = EEPROM_CALIBRATION_O2 + counter;
|
||||||
|
@ -550,7 +789,9 @@ void receiveCalibration(byte tableID)
|
||||||
analogWrite(13, (counter % 50) );
|
analogWrite(13, (counter % 50) );
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
else { every2nd = true; }
|
else {
|
||||||
|
every2nd = true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,7 +806,9 @@ void sendToothLog(bool useChar)
|
||||||
{
|
{
|
||||||
|
|
||||||
//We need 256 records to send to TunerStudio. If there aren't that many in the buffer (Buffer is 512 long) then we just return and wait for the next call
|
//We need 256 records to send to TunerStudio. If there aren't that many in the buffer (Buffer is 512 long) then we just return and wait for the next call
|
||||||
if (toothHistoryIndex < 256) { return; } //Don't believe this is the best way to go. Just display whatever is in the buffer
|
if (toothHistoryIndex < 256) {
|
||||||
|
return; //Don't believe this is the best way to go. Just display whatever is in the buffer
|
||||||
|
}
|
||||||
unsigned int tempToothHistory[512]; //Create a temporary array that will contain a copy of what is in the main toothHistory array
|
unsigned int tempToothHistory[512]; //Create a temporary array that will contain a copy of what is in the main toothHistory array
|
||||||
|
|
||||||
//Copy the working history into the temporary buffer array. This is done so that, if the history loops whilst the values are being sent over serial, it doesn't affect the values
|
//Copy the working history into the temporary buffer array. This is done so that, if the history loops whilst the values are being sent over serial, it doesn't affect the values
|
||||||
|
|
Loading…
Reference in New Issue