Class Issue

I am calling the functions as such - the debug statement prints out the values on the serial monitor (#define debug Serial.println)

The issue is when I get the data the first time i get the correct values out, but when I call it again later the values are big negative numbers like -4357.

Am I missing something really obvious? Thanks

int midway = (params->param[gaugeIndex[i]].getMax(units) + params->param[gaugeIndex[i]].getMin(units)) / 2;
      int fourth = (params->param[gaugeIndex[i]].getMax(units) + abs(params->param[gaugeIndex[i]].getMin(units))) / 4;
      debug(params->param[gaugeIndex[i]].getMin(units));
class Parameter
{
  public:

    char *nickName;
    int minBound[3];
    int maxBound[3];
    int division[3];
    category subClass;  
    int ID;
    char *units[3];
    int displayDecimals;
    int displayDigits;

    
    Parameter()
     {
       nickName = "";
       minBound[0] = -1;
       minBound[1] = -1;
       minBound[2] = -1;
       maxBound[0] = -1;
       maxBound[1] = -1;
       maxBound[2] = -1;
       subClass = performance;
       ID = -1;
       units[0] = "";
       units[1] = "";
       units[2] = "";
       division[0] = -1;
       division[1] = -1;
       division[2] = -1;
       displayDecimals = 1;
       displayDigits = 2;
     } 
     
     virtual void add(int Identifier, char *nName, int minimumNormal, int maximumNormal, int divNormal, int minimumMetric, int maximumMetric, int divMetric, 
     int minimumAmerican, int maximumAmerican, int divAmerican, category subCat, char *NormalUnit, char *MetricUnit, char *AmericanUnit, int digits, int decimals)
     {
       ID = Identifier;
       nickName = nName;
       minBound[0] = minimumNormal;
       minBound[1] = minimumMetric;
       minBound[2] = minimumAmerican;
       maxBound[0] = maximumNormal; 
       maxBound[1] = maximumMetric; 
       maxBound[2] = maximumAmerican; 
       subClass = subCat;
       units[0] = NormalUnit;
       units[1] = MetricUnit;
       units[2] = AmericanUnit;
       division[0] = divNormal;
       division[1] = divMetric;
       division[2] = divAmerican;
       displayDecimals = decimals;
       displayDigits = digits;
     }
     
    int getID() { 
        return ID; 
    }

    char* getName() { 
        return nickName; 
    }

    //Gets the correct unit: 0 = Normal Units, 1 = Metric Units, 2 = American Units
    char* getUnit(int selection) {
        return units[selection];
    }

    int getMin(int selection) {
        return minBound[selection];
    }

    int getMax(int selection) {
        return maxBound[selection];
    }

    int getDivision(int selection){
        return division[selection];
    }

    int getDigits(){
        return displayDigits;
    }

    int getDecimals(){
        return displayDecimals;
    }
};

class Parameters
{
  public:
  Parameter *param = new Parameter[numOfParams];
  
  Parameters()
  {
                //ID,   Name,         Min, Max,  division min,  max, division    min    max  Division,  Sub Category, Unit 1,   Unit 2,     Unit 3,    dig, dec
    param[0].add(0,   "None",         0, 0,       0,      0,      0,      0,      0,      0,      0,      performance, "",        "",         "",         1, 0);
    param[1].add(1,     "1",            0, 350,     50,     0,      350,    50,    0,      45,     9,      performance, "g/s",     "g/s",      "lbs/min",  3, 1);
    param[2].add(2,     "F",    0, 300,     50,     0,      1135,   190,    0,      300,    50,     performance, "gal/hr",  "L/hr",     "gal/hr",   3, 1);
    param[3].add(3,     "V",        0, 16,      4,      0,      16,     4,      0,      16,     4,      performance, "V",       "V",        "V",        2, 1);
    param[4].add(4,     "Lo %",         0, 100,     25,     0,      100,    25,     0,      100,    25,     performance, "%",       "%",        "%",        3, 0);
    param[5].add(5,     "L 1",    -20, 20,    10,     -20,    20,     10,     -20,    20,     10,     performance, "%",       "%",        "%",        2, 2);
    param[6].add(6,     "L 2",    -20, 20,    10,     -20,    20,     10,     -20,    20,     10,     performance, "%",       "%",        "%",        2, 2);
    param[7].add(7,     "1",      -20, 20,    10,     -20,    20,     10,     -20,    20,     10,     performance, "%",       "%",        "%",        2, 2);
    param[8].add(8,     "S 2",    -20, 20,    10,     -20,    20,     10,     -20,    20,     10,     performance, "%",       "%",        "%",        2, 2);
    param[9].add(9,     "RM",           0, 7500,    1500,   0,      7500,   1500,   0,      7500,   1500,   performance, "RPM",     "RPM",      "RPM",      4, 0);
    param[10].add(10,   "ed",       0, 130,     25,     0,      210,    40,     0,      130,    25,     performance, "MPH",     "Km/hr",    "MPH",      3, 0);
    param[11].add(11,   "E",       0, 250,   50,     -18,    120,    10,     0,      250,    50,     performance, "°F",     "°C",      "°F",      3, 0);
    param[12].add(12,   "Oemp",    0, 250,     50,     -18,    120,    10,     0,      250,    50,     performance, "°F",     "°C",      "°F",      3, 0);
    param[13].add(13,   "The %",   0, 100,     25,     0,      100,    25,     0,      100,    25,     performance, "%",       "%",        "%",        3, 0);
    param[14].add(14,   "Ing", -60, 60,         30,     -60,    60,     30,     -60,    60,     30,     performance, "°TDC",   "°TDC",        "°TDC",        2, 1);
    param[15].add(15,   "Sk",        -60, 60,         30,     -60,    60,     30,     -60,    60,     30,     performance, "°TDC",   "°TDC",        "°TDC",        2, 1);
    param[16].add(16,   "I",            0, 150,   50,     -18,    70,     10,     0,      150,    50,     performance, "ºF",     "ºC",      "ºF",      3, 0);
    param[17].add(17,   "Fess",   0, 300,  100,    0,      2070,   690,    0,      300,    100,    performance, "PSI",     "kPA",      "PSI",      4, 0);
    param[18].add(18,   "M",     -25, 25,         25,     -170,   170,    170,    -25,    25,     25,     performance, "PSI",     "kPA",      "PSI",      3, 1);
    param[19].add(19,   "H",         0, 25,       25,     -170,   170,    170,    -25,    25,     25,     performance, "HP",      "HP",       "HP",       3, 1);
    param[20].add(20,   "Te",        0, 25,       25,     -170,   170,    170,    -25,    25,     25,     performance, "ft/lbs",  "ft/lbs",   "ft/lbs",   3, 1);
  }
  
};

Helicopter12:
I am calling the functions as such - the debug statement prints out the values on the serial monitor (#define debug Serial.println)

The issue is when I get the data the first time i get the correct values out, but when I call it again later the values are big negative numbers like -4357.

Am I missing something really obvious? Thanks

int midway = (params->param[gaugeIndex[i]].getMax(units) + params->param[gaugeIndex[i]].getMin(units)) / 2;

int fourth = (params->param[gaugeIndex[i]].getMax(units) + abs(params->param[gaugeIndex[i]].getMin(units))) / 4;
     debug(params->param[gaugeIndex[i]].getMin(units));

Whenever you get an unexpected output (and usually a negative one), then problem is caused by signed overflow.

What I mean is this: An Arduino INT is a signed 16 bit number. It can hold from +32767 to -32768.

So, say you did this:

[b]int x = 40000;
[/b]

40000 is too large for a signed 16 bit variable to hold, so the excess will “loop around” and stop wherever it needs to.

So, since the max is +32767, a value of +32768 “loops around” to -32768. Since the value of 40000 is more than a 16 bit signed integer can hold, the result ends up being -25536.

Check this out:

int main (void)
{
    char buf [64];

    init();
    Serial.begin (115200);

    uint32_t x;
    int16_t d;

    for (x = 30000; x <= 40000; x+=1000) {
        d = x;
        sprintf (buf, "large value: %lu, signed 16 bit overflow: %d\n", x, d);
        Serial.print (buf);
    }

    while (1);
}

Result:

** **large value: 30000, signed 16 bit overflow: 30000 large value: 31000, signed 16 bit overflow: 31000 large value: 32000, signed 16 bit overflow: 32000 large value: 33000, signed 16 bit overflow: -32536 large value: 34000, signed 16 bit overflow: -31536 large value: 35000, signed 16 bit overflow: -30536 large value: 36000, signed 16 bit overflow: -29536 large value: 37000, signed 16 bit overflow: -28536 large value: 38000, signed 16 bit overflow: -27536 large value: 39000, signed 16 bit overflow: -26536 large value: 40000, signed 16 bit overflow: -25536** **

See?

krupski: Whenever you get an unexpected output (and usually a negative one), then problem is caused by signed overflow.

What I mean is this: An Arduino INT is a signed 16 bit number. It can hold from +32767 to -32768.

So, say you did this:

[b]int x = 40000;
[/b]

40000 is too large for a signed 16 bit variable to hold, so the excess will "loop around" and stop wherever it needs to.

So, since the max is +32767, a value of +32768 "loops around" to -32768. Since the value of 40000 is more than a 16 bit signed integer can hold, the result ends up being -25536.

Interesting thanks for the example as well! I am still confused as to why the value in the class would be changing if I am only calling functions that return the data in the class. Any ideas on that part?

The problem is in the code you didn't post.

Somewhere you're writing off the end of an array and overwriting the values that you're looking at. Check all indexes are reasonable before using them in an array. It's too easy to write to minBound[3] when you're not looking for it. Classes let you do that test inside the class and make it "bulletproof" so writing params(1234).getMax(-1) will return a reasonable error value.

MorganS: The problem is in the code you didn't post.

Somewhere you're writing off the end of an array and overwriting the values that you're looking at. Check all indexes are reasonable before using them in an array. It's too easy to write to minBound[3] when you're not looking for it. Classes let you do that test inside the class and make it "bulletproof" so writing params(1234).getMax(-1) will return a reasonable error value.

Yes you are correct, I was passing an out of bound index for debugging and forgot to remove the code for it. Thank you for the fresh eyes!