Repository for import to local machine

Dependencies:   DMBasicGUI DMSupport

MethodRampData.cpp

Committer:
jmitc91516
Date:
2017-07-31
Revision:
8:26e49e6955bd
Parent:
6:dba3fbdfd5da

File content as of revision 8:26e49e6955bd:

#include "MethodRampData.h"
#include "EasyGUITouchAreaIndices.h"
#include "USBHostGCUtilities.h"

#include <float.h>

/*
    MethodRampData - the base, abstract, class.
*/

const GuiConst_INTCOLOR MethodRampData::oddRampEasyGUIColour = 0; // RGB565(0, 0, 0) - black
const GuiConst_INTCOLOR MethodRampData::evenRampEasyGUIColour = 33808; // RGB565(128, 128, 128) - grey

// Constructor - passed pointers for the USB link to the GC
MethodRampData::MethodRampData(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC)
{
    usbDevice = newUsbDevice;
    usbHostGC = newUsbHostGC;

    rampCount = 0;
    
    gotRampData = false;

    for (int rampIndex = 0; rampIndex < MAX_RAMP_COUNT; ++rampIndex) {
        rampData[rampIndex].rampRate = 0.0f;
        rampData[rampIndex].rampUpperLimit = 0.0f;
        rampData[rampIndex].rampUpperTime = 0.0f;
    }

    // Derived classes need to set the EasyGUI variable names,
    // and their sprintf format strings, in *their* constructors

    needToUpdateEasyGUIMethodPageRampVariables = true;
}


/*
    Gets an integer value from the GC, using the specified command and ramp index.
    For all the "get ramp value xxx" commands, the GC returns an eight character string,
    the last four of which are the value. 
    
    Args: pointer to a null-terminated string containing the first three chars of the command (e.g. "GRP" for the column temperature ramp rate).
          the ramp index (this must be in the range 0-9).
    
    Returns the corresponding ramp value obtained from the GC, or 0 if there was a problem - e.g. the ramp index was invalid,
    GC returned "EPKT", etc. (We choose 0 for this, not (say) -1, because a ramp rate of zero means "no ramp at this index".
    Apply that rule consistently everywhere.)
    
    *** It is up to the caller to convert this function's return value to the correct units ***
        e.g. the ramp upper time, for all three ramp types, is in units of 0.1 minute, so the caller
        has to (1) convert the integer value to a float, and (2) divide by 10.
        This function simply says "the four digits returned by the GC had this value".
*/
int MethodRampData::GetIntRampValueFromGC(char *firstThreeCharsOfCommand, unsigned int rampIndex)
{
    if(rampIndex > 9) {
        return 0; // A ramp value of zero means "no ramp at this index" 
    }
    
    char command[50];
    sprintf(command, "%s%u", firstThreeCharsOfCommand, rampIndex);

    char response[50];
    USBHostGCUtilities::SendCommandToGCAndGetResponse(usbDevice, usbHostGC, command, response);

    if(response[0] == 'E') {
        // Assume "EPKT"
        return 0; // A ramp value of zero means "no ramp at this index"
    }
    
    int retVal;
    sscanf(&response[4], "%d", &retVal);
    
    return retVal;
}


/*
    This functions fills the ramp data array with the actual ramp data from the GC.
    After this, the caller can use the "GetRampTemperatureRate", etc, functions
    to find out what the ramp values actually are.
    
    Note that it is up to the caller to call this function when required,
    e.g. when the Column Method page is first entered, the ramp data has changed
    because a new method has been downloaded, etc.
    
    No arguments, no return code.
*/
void MethodRampData::GetRampDataFromGC(void)
{
    rampCount = 0;

    int rampIndex;
    float currentRampRate;
    for (rampIndex = 0; rampIndex < MAX_RAMP_COUNT; ++rampIndex) {
        
        currentRampRate = GetRampRateFromGC(rampIndex);
        if(currentRampRate < FLT_MIN) { // Avoid rounding errors - do not test for equality with zero
        
            // No more ramps - don't waste time getting any more data from the GC,
            // and stop incrementing 'rampCount'
            break;
        }
        rampData[rampIndex].rampRate = currentRampRate;

        rampData[rampIndex].rampUpperLimit = GetRampUpperLimitFromGC(rampIndex);
        rampData[rampIndex].rampUpperTime = GetRampUpperTimeFromGC(rampIndex);
        
        ++rampCount;
    }

    // Fill the data for any remaining ramps with zeroes
    for (; rampIndex < MAX_RAMP_COUNT; ++rampIndex) {
        rampData[rampIndex].rampRate = 0.0f;
        rampData[rampIndex].rampUpperLimit = 0.0f;
        rampData[rampIndex].rampUpperTime = 0.0f;
    }
    
    gotRampData = true;
    
    needToUpdateEasyGUIMethodPageRampVariables = true;
}


