Global var being set to zero soon after assignment in void fcn

Dear all, this is a code snip from the setup() fcn of a fairly big project running on a Mega2560. The observed behaviour is in the comments:

    initGlobalVars(); // rigStatus.rigCal.cal1.FFBounds.mx = 1.2; inside here
    DEBUGSERIAL.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 1.20
    DEBUGSERIAL.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 0.00 (!!)

To be clear, that is the same print statement twice, giving different results. There are no ISRs running at all - not least one that could change this value while not looking, and nor is it declared volatile anywhere anyway.

Worth noting that the struct "cal1" is defined in an #included header file and declared as part of the principal sketch header file. It compiles and runs without warnings.

I'm just looking for any intuition or experience that may suggest where to look into this one as it has me stumped...

As a bit of extra fun:

    initGlobalVars(); // rigStatus.rigCal.cal1.FFBounds.mx = 1.2; inside here
    DEBUGSERIAL.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 1.20
    DEBUGSERIAL.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 0.00 (!!)
    rigStatus.rigCal.cal1.FFBounds.mx = 1.2;
    DEBUGSERIAL.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 1.20
    DEBUGSERIAL.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 1.20 (!!!)

and

    initGlobalVars(); // rigStatus.rigCal.cal1.FFBounds.mx = 1.2; inside here
    rigStatus.rigCal.cal1.FFBounds.mx = 1.2;
    DEBUGSERIAL.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 1.20
    DEBUGSERIAL.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 0.00 (!!)

Any assistance appreciated, thanks!!

Please post a complete sketch that illustrates the problem. It does not have to be your full project sketch as long as it can be compiled and tested

Wow, code snippets.

The only thing I can see to try is

rigStatus.rigCal.cal1.FFBounds.mx = 1.2;
    DEBUGSERIAL.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 1.20
rigStatus.rigCal.cal1.FFBounds.mx = 1.2;
    DEBUGSERIAL.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 0.00 (!!)

working on it

    initGlobalVars(); // rigStatus.rigCal.cal1.FFBounds.mx = 1.2; inside here
    rigStatus.rigCal.cal1.FFBounds.mx = 1.2;
    DEBUGSERIAL.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 1.20
    rigStatus.rigCal.cal1.FFBounds.mx = 1.2;
    DEBUGSERIAL.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 1.20

Well there you go, based upon the code snippet, problem solved.

1 Like

This has all the symptoms of memory problems, e.g. writing outside the bounds of arrays. I suggest that you scrutinise your code.

Yeah, palliative therapy, not curative.

1 Like

What can I do, when all I had was a code snippet to work with? Not my idea of a good solution.

you nailed it, thanks. Just found it as you posted but only through random commenting, not intuition. I still don't understand how the problem manifested many cycles after my error but a full sketch is below.

also lol

full sketch that can be compiled and run, including array indexing errors:

struct bounds {
    float mn; // minimum value
    float mx; // maximum value
};
struct DATA_LUT2D {
    float Ax[5]; // dimension 1 breakpoints
    float Ay[12]; // dimension 2 breakpoints
    float Mz[5][12]; // table data
    const int N1{ 5 }; // size of dimension 1
    const int N2{ 12 }; // size of dimension 2
};

struct CALIBRATION {
    DATA_LUT2D FFMapMain; // primary feed forward LUT
    bounds FFBounds; // bounds on feed forward control demand
    bounds ControlBounds; // bounds on overall control demand
    bounds FBBounds; // bounds on the feedback (PID) control demand
};

struct RIGCAL { // current calibration of rig
    CALIBRATION cal1; 
};

struct RIGSTATUS { // rig overall status
    RIGCAL rigCal; // struct of calibration structs
} rigStatus;

const struct FFMAPINIT { // feedforward calibration 
    const float Ax[5]         {0,10,15,40,60}; 
    const float Ay[12]        {0,2612,3325,5950,9075,12250,15325,18250,20825,22925,24350,24825}; 
    const float Mz[5][12]{    {1.200,1.000,0.900,0.800,0.700,0.600,0.500,0.400,0.300,0.200,0.100,0},
                              {1.200,1.000,0.900,0.800,0.700,0.600,0.500,0.400,0.300,0.200,0.100,0},
                              {1.200,1.000,0.900,0.800,0.700,0.600,0.500,0.400,0.300,0.200,0.100,0},
                              {1.200,1.000,0.900,0.800,0.700,0.600,0.500,0.400,0.300,0.200,0.100,0},
                              {1.200,1.000,0.900,0.800,0.700,0.600,0.500,0.400,0.300,0.200,0.100,0}};
}ffMapInit;

void setup() {
    Serial.begin(57600);
    initGlobalVars(); // rigStatus.rigCal.cal1.FFBounds.mx = 1.2; inside here
    Serial.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 1.20
    Serial.println(rigStatus.rigCal.cal1.FFBounds.mx); // prints 0.00
}

void loop() {
}

void initGlobalVars(){
    rigStatus.rigCal.cal1.ControlBounds.mx = 1.2;
    rigStatus.rigCal.cal1.ControlBounds.mn = 0;
    rigStatus.rigCal.cal1.FBBounds.mx = 1.2;
    rigStatus.rigCal.cal1.FBBounds.mn = 0;
    rigStatus.rigCal.cal1.FFBounds.mx = 1.2;
    rigStatus.rigCal.cal1.FFBounds.mn = 0;
    
    //CAUSES ERROR - note I am well aware I screwed up determining size of the arrays (should be / sizeof(ffMapInit.Ax[0])) - but how does this error affect the above variables many cycles later?
    for (int i=0;i<sizeof(ffMapInit.Ax);i++) {
        rigStatus.rigCal.cal1.FFMapMain.Ax[i]=ffMapInit.Ax[i];
    }

    for (int i=0;i<sizeof(ffMapInit.Ay);i++) {
        rigStatus.rigCal.cal1.FFMapMain.Ay[i]=ffMapInit.Ay[i];
    }
 
    for (int m = 0; m < sizeof(ffMapInit.Ax); m++) {
        for (int n = 0; n < (sizeof(ffMapInit.Ay)/sizeof(ffMapInit.Ay[0])); n++) {
            rigStatus.rigCal.cal1.FFMapMain.Mz[m][n] = ffMapInit.Mz[m][n];
        }
    }
}

I'd also be interested to know if you'd initialise the array differently to how I have, but that's a tangential topic that I can raise separately...
Thanks again!

Hi @UKHeliBob just wondering if you've anything to add now I've posted the full sketch as requested? It's still confusing me how an array indexing error can result in laying a future trap where I soon after read another variable twice and get different results.

Would also still be interested in how you intuited the cause correctly @sterretje

I know where I went wrong, but I don't know why it went wrong in that particular way, and something interesting probably lies beneath...

Thanks again

Experience :sob:

If adding or removing a relatively innocent line like a print statement causes undefined behaviour, it's in my experience usually a symptom of memory corruption. The resulting behaviour can vary from no effect to a corrupted variable to a reboot of the system.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.