Repository for import to local machine
Dependencies: DMBasicGUI DMSupport
ColumnDHManualCalibrationPageHandler.cpp
- Committer:
- jmitc91516
- Date:
- 2017-07-31
- Revision:
- 8:26e49e6955bd
- Parent:
- 1:a5258871b33d
File content as of revision 8:26e49e6955bd:
#include "ColumnDHManualCalibrationPageHandler.h" #include "EasyGUITouchAreaIndices.h" #include "GetGCStatusLoop.h" #include "NumericKeypadPageHandler.h" #include "USBHostGCUtilities.h" /* Note that this class is a singleton - we do not need or want there to be more than one instance of it (we do not want multiple values for the same calibration parameters, etc, and nor will we show more than one easyGUI 'ColumnDHManualCalibrationPage' to the user at the same time). */ ColumnDHManualCalibrationPageHandler * ColumnDHManualCalibrationPageHandler::theColumnDHManualCalibrationPageHandlerInstance = NULL; /* Singleton class - return the one and only instance, first creating it if necessary. */ ColumnDHManualCalibrationPageHandler * ColumnDHManualCalibrationPageHandler::GetInstance(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC) { if (theColumnDHManualCalibrationPageHandlerInstance == NULL) { theColumnDHManualCalibrationPageHandlerInstance = new ColumnDHManualCalibrationPageHandler(newUsbDevice, newUsbHostGC); } return theColumnDHManualCalibrationPageHandlerInstance; } /* Overriden version of the above, that does not take any arguments and does not create the instance if it does not already exist. Provided for callers that do not have the 'usbDevice' and'usbHostGC' pointers, and just want access to the instance if it exists */ ColumnDHManualCalibrationPageHandler * ColumnDHManualCalibrationPageHandler::GetInstance(void) { return theColumnDHManualCalibrationPageHandlerInstance; } // Singleton class - private constructor ColumnDHManualCalibrationPageHandler::ColumnDHManualCalibrationPageHandler(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC) { usbDevice = newUsbDevice; usbHostGC = newUsbHostGC; variablesForTouchArea[0].touchAreaIndex = COLUMN_DH_MANUAL_CALIB_EDIT_TEMP1; variablesForTouchArea[0].easyGUIVariablePtr = GuiVar_columnDHManualCalibTemp1; variablesForTouchArea[0].maxValue = 999; variablesForTouchArea[0].placesOfDecimals = 1; strcpy(variablesForTouchArea[0].variableTitle, "Temp Point 1"); variablesForTouchArea[1].touchAreaIndex = COLUMN_DH_MANUAL_CALIB_EDIT_TEMP2; variablesForTouchArea[1].easyGUIVariablePtr = GuiVar_columnDHManualCalibTemp2; variablesForTouchArea[1].maxValue = 999; variablesForTouchArea[1].placesOfDecimals = 1; strcpy(variablesForTouchArea[1].variableTitle, "Temp Point 2"); variablesForTouchArea[2].touchAreaIndex = COLUMN_DH_MANUAL_CALIB_EDIT_TEMP3; variablesForTouchArea[2].easyGUIVariablePtr = GuiVar_columnDHManualCalibTemp3; variablesForTouchArea[2].maxValue = 999; variablesForTouchArea[2].placesOfDecimals = 1; strcpy(variablesForTouchArea[2].variableTitle, "Temp Point 3"); variablesForTouchArea[3].touchAreaIndex = COLUMN_DH_MANUAL_CALIB_EDIT_RES1; variablesForTouchArea[3].easyGUIVariablePtr = GuiVar_columnDHManualCalibRes1; variablesForTouchArea[3].maxValue = 99; variablesForTouchArea[3].placesOfDecimals = 2; strcpy(variablesForTouchArea[3].variableTitle, "Res Point 1"); variablesForTouchArea[4].touchAreaIndex = COLUMN_DH_MANUAL_CALIB_EDIT_RES2; variablesForTouchArea[4].easyGUIVariablePtr = GuiVar_columnDHManualCalibRes2; variablesForTouchArea[4].maxValue = 99; variablesForTouchArea[4].placesOfDecimals = 2; strcpy(variablesForTouchArea[4].variableTitle, "Res Point 2"); variablesForTouchArea[5].touchAreaIndex = COLUMN_DH_MANUAL_CALIB_EDIT_RES3; variablesForTouchArea[5].easyGUIVariablePtr = GuiVar_columnDHManualCalibRes3; variablesForTouchArea[5].maxValue = 99; variablesForTouchArea[5].placesOfDecimals = 2; strcpy(variablesForTouchArea[5].variableTitle, "Res Point 3"); } // Private destructor also ColumnDHManualCalibrationPageHandler::~ColumnDHManualCalibrationPageHandler() { } /* Tells the caller whether or not the specified touch index is on the easyGUI 'ColumnDHAutoCalibrationPage', and therefore needs to be handled by this class. Args: the touch area index in question Return code: true if the touch area is 'one of ours', false if not */ bool ColumnDHManualCalibrationPageHandler::TouchAreaIsOnCalibrationPage(int touchAreaIndex) { if((touchAreaIndex >= MIN_COLUMN_DH_MANUAL_CALIB_TOUCHINDEX) && (touchAreaIndex <= MAX_COLUMN_DH_MANUAL_CALIB_TOUCHINDEX)) { return true; } // 'else' return false; } /* If the specified touch area represents a key or field on the easyGUI 'ColumnDHManualCalibrationPage', this function performs whatever action is appropriate for it. Provided so that the caller can (in effect) say "if this is one of yours, deal with it", without needing to know anything about what this class does, or how it handles the touch areas on that easyGUI page. Args: the touch area index in question Returns true if it dealt with the touch area (so the caller need not do anything else with the value), or false if it did not deal with the touch area (implying that it was not a touch area on the easyGUI 'Directly Heated Column Manual CalibrationPage', and so the caller must deal with it some other way). */ bool ColumnDHManualCalibrationPageHandler::DealWithTouch(int touchAreaIndex) { bool dealtWithTouch = false; // so far... // Has the user selected a field to edit - // if so, we will have an entry in our 'variablesForTouchArea' array that corresponds with this touch area int indexOfValueToEdit = GetIndexOfValueToEditForTouchArea(touchAreaIndex); if(indexOfValueToEdit != -1) { // User has selected a field to edit NumericKeypadPageHandler* numericKeypadPageHandler = NumericKeypadPageHandler::GetInstance(usbDevice, usbHostGC); if(numericKeypadPageHandler != NULL) { numericKeypadPageHandler->StartEditing(variablesForTouchArea[indexOfValueToEdit].easyGUIVariablePtr, variablesForTouchArea[indexOfValueToEdit].placesOfDecimals); numericKeypadPageHandler->SetEasyGUIVariableToEdit(variablesForTouchArea[indexOfValueToEdit].easyGUIVariablePtr); numericKeypadPageHandler->SetEasyGUICallingPage(GuiStruct_ColumnDHManualCalibrationPage_Def); numericKeypadPageHandler->SetEditVariableRange(0, variablesForTouchArea[indexOfValueToEdit].maxValue); numericKeypadPageHandler->SetEditVariableName(variablesForTouchArea[indexOfValueToEdit].variableTitle); numericKeypadPageHandler->DisplayEasyGUIPage(); } dealtWithTouch = true; } if(!dealtWithTouch) { switch(touchAreaIndex) { case COLUMN_DH_MANUAL_CALIB_SET: SetCurrentCalibrationInGC(); dealtWithTouch = true; break; case COLUMN_DH_MANUAL_CALIB_GET: GetCurrentCalibrationFromGC(); dealtWithTouch = true; break; default: // Not recognised - do nothing break; } } return dealtWithTouch; } /* Caller is telling us it is about to display the easyGUI 'ColumnDHManualCalibrationPage', and that we should do whatever we have to do to get it ready, before the caller displays it. No arguments, no return code */ void ColumnDHManualCalibrationPageHandler::DisplayingEasyGUIPage(bool updateEasyGUIVariables) { if(updateEasyGUIVariables) { GetCurrentCalibrationFromGC(); } } /* Gets the current calibration temperature and resistance values from the GC, and copies them into the relevant easyGUI variables for display to the user. No arguments, no return code */ void ColumnDHManualCalibrationPageHandler::GetCurrentCalibrationFromGC(void) { GetColumnTemperaturePointFromGC(1, GuiVar_columnDHManualCalibTemp1); GetColumnResistancePointFromGC(1, GuiVar_columnDHManualCalibRes1); GetColumnTemperaturePointFromGC(2, GuiVar_columnDHManualCalibTemp2); GetColumnResistancePointFromGC(2, GuiVar_columnDHManualCalibRes2); GetColumnTemperaturePointFromGC(3, GuiVar_columnDHManualCalibTemp3); GetColumnResistancePointFromGC(3, GuiVar_columnDHManualCalibRes3); } /* Sets the calibration temperature and resistance values in the GC, to match the values we are currently displayin to the user. No arguments, no return code */ void ColumnDHManualCalibrationPageHandler::SetCurrentCalibrationInGC(void) { SetColumnTemperaturePointInGC(1, GuiVar_columnDHManualCalibTemp1); SetColumnResistancePointInGC(1, GuiVar_columnDHManualCalibRes1); SetColumnTemperaturePointInGC(2, GuiVar_columnDHManualCalibTemp2); SetColumnResistancePointInGC(2, GuiVar_columnDHManualCalibRes2); SetColumnTemperaturePointInGC(3, GuiVar_columnDHManualCalibTemp3); SetColumnResistancePointInGC(3, GuiVar_columnDHManualCalibRes3); } /* As the name implies, sends a command to the GC and returns the response. Args: pointer to a buffer containing the command, as a null-terminated string pointer to a buffer to contain the response, as a null-terminated string No return code (it is up to the caller to examine the response to see whether the command succeeded or failed) */ void ColumnDHManualCalibrationPageHandler::SendCommandToGCAndGetResponse(char* command, char* response) { #define USE_GC_UTILS // Testing new class #ifdef USE_GC_UTILS USBHostGCUtilities::SendCommandToGCAndGetResponse(usbDevice, usbHostGC, command, response); #else while(usbHostGC->ExecutingSetDeviceReport()) {} usbHostGC->SetDeviceReport(usbDevice, command, response); //#define DEBUG_PRINT_HERE #ifdef DEBUG_PRINT_HERE char dbg[100]; sprintf(dbg, "SCTGC cmd \"%s\", response \"%s\"", command, response); SpecialDebugPrint(dbg, 10, 275); #endif // DEBUG_PRINT_HERE #endif // USE_GC_UTILS } /* Sends a command to the GC for which we expect a response of "DACK" if successful, "DNAK" or "EPKT" if failure. Args: a pointer to the command in question, as a null terminated string Returns true if the GC responded with "DACK", false for anything else */ bool ColumnDHManualCalibrationPageHandler::SendCommandToGCWithDACKResponse(char *cmd) { #define USE_GC_UTILS // Testing new class #ifdef USE_GC_UTILS return USBHostGCUtilities::SendCommandToGCWithDACKResponse(usbDevice, usbHostGC, cmd); #else char response[50]; SendCommandToGCAndGetResponse(cmd, response); // We expect a response like this: "DACK" for success, "DNAK" for failure, "EPKT" for error return (response[1] == 'A'); #endif // USE_GC_UTILS } /* There are three temperature points included in the manual calibration of the DH column. This function gets the value for the specified point, and copies it into the specified easyGUI variable (to be displayed on the easyGUI ColumnDHManualCalibration page). Args: the number of the point to be displayed (1, 2 or 3) a pointer to the corresponding easyGUI variable Returns true if successful, false if not. */ bool ColumnDHManualCalibrationPageHandler::GetColumnTemperaturePointFromGC(int pointNumber, GuiConst_TEXT* easyGUIVariable) { char cmd[50]; char response[50]; if((pointNumber < 1) || (pointNumber > 3)) { return false; } sprintf(cmd, "GCT%d", pointNumber); SendCommandToGCAndGetResponse(cmd, response); if(response[0] != 'D') return false; if(response[1] != 'C') return false; if(response[2] != 'T') return false; if(response[3] != cmd[3]) return false; // Response is in units of 1/10 degree C - // and we don't want leading zeroes int index = 0; bool wantZeroes = false; if(response[4] != '0') { easyGUIVariable[index++] = response[4]; wantZeroes = true; } if((response[5] != '0') || wantZeroes) { easyGUIVariable[index++] = response[5]; } easyGUIVariable[index++] = response[6]; easyGUIVariable[index++] = '.'; easyGUIVariable[index++] = response[7]; easyGUIVariable[index] = '\0'; return true; } /* There are three temperature points included in the manual calibration of the DH column. This function sets the value for the specified point in the GC from our internal variable, whose value matches the one displayed to the user in the relevant easyGUI variable. Args: the number of the point to be displayed (1, 2 or 3) Returns true if successful, false if not. */ bool ColumnDHManualCalibrationPageHandler::SetColumnTemperaturePointInGC(int pointNumber, GuiConst_TEXT* easyGUIVariable) { char cmd[50]; if((pointNumber < 1) || (pointNumber > 3)) { return false; } // temperature is passed to the GC in units of 0.1 degree C float temp; sscanf(easyGUIVariable, "%f", &temp); int gcTemp = (int)(temp * 10.0f); // In the command, the temperature value must have 4 digits, padded if necessary with leading zeroes sprintf(cmd, "SCT%d%.4d", pointNumber, gcTemp); return SendCommandToGCWithDACKResponse(cmd); } /* There are three resistance points included in the manual calibration of the DH column. This function gets the value for the specified point, and copies it into the specified easyGUI variable (to be displayed on the easyGUI ColumnDHManualCalibration page). Args: the number of the point to be displayed (1, 2 or 3) a pointer to the corresponding easyGUI variable Returns true if successful, false if not. */ bool ColumnDHManualCalibrationPageHandler::GetColumnResistancePointFromGC(int pointNumber, GuiConst_TEXT* easyGUIVariable) { char cmd[50]; char response[50]; if((pointNumber < 1) || (pointNumber > 3)) { return false; } sprintf(cmd, "GCR%d", pointNumber); SendCommandToGCAndGetResponse(cmd, response); if(response[0] != 'D') return false; if(response[1] != 'C') return false; if(response[2] != 'R') return false; if(response[3] != cmd[3]) return false; // Response is in units of 1/100 ohm - // and we don't want leading zeroes int index = 0; if(response[4] != '0') easyGUIVariable[index++] = response[4]; easyGUIVariable[index++] = response[5]; easyGUIVariable[index++] = '.'; easyGUIVariable[index++] = response[6]; easyGUIVariable[index++] = response[7]; easyGUIVariable[index] = '\0'; return true; } /* There are three resistance points included in the manual calibration of the DH column. This function sets the value for the specified point in the GC from our internal variable, whose value matches the one displayed to the user in the relevant easyGUI variable. Args: the number of the point to be displayed (1, 2 or 3) Returns true if successful, false if not. */ bool ColumnDHManualCalibrationPageHandler::SetColumnResistancePointInGC(int pointNumber, GuiConst_TEXT* easyGUIVariable) { char cmd[50]; if((pointNumber < 1) || (pointNumber > 3)) { return false; } // Resistance is passed to the GC in units of 0.01 ohm float res; sscanf(easyGUIVariable, "%f", &res); int gcRes = (int)(res * 100.0f); // In the command, the resistance value must have 4 digits, padded if necessary with leading zeroes sprintf(cmd, "SCR%d%.4d", pointNumber, gcRes); return SendCommandToGCWithDACKResponse(cmd); } /* (Re)display the easyGUI 'ColumnDHManualCalibrationPage' - e.g. after the caller has updated one or more of the easyGUI variables included in the page, and wants to display the new value to the user. No arguments, no return code */ void ColumnDHManualCalibrationPageHandler::UpdateEasyGUIPage(void) { GetGCStatusLoop *getGCStatusLoop = GetGCStatusLoop::GetInstance(); if(getGCStatusLoop != NULL) { // The Gas Calibration page has a status rectangle for the gas - // GetGCStatusLoop can display this, we cannot getGCStatusLoop->ForceUpdateOfColumnDHManualCalibrationPage(); } } /* Tells the caller if the specified touch area corresponds to a value the user can edit on the easyGUI 'ColumnDHManualCalibrationPage', and if so, which one. Args: the touch area index in question Returns the index of the corresponding entry in our 'variablesForTouchArea' array, or -1 if there is no such entry. It is up to the caller to check for -1 ************************************** */ int ColumnDHManualCalibrationPageHandler::GetIndexOfValueToEditForTouchArea(int touchAreaIndex) { for (int index = 0; index < COUNT_OF_VARIABLES_FOR_TOUCH_AREAS; ++index) { if(variablesForTouchArea[index].touchAreaIndex == touchAreaIndex) { return index; } } // 'else' no Column DH Manual Calibration value corresponds to the specified touch area return -1; }