/*
    Gets the rate of temperature/pressure increase for the specified ramp, if it exists.
    
    Args: the ramp index
          a pointer to an float to contain the ramp rate
          (in units of degrees C/min for column and injector, psi/min for gas)
          
    Returns true if we have a ramp at that index, false if not
*/
bool MethodRampData::GetRampRate(unsigned int rampIndex, float *rampRate)
{
    if(rampIndex < rampCount) {
        *rampRate = rampData[rampIndex].rampRate;
        
        return true;
    }
    
    // 'else' - no ramp at that index
    *rampRate = 0.0f;
    return false;
}


/*
    Gets the upper limit for the specified ramp, if it exists.
    
    Args: the ramp index
          a pointer to a float to contain the upper limit
          (in units of degrees C for column and injector, psi for gas)
          
    Returns true if we have a ramp at that index, false if not
*/
bool MethodRampData::GetRampUpperLimit(unsigned int rampIndex, float *rampUpperLimit)
{
    if(rampIndex < rampCount) {
        *rampUpperLimit = rampData[rampIndex].rampUpperLimit;
        
        return true;
    }
    
    // 'else' - no ramp at that index
    *rampUpperLimit = 0.0f;
    return false;
}


/*
    Gets the upper hold time for the specified ramp, if it exists.
    
    Args: the ramp index
          a pointer to an float to contain the upper hold time 
          (in units of minutes, to one decimal place)
          
    Returns true if we have a ramp at that index, false if not
*/
bool MethodRampData::GetRampUpperTime(unsigned int rampIndex, float *rampUpperTime)
{
    if(rampIndex < rampCount) {
        *rampUpperTime = rampData[rampIndex].rampUpperTime;
        
        return true;
    }
    
    // 'else' - no ramp at that index
    *rampUpperTime = 0.0f;
    return false;
}


/*
    Updates the easyGUI variables, shown on the relevant EasyGUI Method page, that show the ramp data, 
    with the current ramp values, starting at the specified ramp.
    
    Args: the index of the first ramp to display (there are up to nine ramps, 
          but every EasyGUI Method page can only display a maximum of five, 
          so we may have to scroll thrugh them)
          
    No return code.
    
    Note that it is up to the caller, by calling "NeedToUpdateEasyGUIMethodPageRampVariables",
    to verify that the EasyGUI Method page variables actually need to be updated.
*/
void MethodRampData::UpdateEasyGUIMethodPageVariables(unsigned int firstRampIndex)
{
    int rampIndex;
    int lineIndex;
    for (lineIndex = 0, rampIndex = firstRampIndex; (rampIndex < rampCount) && (lineIndex < EASYGUI_RAMP_LINES); ++lineIndex, ++rampIndex) {
        sprintf(easyGUIRampNumber[lineIndex], "%d", (rampIndex + 1)); // Show 1 as the first ramp number, not 0
        sprintf(easyGUIRampRateVariable[lineIndex], easyGUIRampRateSprintfFormat, rampData[rampIndex].rampRate);
        sprintf(easyGUIRampUpperLimitVariable[lineIndex], easyGUIRampUpperLimitSprintfFormat, rampData[rampIndex].rampUpperLimit);
        sprintf(easyGUIRampUpperTimeVariable[lineIndex], easyGUIRampUpperTimeSprintfFormat, rampData[rampIndex].rampUpperTime);
    }
    
    // If there are any easyGUI variables left, below the ones we have just updated, clear them
    for (; lineIndex < EASYGUI_RAMP_LINES; ++lineIndex) {
        easyGUIRampNumber[lineIndex][0] = '\0';
        easyGUIRampRateVariable[lineIndex][0] = '\0';
        easyGUIRampUpperLimitVariable[lineIndex][0] = '\0';
        easyGUIRampUpperTimeVariable[lineIndex][0] = '\0';
    }
    
    if((firstRampIndex & 1) == 0) { // First ramp has an even number - so it appears on an odd-numbered row on the easyGUI page
        *easyGUIMethodRampOddRowsColour = oddRampEasyGUIColour;
        *easyGUIMethodRampEvenRowsColour = evenRampEasyGUIColour;
    } else {
        *easyGUIMethodRampOddRowsColour = evenRampEasyGUIColour;
        *easyGUIMethodRampEvenRowsColour = oddRampEasyGUIColour;
    }

    needToUpdateEasyGUIMethodPageRampVariables = false;
}



/*
    Tells the caller how many ramps are "off screen" in the EasyGUI Method page.
*/
unsigned int MethodRampData::GetScrollRange(void)
{
    if(rampCount > EASYGUI_RAMP_LINES) {
        return (rampCount - EASYGUI_RAMP_LINES);
    }
    
    // 'else'...
    return 0;
}


/*
    ColumnMethodRampData - handles the column method, with its own commands to get the ramp data,
                           and its own easyGUI variables to display it
*/

// Constructor - passed pointers for the USB link to the GC
ColumnMethodRampData::ColumnMethodRampData(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC) : MethodRampData(newUsbDevice, newUsbHostGC)
{
    // Remember there are 5 easyGUI ramp lines (EASYGUI_RAMP_LINES enum)
    
    easyGUIRampNumber[0] = GuiVar_columnMethodRampNumber1;
    easyGUIRampNumber[1] = GuiVar_columnMethodRampNumber2;
    easyGUIRampNumber[2] = GuiVar_columnMethodRampNumber3;
    easyGUIRampNumber[3] = GuiVar_columnMethodRampNumber4;
    easyGUIRampNumber[4] = GuiVar_columnMethodRampNumber5;

    easyGUIRampRateVariable[0] = GuiVar_columnMethodRampRate1;
    easyGUIRampRateVariable[1] = GuiVar_columnMethodRampRate2;
    easyGUIRampRateVariable[2] = GuiVar_columnMethodRampRate3;
    easyGUIRampRateVariable[3] = GuiVar_columnMethodRampRate4;
    easyGUIRampRateVariable[4] = GuiVar_columnMethodRampRate5;

    easyGUIRampUpperLimitVariable[0] = GuiVar_columnMethodRampUpper1;
    easyGUIRampUpperLimitVariable[1] = GuiVar_columnMethodRampUpper2;
    easyGUIRampUpperLimitVariable[2] = GuiVar_columnMethodRampUpper3;
    easyGUIRampUpperLimitVariable[3] = GuiVar_columnMethodRampUpper4;
    easyGUIRampUpperLimitVariable[4] = GuiVar_columnMethodRampUpper5;
    
    easyGUIRampUpperTimeVariable[0] = GuiVar_columnMethodRampHold1;
    easyGUIRampUpperTimeVariable[1] = GuiVar_columnMethodRampHold2;
    easyGUIRampUpperTimeVariable[2] = GuiVar_columnMethodRampHold3;
    easyGUIRampUpperTimeVariable[3] = GuiVar_columnMethodRampHold4;
    easyGUIRampUpperTimeVariable[4] = GuiVar_columnMethodRampHold5;
    
    // When we write our internal (float) values to the EasyGUI (string) variables,
    // these are the format strings we use
    strcpy(easyGUIRampRateSprintfFormat, "%.0f"); // degrees C per minute - a whole number
    strcpy(easyGUIRampUpperLimitSprintfFormat, "%.0f"); // degrees C - a whole number
    strcpy(easyGUIRampUpperTimeSprintfFormat, "%.1f"); // In minutes, but in "units" of 0.1 minute
    
    easyGUIMethodRampOddRowsColour = &GuiVar_columnMethodRampOddRowsColour;
    easyGUIMethodRampEvenRowsColour = &GuiVar_columnMethodRampEvenRowsColour;
}

float ColumnMethodRampData::GetRampRateFromGC(unsigned int rampIndex)
{
    // The column method ramp rate is obtained from the GC in units of degree C / min
    return (float)GetIntRampValueFromGC("GRP", rampIndex);
}


