computations with local variables not allowed?

Hi,
there is a function getServerData(), defined in a cpp-file.

byte getServerData(word rvon, byte anz, word* wmean, word* wmin, word* wmax, byte* morePeaks) {
  /* computes the mean of a sequence of data in warray[] which is a global array.
      warray[] is a ring buffer with length BUFFLEN. rbuf_idx is the index containing the latest value.
      rvon is the start index of the sequence relative to rbuf_idx.
      anz is the length of the sequence.
      the function performs some more computations which are not relevant here.   */

  int j, i;

  rvon=rbuf_idx-rvon+1;
  if (rvon>BUFFLEN) rvon += BUFFLEN;  // jetzt ist rvon der Startindex (geht auch mit word)
  *wmean=*wmin=*wmax=warray[rvon];
  j=rvon;
 
  for (i=1; i<anz; i++) {
    j++;
    if (j>BUFFLEN-1) j=0; // Ueberlauf
    *wmean += warray[j];
  }
  
  *wmean = (*wmean+(anz>>1))/anz;
...

This function once is called from a sketch, which works fine:

// global declarations for the sketch:
word wmean, wmin, wmax;
byte wdir, npeaks;
...
loop() {
...
wdir = getServerData(257, 19, &wmean, &wmin, &wmax, &npeaks);
...
}

The function also is called from within another function which fails:

void SdPlayClass::talkSequence(void) {
	word wspeed, wsmin, wsmax,
	byte  wd, npeaks;
	
  wd = getServerData(13, 13, &wspeed, &wsmin, &wsmax, &npeaks);
...
}

Shifting the local variables within void SdPlayClass::talkSequence(void) outside the function as global variables of the module works fine again:

word wspeed, wsmin, wsmax,
byte  wd, npeaks;
...
void SdPlayClass::talkSequence(void) {
	
  wd = getServerData(13, 13, &wspeed, &wsmin, &wsmax, &npeaks);
...
}

I don't understand why talkSequence() is delivering a totally wrong value for wspeed (and the other variables too) when the data transferred to the function are declared as local variables.

Can somebody explain it to me?

SupArdu

The compiler will 'automagically' generate code that initialises global and static variables; it will not do so for local variables.

In the one where they are local you give them no value. What value do you expect those variables to have?

The function getServerData() fetches data from the circular buffer and fills them into the variables. Therefore pointers of the variables are handed over to the function as arguments.

At different locations in my application some data from the circular buffer are needed. The function getServerData() is called at those locations and shall provide the data. When the variables are defined globally then the correct data are loaded to them. But when the variables are defined locally in a further function then wrong data are loaded to them.

I inserted print() statements to find out where the error happens. The code of getServerData() now looks like this:

byte getServerData(word rvon, byte anz, word* wmean, word* wmin, word* wmax, byte* morePeaks) {
  /* computes the mean of a sequence of data in warray[] which is a global array.
      warray[] is a ring buffer with length BUFFLEN. rbuf_idx is the index containing the latest value.
      rvon is the start index of the sequence relative to rbuf_idx.
      anz is the length of the sequence.
      the function performs some more computations which are not relevant here.   */

  int j, i;

Serial.print(F("Aufrufparameter: "));Serial.print(rvon);Serial.print(" ");Serial.println(anz);

  rvon=rbuf_idx-rvon+1;
  if (rvon>BUFFLEN) rvon += BUFFLEN;  // jetzt ist rvon der Startindex (geht auch mit word)
  *wmean=*wmin=*wmax=warray[rvon];
  j=rvon;

Serial.print(F("Berechnung ab "));Serial.print(j);Serial.print(F(": ")); Serial.print(*wmean);Serial.print(F("+"));
 
  for (i=1; i<anz; i++) {
    j++;
    if (j>BUFFLEN-1) j=0; // Ueberlauf
    *wmean += warray[j];

Serial.print(warray[j]);Serial.print(F("="));Serial.print(*wmean);Serial.print(F("+"));

  }
 
  *wmean = (*wmean+(anz>>1))/anz;
...

The first line of Serial.print()s shows the first two arguments of the function. They are correct.
The second line of Serial.print()s shows the initial value for wmean. Here the error occurs.The value is much too large (about 49000 instead of 100).
The third line of Serial.print()s shows how the content of wmean is rising up. This is correct too.

For me it is a mystery :confused:

Without the entire sketch I doubt there's going to be any progress. Little snippets are not
the whole story and bugs are seldom where you think they are in the code otherwise you'd
have found them!