Sensor calibration in New Comms

This commit is contained in:
Josh Stewart 2021-12-07 15:20:02 +11:00
parent e7a217fab7
commit 8b262a0087
3 changed files with 102 additions and 101 deletions

View File

@ -1,6 +1,7 @@
;-------------------------------------------------------------------------------
#unset CAN_COMMANDS
#unset enablehardware_test
#set NEW_COMMS
[MegaTune]
MTversion = 2.25
@ -30,6 +31,8 @@
settingOption = resetcontrol_standard, "Basic Options Only"
settingOption = resetcontrol_adv, "Advanced Features (16u2 Firmware Update Required)"
settingGroup = NEW_COMMS, "Use new comms protocol"
[PcVariables]
; valid types: boolean, double, int, list
;
@ -222,7 +225,9 @@
interWriteDelay = 1 ;Ignored when tsWriteBlocks is on
pageActivationDelay = 10
restrictSquirtRelationship = false ;This requires TS 3.1 or above
;messageEnvelopeFormat = msEnvelope_1.0 ;New and testing only
#if NEW_COMMS
messageEnvelopeFormat = msEnvelope_1.0 ;New and testing only
#endif
readSdCompressed = false
;New for TS 3.0.08ish upwards, define lists of standard I/O options
@ -5138,6 +5143,10 @@ cmdVSSratio6 = "E\x99\x06"
calcField = time, "Time", "ms", { refTime }
[ReferenceTables]
#if NEW_COMMS
tableWriteCommand = "t\$tsCanId%2i%2o%2c%v"; "t%2i%2o%2c%v"; "t\x01\xFC\x00\x01\xFC" "t\%2i%2o%2c%v"
tableBlockingFactor = 256
#endif
referenceTable = std_ms2gentherm, "Calibrate Thermistor Tables."
topicHelp = "https://wiki.speeduino.com/en/configuration/Sensor_Calibration"
tableIdentifier = 000, "Coolant Temperature Sensor", 001, "Air Temperature Sensor", 003, "Custom#1 Temperature Sensor"

View File

@ -114,7 +114,7 @@ void parseSerial()
if(serialCRC != receivedCRC)
{
//CRC Error. Need to send an error message
sendSerialReturnCode(SERIAL_RC_CRC_ERROR);
sendSerialReturnCode(SERIAL_RC_CRC_ERR);
}
else
{
@ -558,17 +558,94 @@ void processSerialCommand()
break;
case 't': // receive new Calibration info. Command structure: "t", <tble_idx> <data array>.
byte tableID;
//byte canID;
{
uint8_t cmd = serialPayload[2];
uint16_t valueOffset = word(serialPayload[3], serialPayload[4]);
uint16_t calibrationLength = word(serialPayload[5], serialPayload[6]); // Should be 256
//The first 2 bytes sent represent the canID and tableID
while (Serial.available() == 0) { }
tableID = Serial.read(); //Not currently used for anything
if(cmd == O2_CALIBRATION_PAGE)
{
//TS sends a total of 1024 bytes of calibration data, broken up into 256 byte chunks
//As we're using an interpolated 2D table, we only need to store 32 values out of this 1024
void* pnt_TargetTable_values = (uint8_t *)&o2Calibration_values; //Pointer that will be used to point to the required target table values
uint16_t* pnt_TargetTable_bins = (uint16_t *)&o2Calibration_bins; //Pointer that will be used to point to the required target table bins
//Read through the current chunk (Should be 256 bytes long)
for(uint16_t x = 0; x < calibrationLength; x++)
{
//Only apply every 32nd value
if( (x % 32) == 0 )
{
uint16_t totalOffset = valueOffset + x;
((uint8_t*)pnt_TargetTable_values)[(totalOffset/32)] = serialPayload[x+7]; //O2 table stores 8 bit values
pnt_TargetTable_bins[(totalOffset/32)] = (totalOffset);
}
}
sendSerialReturnCode(SERIAL_RC_OK);
}
else if(cmd == IAT_CALIBRATION_PAGE)
{
void* pnt_TargetTable_values = (uint16_t *)&iatCalibration_values;
uint16_t* pnt_TargetTable_bins = (uint16_t *)&iatCalibration_bins;
//Temperature calibrations are sent as 32 16-bit values
if(calibrationLength == 64)
{
for (uint16_t x = 0; x < 32; x++)
{
int16_t tempValue = (int16_t)(word(serialPayload[((2 * x) + 8)], serialPayload[((2 * x) + 7)])); //Combine the 2 bytes into a single, signed 16-bit value
tempValue = div(tempValue, 10).quot; //TS sends values multipled by 10 so divide back to whole degrees.
tempValue = ((tempValue - 32) * 5) / 9; //Convert from F to C
//Apply the temp offset and check that it results in all values being positive
tempValue = tempValue + CALIBRATION_TEMPERATURE_OFFSET;
if (tempValue < 0) { tempValue = 0; }
((uint16_t*)pnt_TargetTable_values)[x] = tempValue; //Both temp tables have 16-bit values
pnt_TargetTable_bins[x] = (x * 32U);
}
writeCalibration();
sendSerialReturnCode(SERIAL_RC_OK);
}
else { sendSerialReturnCode(SERIAL_RC_RANGE_ERR); }
}
else if(cmd == CLT_CALIBRATION_PAGE)
{
void* pnt_TargetTable_values = (uint16_t *)&cltCalibration_values;
uint16_t* pnt_TargetTable_bins = (uint16_t *)&cltCalibration_bins;
//Temperature calibrations are sent as 32 16-bit values
if(calibrationLength == 64)
{
for (uint16_t x = 0; x < 32; x++)
{
int16_t tempValue = (int16_t)(word(serialPayload[((2 * x) + 8)], serialPayload[((2 * x) + 7)])); //Combine the 2 bytes into a single, signed 16-bit value
tempValue = div(tempValue, 10).quot; //TS sends values multipled by 10 so divide back to whole degrees.
tempValue = ((tempValue - 32) * 5) / 9; //Convert from F to C
//Apply the temp offset and check that it results in all values being positive
tempValue = tempValue + CALIBRATION_TEMPERATURE_OFFSET;
if (tempValue < 0) { tempValue = 0; }
((uint16_t*)pnt_TargetTable_values)[x] = tempValue; //Both temp tables have 16-bit values
pnt_TargetTable_bins[x] = (x * 32U);
}
writeCalibration();
sendSerialReturnCode(SERIAL_RC_OK);
}
else { sendSerialReturnCode(SERIAL_RC_RANGE_ERR); }
}
else
{
sendSerialReturnCode(SERIAL_RC_RANGE_ERR);
}
receiveCalibrationNew(tableID); //Receive new values and store in memory
writeCalibration(); //Store received values in EEPROM
break;
}
case 'U': //User wants to reset the Arduino (probably for FW update)
if (resetControl != RESET_CONTROL_DISABLED)
@ -795,96 +872,6 @@ namespace
}
/** Processes an incoming stream of calibration data (for CLT, IAT or O2) from TunerStudio.
* Result is store in EEPROM and memory.
*
* @param tableID - calibration table to process. 0 = Coolant Sensor. 1 = IAT Sensor. 2 = O2 Sensor.
*/
void receiveCalibrationNew(byte tableID)
{
void* pnt_TargetTable_values; //Pointer that will be used to point to the required target table values
uint16_t* pnt_TargetTable_bins; //Pointer that will be used to point to the required target table bins
int OFFSET, DIVISION_FACTOR;
switch (tableID)
{
case 0:
//coolant table
pnt_TargetTable_values = (uint16_t *)&cltCalibration_values;
pnt_TargetTable_bins = (uint16_t *)&cltCalibration_bins;
OFFSET = CALIBRATION_TEMPERATURE_OFFSET; //
DIVISION_FACTOR = 10;
break;
case 1:
//Inlet air temp table
pnt_TargetTable_values = (uint16_t *)&iatCalibration_values;
pnt_TargetTable_bins = (uint16_t *)&iatCalibration_bins;
OFFSET = CALIBRATION_TEMPERATURE_OFFSET;
DIVISION_FACTOR = 10;
break;
case 2:
//O2 table
//pnt_TargetTable = (byte *)&o2CalibrationTable;
pnt_TargetTable_values = (uint8_t *)&o2Calibration_values;
pnt_TargetTable_bins = (uint16_t *)&o2Calibration_bins;
OFFSET = 0;
DIVISION_FACTOR = 1;
break;
default:
OFFSET = 0;
pnt_TargetTable_values = (uint16_t *)&iatCalibration_values;
pnt_TargetTable_bins = (uint16_t *)&iatCalibration_bins;
DIVISION_FACTOR = 10;
break; //Should never get here, but if we do, just fail back to main loop
}
int16_t tempValue;
byte tempBuffer[2];
if(tableID == 2)
{
//O2 calibration. Comes through as 1024 8-bit values of which we use every 32nd
for (int x = 0; x < 1024; x++)
{
while ( Serial.available() < 1 ) {}
tempValue = Serial.read();
if( (x % 32) == 0)
{
((uint8_t*)pnt_TargetTable_values)[(x/32)] = (byte)tempValue; //O2 table stores 8 bit values
pnt_TargetTable_bins[(x/32)] = (x);
}
}
}
else
{
//Temperature calibrations are sent as 32 16-bit values
for (uint16_t x = 0; x < 32; x++)
{
while ( Serial.available() < 2 ) {}
tempBuffer[0] = Serial.read();
tempBuffer[1] = Serial.read();
tempValue = (int16_t)(word(tempBuffer[1], tempBuffer[0])); //Combine the 2 bytes into a single, signed 16-bit value
tempValue = div(tempValue, DIVISION_FACTOR).quot; //TS sends values multipled by 10 so divide back to whole degrees.
tempValue = ((tempValue - 32) * 5) / 9; //Convert from F to C
//Apply the temp offset and check that it results in all values being positive
tempValue = tempValue + OFFSET;
if (tempValue < 0) { tempValue = 0; }
((uint16_t*)pnt_TargetTable_values)[x] = tempValue; //Both temp tables have 16-bit values
pnt_TargetTable_bins[x] = (x * 32U);
writeCalibration();
}
}
writeCalibration();
}
/** Send 256 tooth log entries to serial.
* if useChar is true, the values are sent as chars to be printed out by a terminal emulator
* if useChar is false, the values are sent as a 2 byte integer which is readable by TunerStudios tooth logger

View File

@ -44,6 +44,10 @@
#define SD_RTC_WRITE_ARG2 0x0009
#define O2_CALIBRATION_PAGE 2
#define IAT_CALIBRATION_PAGE 1
#define CLT_CALIBRATION_PAGE 0
#define SERIAL_CRC_LENGTH 4
#define SERIAL_LEN_SIZE 2
#define SERIAL_OVERHEAD_SIZE (SERIAL_LEN_SIZE + SERIAL_CRC_LENGTH) //The overhead for each serial command is 6 bytes. 2 bytes for the length and 4 bytes for the CRC
@ -64,7 +68,9 @@
#define SERIAL_RC_BURN_OK 0x04
#define SERIAL_RC_CRC_ERROR 0x82
#define SERIAL_RC_CRC_ERR 0x82
#define SERIAL_RC_UKWN_ERR 0x83 //Unkwnown command
#define SERIAL_RC_RANGE_ERR 0x84 //Incorrect range. TS will not retry command
extern uint16_t serialPayloadLength;
extern uint32_t serialCRC;
@ -82,7 +88,6 @@ void sendSerialPayload(void*, uint16_t payloadLength);
void generateLiveValues(uint16_t, uint16_t);
void saveConfig();
void receiveCalibrationNew(byte);
void generateToothLog(uint8_t);
void commandButtons(int16_t);
void generateCompositeLog(uint8_t);