Understanding Concepts About Arrays

I have come to learn by experience about using arrays but instead of asking what I can do, I think it more productive to ask what I cannot do and ask for insight about why that is.

In two self-instruction exercises, I sought to use arrays to make my code look tidier and more efficient only to be error-ed by the IDE.

One situation pulses three LEDs, all at different delay times an stored in a 1x3 integer array as a global variable. Using an interrupt, I intended to overwrite the rates using the following:

void chngFlashRate(){
  int timeInterval[] = {400,600,800};
}

The upload executed and ran but upon executing the interrupt, nothing happened. I verified this by printing the output of one of the elements and watching it unchanged. To check, I replaced the code so the interrupt only reassigned a single integer variable and it indeed worked.

What occurred/didn’t occur and why?

In the second use case, I wrote a program cycling LED states and initialized them, as global variables, in a 1x3 array

int ledState_0[3] = {LOW,LOW,LOW};

To write the logic for situational switching, I wrote an “if” conditional statement (and rewrote and rewrote), comparing the different variable states in the array and writing in resultant states.

 if (ledState[] == {LOW, LOW, LOW}){
            ledState_0[] = {LOW, HIGH, LOW};
          }

I was unsure the exact syntax to use so I played around but in no case did it work. But only then did this approach with arrays work:

if (ledState_0[0] == LOW && ledState_0[1] == LOW && ledState_0[2] == LOW){ // ALTERNATE: if (pbState_1 == HIGH && pbState_0 == LOW){
          ledState_0[0] = HIGH; ledState_0[1] = LOW; ledState_0[2] = LOW;
          digitalWrite(ledPin[0],ledState_0[0]); digitalWrite(ledPin[1],ledState_0[1]); digitalWrite(ledPin[2],ledState_0[2]);

So clearly I have a knowledge gap in how arrays do and do not work and would appreciate a clarification of my understanding. Can this approach still be used?

We would have to see the entire code, snippets are useless. Almost invariably, the error lies NOT in the code posted, but somewhere else.

void chngFlashRate(){
  int timeInterval[] = {400,600,800};
}

This function declares and defines the values for an array named timeInterval but that array is local to the function and the values that it contains are not accessible outside the scope of that function

If you have a global array with the same name it will be unaffected by the declaration in the function as it has different scope.

As you have discovered, you can set the value of an element of an array within a function if the array is accessible in the scope of the function, which it will be if the array is declared as a global

Incidentally, there is nothing special about arrays in this context. If you declare a variable of any type within a function then its scope will only be that function

I’m confused. You found that this worked, then you ask if it can “still be used”. Yes, because the syntax is now correct. Clumsy, likely because it’s just a construct meant to educate yourself about the state of affairs, but correct.

Now, tell us what it really is you want to do, and perhaps a ‘less clumsy’ construct can be outlined, along with reasons…

if (ledState[] == {LOW, LOW, LOW})

This makes no sense. You cannot test the value of all of the elements of an array in a single statement like this, only element by element as you have discovered

Good point - in this case, the error IS in the code posted, but we still don’t have context for it’s use.

Thanks. This was concept of what I posted is what I was trying to achieve. And is apparently not possible, as you have stated. Seems frustrating because what if the user implemented a larger array and wanted to compare. A hypothetical application.

/*
Program cycles through three LEDs with a single pushbutton. The fundamental portion is the 
state detection logic ("If <<state change>> then enter condion"). Version 2 uses the conditionals
found in the "if" statements to evaluate the iterations feature to iterate through states.
*/


unsigned int time_0 = millis();
unsigned int time_db = 50;
const int ledPin[3] = {6,5,3};
const int pbIn = 2;
int pbState_0 = LOW;

int ledState_0[3] = {LOW,LOW,LOW};

void setup() {
  Serial.begin(9600);
  for (int i = 0; i <= 2; i++){
    pinMode(ledPin[i],OUTPUT);
  }
  pinMode(pbIn,INPUT);
}

void loop() {
  unsigned int time_1 = millis();
  if (time_1 - time_0 > time_db){

    int pbState_1 = digitalRead(pbIn);
   // Serial.print(pbState_0);Serial.print("  ");Serial.print(pbState_1);
    //Serial.println(ledState_0[]);

    if (pbState_1 != pbState_0){
      if (pbState_1 == HIGH){  
        //time_0 = time_1;
        
        if (ledState_0[0] == LOW && ledState_0[1] == LOW && ledState_0[2] == LOW){ // ALTERNATE: if (pbState_1 == HIGH && pbState_0 == LOW){
          ledState_0[0] = HIGH; ledState_0[1] = LOW; ledState_0[2] = LOW;
          digitalWrite(ledPin[0],ledState_0[0]); digitalWrite(ledPin[1],ledState_0[1]); digitalWrite(ledPin[2],ledState_0[2]);

          /*
          if (ledState[] == {LOW, LOW, LOW}){
            ledState_0[] = {LOW, HIGH, LOW};
          }

          */

        }
        else if (ledState_0[0] == HIGH){
          ledState_0[0] = LOW; ledState_0[1] = HIGH; ledState_0[2] = LOW;
          digitalWrite(ledPin[0],ledState_0[0]); digitalWrite(ledPin[1],ledState_0[1]); digitalWrite(ledPin[2],ledState_0[2]);

        }
        else if (ledState_0[1] == HIGH){
          ledState_0[0] = LOW; ledState_0[1] = LOW; ledState_0[2] = HIGH;
          digitalWrite(ledPin[0],ledState_0[0]); digitalWrite(ledPin[1],ledState_0[1]); digitalWrite(ledPin[2],ledState_0[2]);

        }
        else if (ledState_0[2] == HIGH){
          ledState_0[0] = HIGH; ledState_0[1] = LOW; ledState_0[2] = LOW;
          digitalWrite(ledPin[0],ledState_0[0]); digitalWrite(ledPin[1],ledState_0[1]); digitalWrite(ledPin[2],ledState_0[2]);

        }
      }
      pbState_0 = pbState_1;
    }

   }
}
  


Sorry, I was looking for the context of the single-line function you posted, higher in your OP.

To check whether I constructed the interrupt properly, I created a global variable on line 5 of the code (pasted in response to another responder, called “test2Chg”.

I modified the interrupt to change the value from 5 to 2.

void chngFlashRate(){
  //int timeInterval[] = {400,600,800};
  test2Chg = 2;
}

and observed the output in the SM and it works.

Would the proper approach have been to create a local array within the interrupt and then immediately set it equal to the global array in the following line of the interrupt?

would the volatile qualifier been of use here?

See if this provides some illumination:

Your description as to the operations of your three LEDs are not clear to me.

Say, you have three (LED1, LED2, LED3) LEDs.

What are the meanings of pulsing these LEDs? Do you want to blink them one-after-another? If yes, then what are the On-Off times of LED1, LED2, and LED3? What are the seperation delay times (rigger times) between LED1 and LED2; LED2 and LED3; LED3 and LED1?

What have you wanted to mean by "overwrite the rates"?

Are you using UNOR3? Do you want to inject an external interrupting signal to the MCU to change the seperation delay times or the On-Off times of the LEDs?

If you provide the above information, I may try to devise array structures for the solution of your project.

Please, post the codes that you have tried.

Then I would use a for loop to iterate through the array rather than multiple if statements

How would you do that ? You cannot simply say oldArray[] = newArray[]

I have a much broader question. That is, why are you using an interrupt ?

Consider; two arrays, identical length; you know the length:

int i;
for (int i = 0; i < length; i++) if (array1[i] != array2[i]) break;
if (i == length) {} //identical.
else {} //different - i was left pointing to the first element that isn't the same

{warning - untested}

This is just all part of an exercise to learn more about using interrupts. I just wanted to explore using arrays in my code more. When you say you cannot simply reassign arrays, could you expound? I guess the problem i had is I found the Arduino array documentation lacking in explaining some of these types of things. It would seem the ability to reassign arrays, similar to how you could in MathCad (really the only other coding I worked in) would be powerful but I understand I am dealing with two very different enviroments.

Interesting, I’ll look more at this

You cannot do

oldArray[] = newArray[];

You could do

int arrayLen = sizeof(oldArray) / sizeof(oldArray[0);  //calculate how many elements in the array

for (int i = 0; i < arrayLen; i++)
{
  oldArray[i] = newArray[i];
}


Note that both arrays must have the same number of elements

You could also use the memcpy() function like this (untested)

byte oldArray[] = { 1, 2, 3 };
byte newArray[] = { 4, 5, 6 };
byte arraySize = sizeof(oldArray) / sizeof(oldArray[0]);

void setup()
{
    Serial.begin(115200);
    printArray(oldArray, "oldArray");
    printArray(newArray, "original newArray");
    memcpy(oldArray, newArray, arraySize);	//copy newArray to oldArray
    printArray(oldArray, "new oldArray");
}

void loop()
{
}

void printArray(byte* array, char* name)
{
    Serial.println(name);
    for (int i = 0; i < arraySize; i++)
    {
        Serial.println(array[i]);
    }
    Serial.println();
}

How complicated do you want to make this ?

That would work, but only because the array is of type byte. If it was int...

Better to use

memcpy(oldArray, newArray, sizeof(oldArray));

@PaulRB Thanks for spotting that

Save this link:

Nick’s writings about most things Microprocessor-related are absolutely the place to start.