float ColumnMethodRampData::GetRampUpperLimitFromGC(unsigned int rampIndex)
{
    // The column method ramp upper limit is a temperature, obtained from the GC in units of degree C
    return (float)GetIntRampValueFromGC("GRC", rampIndex);
}


float ColumnMethodRampData::GetRampUpperTimeFromGC(unsigned int rampIndex)
{
    // The column method ramp upper time is obtained from the GC in units of 0.1 minute
    return (((float)GetIntRampValueFromGC("GRS", rampIndex)) / 10.0f);
}


/*
    InjectorMethodRampData - handles the injector method, with its own commands to get the ramp data,
                           and its own easyGUI variables to display it
*/

// Constructor - passed pointers for the USB link to the GC
InjectorMethodRampData::InjectorMethodRampData(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC) : MethodRampData(newUsbDevice, newUsbHostGC)
{
    // Remember there are 5 easyGUI ramp lines (EASYGUI_RAMP_LINES enum)
    
    // TODO: insert the correct easyGUI variables below
    easyGUIRampNumber[0] = GuiVar_injectorMethodRampNumber1;
    easyGUIRampNumber[1] = GuiVar_injectorMethodRampNumber2;
    easyGUIRampNumber[2] = GuiVar_injectorMethodRampNumber3;
    easyGUIRampNumber[3] = GuiVar_injectorMethodRampNumber4;
    easyGUIRampNumber[4] = GuiVar_injectorMethodRampNumber5;

    easyGUIRampRateVariable[0] = GuiVar_injectorMethodRampRate1;
    easyGUIRampRateVariable[1] = GuiVar_injectorMethodRampRate2;
    easyGUIRampRateVariable[2] = GuiVar_injectorMethodRampRate3;
    easyGUIRampRateVariable[3] = GuiVar_injectorMethodRampRate4;
    easyGUIRampRateVariable[4] = GuiVar_injectorMethodRampRate5;

    easyGUIRampUpperLimitVariable[0] = GuiVar_injectorMethodRampUpper1;
    easyGUIRampUpperLimitVariable[1] = GuiVar_injectorMethodRampUpper2;
    easyGUIRampUpperLimitVariable[2] = GuiVar_injectorMethodRampUpper3;
    easyGUIRampUpperLimitVariable[3] = GuiVar_injectorMethodRampUpper4;
    easyGUIRampUpperLimitVariable[4] = GuiVar_injectorMethodRampUpper5;
    
    easyGUIRampUpperTimeVariable[0] = GuiVar_injectorMethodRampHold1;
    easyGUIRampUpperTimeVariable[1] = GuiVar_injectorMethodRampHold2;
    easyGUIRampUpperTimeVariable[2] = GuiVar_injectorMethodRampHold3;
    easyGUIRampUpperTimeVariable[3] = GuiVar_injectorMethodRampHold4;
    easyGUIRampUpperTimeVariable[4] = GuiVar_injectorMethodRampHold5;
    
    // When we write our internal (float) values to the EasyGUI (string) variables,
    // these are the format strings we use
    strcpy(easyGUIRampRateSprintfFormat, "%.0f"); // degrees C per minute - a whole number
    strcpy(easyGUIRampUpperLimitSprintfFormat, "%.0f"); // degrees C - a whole number
    strcpy(easyGUIRampUpperTimeSprintfFormat, "%.1f"); // In minutes, but in "units" of 0.1 minute
    
    easyGUIMethodRampOddRowsColour = &GuiVar_injectorMethodRampOddRowsColour;
    easyGUIMethodRampEvenRowsColour = &GuiVar_injectorMethodRampEvenRowsColour;
}

float InjectorMethodRampData::GetRampRateFromGC(unsigned int rampIndex)
{
    // The injector method ramp rate is obtained from the GC in units of degree C / min
    return (float)GetIntRampValueFromGC("GIP", rampIndex);
}


float InjectorMethodRampData::GetRampUpperLimitFromGC(unsigned int rampIndex)
{
    // The injector method ramp upper limit is a temperature, obtained from the GC in units of degree C
    return (float)GetIntRampValueFromGC("GIC", rampIndex);
}


float InjectorMethodRampData::GetRampUpperTimeFromGC(unsigned int rampIndex)
{
    // The injector method ramp upper time is obtained from the GC in units of 0.1 minute
    return (((float)GetIntRampValueFromGC("GIS", rampIndex)) / 10.0f);
}


/*
    GasMethodRampData - handles the gas method, with its own commands to get the ramp data,
                           and its own easyGUI variables to display it
*/

// Constructor - passed pointers for the USB link to the GC
GasMethodRampData::GasMethodRampData(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC) : MethodRampData(newUsbDevice, newUsbHostGC)
{
    // Remember there are 5 easyGUI ramp lines (EASYGUI_RAMP_LINES enum)
    
    // TODO: insert the correct easyGUI variables below
    easyGUIRampNumber[0] = GuiVar_gasMethodRampNumber1;
    easyGUIRampNumber[1] = GuiVar_gasMethodRampNumber2;
    easyGUIRampNumber[2] = GuiVar_gasMethodRampNumber3;
    easyGUIRampNumber[3] = GuiVar_gasMethodRampNumber4;
    easyGUIRampNumber[4] = GuiVar_gasMethodRampNumber5;

    easyGUIRampRateVariable[0] = GuiVar_gasMethodRampRate1;
    easyGUIRampRateVariable[1] = GuiVar_gasMethodRampRate2;
    easyGUIRampRateVariable[2] = GuiVar_gasMethodRampRate3;
    easyGUIRampRateVariable[3] = GuiVar_gasMethodRampRate4;
    easyGUIRampRateVariable[4] = GuiVar_gasMethodRampRate5;

    easyGUIRampUpperLimitVariable[0] = GuiVar_gasMethodRampUpper1;
    easyGUIRampUpperLimitVariable[1] = GuiVar_gasMethodRampUpper2;
    easyGUIRampUpperLimitVariable[2] = GuiVar_gasMethodRampUpper3;
    easyGUIRampUpperLimitVariable[3] = GuiVar_gasMethodRampUpper4;
    easyGUIRampUpperLimitVariable[4] = GuiVar_gasMethodRampUpper5;
    
    easyGUIRampUpperTimeVariable[0] = GuiVar_gasMethodRampHold1;
    easyGUIRampUpperTimeVariable[1] = GuiVar_gasMethodRampHold2;
    easyGUIRampUpperTimeVariable[2] = GuiVar_gasMethodRampHold3;
    easyGUIRampUpperTimeVariable[3] = GuiVar_gasMethodRampHold4;
    easyGUIRampUpperTimeVariable[4] = GuiVar_gasMethodRampHold5;
    
    // When we write our internal (float) values to the EasyGUI (string) variables,
    // these are the format strings we use
    strcpy(easyGUIRampRateSprintfFormat, "%.2f"); // In "units" of 0.01 psi per minute - i.e. 2 decimal places
    strcpy(easyGUIRampUpperLimitSprintfFormat, "%.1f"); // In "units" of 0.1 psi - so 1 decimal place
    strcpy(easyGUIRampUpperTimeSprintfFormat, "%.1f"); // In minutes, but in "units" of 0.1 minute
    
    easyGUIMethodRampOddRowsColour = &GuiVar_gasMethodRampOddRowsColour;
    easyGUIMethodRampEvenRowsColour = &GuiVar_gasMethodRampEvenRowsColour;
}

float GasMethodRampData::GetRampRateFromGC(unsigned int rampIndex)
{
    // The gas method ramp rate is obtained from the GC in units of 0.01 psi / min
    return (((float)GetIntRampValueFromGC("GPR", rampIndex)) / 100.0f);
}


float GasMethodRampData::GetRampUpperLimitFromGC(unsigned int rampIndex)
{
    // The gas method ramp upper limit is a pressure, obtained from the GC in units of 0.1 psi
    return (((float)GetIntRampValueFromGC("GPU", rampIndex)) / 10.0f);
}


float GasMethodRampData::GetRampUpperTimeFromGC(unsigned int rampIndex)
{
    // The gas method ramp upper time is obtained from the GC in units of 0.1 minute.
    // *** There does not seem to be a separate GC command for this in the gas method. ***
    // *** Using the command for the column method until we clarify this.              ***
    return (((float)GetIntRampValueFromGC("GRS", rampIndex)) / 10.0f);
}