Loop not incrementing INT

This is one of the most bizarre things I've ever seen, how and why is a INT being reset back to zero by the thing that’s using it ?

Declared at the top of the page

const uint8_t  PIX_COUNT = 5;
const uint8_t FRAMES = PIX_COUNT;
const uint8_t CHANNELS = PIX_COUNT * 3;
uint8_t FX[FRAMES][CHANNELS]; 
uint32_t FX_F = 0;

This will work

void loop() {

  for (int f = 0; f < FRAMES; f++) {// loops through creating each frame
    for (int c = 0; c < CHANNELS; c++) { // loop through creating each channel
      uniData[c] = FX[f][c];
    }
    Serial.println(FX_F);
    delay(100)

}

This will not, FX_F is always zero

void loop() {
for (int c = 0; c < CHANNELS; c++) { // loop through creating each channel
    uniData[c] = FX[FX_F][c];
  }
  delay(100);
  FX_F++;
  if (FX_F == FRAMES) {
    FX_F = 0;
  }
  Serial.println(FX_F);

}

I have determined that uniData

 = FX[FX_F][c]; is resetting the FX_F back to zero?


How, that makes not seance at all?

thanks

Brian

What you have posted is not a complete sketch: setup() is missing.

Please post your entire sketch. It is likely that the problem is caused by something you have not yet shown us. We can't fix what we can't see.

I'm confused. In spite of there being no declaration of uniData[] (probably in the code not posted, see #1], how can you say that the first code segment works when FX_F never gets incremented thus always prints out 0?

In contrast, your second segment cycles through, increments FX_F and resets at 5 - prints 0, 1, 2, 3, 4, 0 ...

Both code segments tested.

It sounds to me like something is writing outside the bounds of an array

I found it

I had declared the uniData[] as uniData[FRAMES] instead of uniData[CHANNELS].

UKHeliBob:
It sounds to me like something is writing outside the bounds of an array

Yes you were right. I'm just not use to a coding environment where instead of reporting something like "List array out of bound" it will just do something random that keeps you chasing your tail looking in the wrong place !

I just don't like the way C handles (and I use that term loosely) arrays. You can't get a size of an array, (myarray.TheSize), you can't have dynamic arrays, you can't just assign one array to another MyArray[] = AnotherArray[1][], all things I have used in coding for years, with this you end up with a lot of loops doing things :slight_smile:

This was the full test code, I wanted to test the theory before adding it to main code

Thanks for you help guys :slight_smile:

/* ***********************************
         GOLBAL VARS
 ************************************/

const uint8_t  PIX_COUNT = 10;

/////////////   FX VARS   ////////////////

const uint8_t FRAMES = PIX_COUNT;
const uint8_t CHANNELS = PIX_COUNT * 3;
uint8_t FX[FRAMES][CHANNELS]; //  FX[NumOfFrames][NumOfChannels]
uint8_t FXf; // used to track FX frames in main loop
uint16_t FX_Delay = 0, FX_Delay_Millis;  // used in main loop to run FX Speed

/////////////////////////////////////////

uint8_t uniData[CHANNELS];
uint16_t uniSize;

/////////////////////////////////////////

void FX_Clear() {
  for (int f = 0; f < FRAMES; f ++) {
    uniData[f] = 0;
  }
  FXf = 0;
}


/////////////////////////////////////////
// just add some test data to the FX Array

void testData() { 
  for (int f = 0; f < FRAMES; f ++) {// number of frames
    for (int c = 0; c < CHANNELS; c ++) {// number of channels
      FX[f][c] = (f + c);
    }
  }
}

/////////////////////////////////////////

void setup() {
  Serial.setDebugOutput(true);
  Serial.begin(115200);
  delay(500);
  
  FXf = 0;
  testData();
  FX_Delay = 100;
  FX_Delay_Millis = millis();

}
/////////////////////////////////////////

void loop() {
  // FX Delay Timmer
  if (millis() - FX_Delay_Millis >= FX_Delay) {
    for (int c = 0; c < CHANNELS; c++) { // loop through creating each channel
      uniData[c] = FX[ FXf ][ c ];
      Serial.printf("uniData[c] = %d", uniData[c]);Serial.println();
    }
    // add code to send out to WS
    FX_Delay_Millis = millis();
    if (FXf++==FRAMES) {FXf = 0;}
    Serial.printf("FXf = %d", FXf);Serial.println();
    Serial.println("==========================");
  }

}

I'm just not use to a coding environment where instead of reporting something like "List array out of bound" it will just do something random that keeps you chasing your tail looking in the wrong place !

Whilst it will not prevent you writing outside of the array bounds I believe that you can turn on a warning to that effect if you want but you have to take note of it yourself

You can't get a size of an array

Oh yes you can

int arraySize = sizeof(theArray);  //the number of bytes used by the array
int arrayElements = sizeof(theArray) / sizeof(theArray[0]);  //the number of elements in the array

you can't just assign one array to another MyArray[] = AnotherArray[1][],

You can by using memcpy()

From the beginning, C was designed to be small and efficient. As with everything, there are tradeoffs. One price of that efficiency is limited run-time error checking.

All of the features and structures that you're lamenting the absence of can be implemented with C++ classes.

Hi Guys

Thanks for all your replies, this is all a new learning curve to me 

UKHeliBob:

int arraySize = sizeof(theArray);  //the number of bytes used by the array

int arrayElements = sizeof(theArray) / sizeof(theArray[0]);  //the number of elements in the array

Very good to know, thanks for this. I do have a question, is this the size of the full array populated or not, or the size of a populated array?
By this I mean is I have MyArray[10], and I add content to 0-4, would the sizeof report 10 or 5?

I have discovered that you can not have a undefined array size (MyArray[]), as such you will also know the size of the array, so although good to know, unless if reports the size of the populated array I can't see why I would ever use this (yes I know I'll eat my own words soon)

UKHeliBob:
You can by using memcpy()

Now this I like (I eat my words)

So is this.....

memcpy(uniData, FX[ FXf ], sizeof uniData);

Quicker and better than using this?

for (int c = 0; c < CHANNELS; c++) { // loop through creating each channel
  uniData[c] = FX[ FXf ][ c ];
 }

[/quote]

gfvalvo:
From the beginning, C was designed to be small and efficient. As with everything, there are tradeoffs. One price of that efficiency is limited run-time error checking.

All of the features and structures that you're lamenting the absence of can be implemented with C++ classes.

Starting to find more and more of this, I have chased my tail on a number of things, arrays especially, also not use to having programming with a continuous loop running

is this the size of the full array populated or not, or the size of a populated array?

That's like asking "is this the length of the street I live on or the length of the street that goes by houses that have people living in them"?

EVERY element of an array is "populated". Whether it is populated by meaningful data, or not, is for you to determine.

PaulS:
That's like asking "is this the length of the street I live on or the length of the street that goes by houses that have people living in them"?

EVERY element of an array is "populated". Whether it is populated by meaningful data, or not, is for you to determine.

That’s was kinda what I was getting at, as you can't have undefined array lengths, you always know the size of it, so at this point I could never see a reason why I would then what to check how long it is as I always know.

I come from a background where I can create undefined arrays, and just add to them as I need, this is where I would then use array.length to know how many elements I have added to it.

Thanks for you reply Paul :slight_smile: