array of variable names, is it possible

I'm trying to create an array of variable names, but I'm not sure which data type to use. Would this work?

int led00 = 50;
int led01 = 51;
int led02 = 52;

string ledArray[3] = {led00, led01, led02};

I've used "int" arrays successfully, but I'm not sure about arrays of variable names.

Yes, it is possible, but I think not what you want to do.

char* ledNames [] = {"led00", "led01", "led02"}

tell us what you want to do. (I suspect you want to know about pointers)

I'm working on a script that will drive led's and references to potentiometers and switches based on an interrupt. It's for a voltage controlled synth sequencer.

My idea is each time an interrupt is triggered the sequencer will move forward a step. The script above is for the led's only, but it is the same idea for the pots and switches.

So, basically, each time an interrupt is received I want the array to go from ledArray[0] to ledArray[1] to ledArray[2], etc. However, incrementing the array doesn't seem to be the problem. What data type to store the led variables is.

I know char is a single character, but the char* is confusing. How does it work? Also, why didn't you declare a number in the array brackets.

Making an array of ints that contain the pin numbers would be the best.

Something like:

int RedLED = 2, BlueLED = 4, GreenLED = 6;
int ledArray[] = { RedLED, BlueLED, GreenLED };

Example for loop:
for (int i=0; i < 3; i++)
digitalWrite(ledArray*, HIGH);*
In C/C++ a char* is a string. The * means it is a pointer and points to the memory address of the first char of the string.
As for the empty square brackets, if you are setting the values then the compiler is smart enough to insert the correct number inside at compile time.

Variable names only exist in the program source in C/C++, they have no meaning at runtime so the short answer is no.

However that's a subtle point, what you practically need to know is that you need to work with the addresses of variables, and learn about the & "address of" operator.

int led00 = 50;
int led01 = 51;
int led02 = 52;

int * ledArray[3] = {&led00, &led01, &led02};

"int *" is the type of a pointer-to-integer, here I create an array of three pointers. Using the pointers I can access the variables (read or write) using the * operator.

I think the "& addresses of" operator is just what I needed. I'll test the script later. Thanks.

I tried using the addresses of operator, but I'm getting the error in funtion void() "error: invalid conversion from 'int*' to 'uint8_t'"

Here's the whole script:

/* Big fat D rev. 4 */

int gateDataPin = 13;

//dac pins
int clockPin = 22;
int cvDataPin = 23;
int latchPin = 24;

//LED pins
int ledPin00 = 50;
int ledPin01 = 51;
int ledPin02 = 52;
int ledPin03 = 53;

//cv pitch knobs
int cvPot00 = 0;
int cvPot01 = 1;
int cvPot02 = 2;
int cvPot03 = 3;

int cvData;
int stepNum = 0;
int* currentLed[4] = {&ledPin00, &ledPin01, &ledPin02, &ledPin03};
int currentStep[4] = {cvPot00, cvPot01, cvPot02, cvPot03};

volatile int state = LOW;

void setup()
  {
    pinMode (gateDataPin, OUTPUT);
    pinMode (clockPin, OUTPUT);
    pinMode (cvDataPin, OUTPUT);
    pinMode (latchPin, OUTPUT);
    pinMode (ledPin00, OUTPUT);
    pinMode (ledPin01, OUTPUT);
    pinMode (ledPin02, OUTPUT);
    pinMode (ledPin03, OUTPUT);
  
    attachInterrupt (2, voltIn, CHANGE);
  }
 
void loop()
  {
    if (state == HIGH)
      {
        analogWrite (gateDataPin, HIGH);
        digitalWrite (currentLed[stepNum], HIGH);
      }
    else
      {
        analogWrite (gateDataPin, LOW);
        digitalWrite (currentLed[stepNum], LOW);
      }
      
    cvData = analogRead(currentStep[stepNum]);
  
    digitalWrite (latchPin, LOW);
    shiftOut (cvDataPin, clockPin, MSBFIRST, cvData);
    digitalWrite (latchPin, HIGH);
  }
 
void voltIn ()
  {
    state = !state;
    stepPos();
  }
 
void stepPos()
    { 
      stepNum++;
      
      if (stepNum == 3)
        {
          stepNum = 0;
        }
    }
int* currentLed[4] = {&ledPin00, &ledPin01, &ledPin02, &ledPin03};
 digitalWrite (currentLed[stepNum], HIGH);

"currentLed [n]" is a pointer to an "int", but "digitalWrite" expects a "uint_8" as a first parameter.

Try "digitalWrite ((uint_8)*currentLed[stepNum], HIGH);"

This will dereference the pointer, and cast the result to the correct type.

Hint: When you get a problem like this, try cutting down your sketch to the bare minimum that still exhibits the problem before posting.

Much simpler would have been:

uint_8 currentLed[4] = {ledPin00, ledPin01, ledPin02, ledPin03};

 digitalWrite (currentLed[stepNum], HIGH);

Your code works, but it's inefficient.

What you are doing is creating a series of two byte variables in memory, and loading them with a constant number (50, 51, 52).

Then you create an array of addresses, each entry of which takes two bytes, to hold the address of the two byte variables you created first.

Your code then steps through the array, extracts the address of the two byte variable, goes there, and gets the constant, which is the pin number.

pceric gave you the right answer. Just make an array of pin numbers. Then your loop just steps through the array picking up the pin number directly.

Your way takes twice as much memory, and takes some percentage, maybe 30% longer to execute, and you get nothing for it.

Learning to use pointers is valuable, but don't use pointers when the variable the pointer points to is always constant and all you ever do is run through the list in order extracting the value.

I got the code working last night how I wanted it. I ended using

ledArray[4] = {ledPin00, ledPin01, ledPin02, ledPin03};

The stepPos() function, as I suspected, was where it was going wrong. By referencing the state of the "state" variable in that function, I was able to fix the problem.

brtech, are you saying I should skip defining the ledPins and just make an array of pin numers like this?

ledArray[4] = {50,51,52,53};

Or were you referencing the "address of" method?

Thanks for all the help!

are you saying I should skip defining the ledPins and just make an array of pin numers like this?

ledArray[4] = {50,51,52,53};

brtech isn't on line, so I'll stick my neck out, and say YES.

Or were you referencing the "address of" method?

brtech was probably talking about address of too. It isn't needed.

Less code, and maybe simpler?

For example:

const byte ledArray[4] = {50,51,52,53};

void setup() {
  for (int i=0; i<sizeof(ledArray); i++) {
    pinMode (ledArray[i], OUTPUT);
  }
}

It is easy to add more LEDs by adding pins into ledArray

HTH
GB

The code "i<sizeof(ledArray)" is fragile.
It relies on the fact that byte is the type of ledArray, and also the unit sizeof() uses.

It would break, and return a number which is too big for every type of variable that are bigger than a byte. If you like, it only works by luck.

This would likely drive everyone who tries to use this nuts.

It would be more robust to say something like, e.g.

const int ledArraySize = sizeof(ledArray)/sizeof(ledArray[0]);

so sizeof(ledArray) is the size (in bytes) of the whole array, and
sizeof(ledArray[0]) is the size (in bytes) of one element of the array (the first)

This has the good property that it always gives the number of elements in the array, no matter what type, even if each element is a struct.

and then:

void setup() {
  for (int i=0; i<ledArraySize; i++) {
    pinMode (ledArray[1], OUTPUT);
  }
}

Which won't break if the ledArray[] becomes an array of int.

Warning - I've Verify'ed but not run this code.

HTH
GB