Using String variable to represent Array

Hello. So I am trying to create a home project light show, but I want the light sequence to be "random" I have created multiple arrays with difference sequences, along with an array of each array name. I have a random number generator that is used to reference a random array name and use it to randomize my program. the variable "sequence" is where the random array name ends up, as proven by the serial monitor....but using it in my function call, it refuses to work. can anybody explain what I have wrong? TIA


//FUNCTION PROTOTYPE
void LightOn (int, int);
void LightOff (int, int);

//Array names Array
String ArrayNames[] =
{
  "Left2Right", "Right2Left", "LeftOut2In",
  "RightOut2In", "In2Out1", "In2Out2"
};

//ARRAY DESIGN
int Left2Right[] =  //Array #1
{
  2, 3, 4, 5, 6, 7, 8, 9
};

int Right2Left[] =   //Array #2
{
  9, 8, 7, 6, 5, 4 , 3, 2
};

int LeftOut2In1[] =   //Array #3
{
  2, 9, 3, 8, 4, 7, 5, 6
};

int RightOut2In[] =   //Array #4
{
  9, 2, 8, 3, 7, 4, 6, 5
};

int In2Out1[] =    //Array #5
{
  5, 6, 4, 7, 3, 8, 2, 9
};

int In2Out2[] =    //Array #6
{
  6, 5, 7, 4, 8, 3, 9, 2
};

void setup()
{
  int i;
  int pinMin = 2;
  int pinMax = 9;
  for (i = pinMin ; i <= pinMax ; i++)
  {
    pinMode(i, OUTPUT);
  }
}

void loop()
{
  int i;
  String sequence;
  int randomSeq;  //(start , total-1)
  int randomTime; //20-500 mS

  Serial.begin(9600);
  randomSeq = random(6);
  randomTime = random(501);
  sequence = ArrayNames[randomSeq];
  Serial.println(sequence);

  for (i = 0 ; i <= 7 ; i++)
  {
    LightOn(sequence[i], randomTime);
  }

  randomTime = random(20, 501);
  for (i = 0 ; i <= 7 ; i++)
  {
    LightOff(sequence[i], randomTime);
  }
}

void LightOn (int i, int randomTime)
{
  digitalWrite(i, LOW);
  delay(randomTime);
}

void LightOff(int i, int randomTime)
{
  digitalWrite(i, HIGH);
  delay(randomTime);
}

could you edit your post and put the code in between code tags plz?

Sorry about that. new here. :slight_smile:

The short answer is you've used the wrong programming language. :wink:

With C/C++…

By the time your code is being uploaded, it is compiled and the names you have carefully chosen are not known to the program.

The way around this is to give your sequences numbers by which they can be referred to.

Here a two dimensional array might be the easiest thing for you to figure out given what your code is now.

I'm not at the big rig. Google

two dimensional array C

while waiting for someone who might provide more immediate help.

But good conceptual thinking… at a glance, it should work, and there are languages where that kind of thing would.

Just not C.

a7

You can store pointers to your arrays in your arraynames and then just chose pointer at random. it will allow you to access content of that array

1 Like

....I really do hate pointers. I'm so bad with them....I try to avoid them

@killzone_kid is correct, and in this particular case you'll be surprised to see how easy it is.

So your pick, 2D arrays or pointers. Either will advance your essential knowledge and experience, hard to say which would be better learnt first.

But please don't avoid pointers dgomatically, they just a bit hard until they are easy, or easier, and are widely used, so at the very least you should have a reading knowledge of them.

a7

If I type the name of one of my random array's I've created, the program works as intended. and when I use the serial monitor, I can see the names of each array randomly. I don't understand why using "sequence", which has my random data ()verified by serial monitor), does not work...but typing it in directly does......it bothers me. lol

@killzone_kid Thanks for the help. Looks like I'm in for an evening of learning how to use pointers.....

OK, there's a few problems with your original code.

Move Serial.begin(9600) into you setup() function where it belongs.

Even if your idea was gonna work, you mistyped an array name in one of two places, viz:

LeftOut2In1

and

  randomTime = random(501);

isn't like the other, so sometimes things really would zip… clealry you meant random(20, 501).

Other than that, using pointers was easy enough. Normally I'd let you have all the fun, so promise me you'll take a close look at this

while you hit the books on pointers. :expressionless:

Oh, also you wired your LEDs backwards. :wink:

Note: Wokwi lets you use LEDs without resistors, don't do that at home.

There's a reason that the bible The C Programming Language has

Chapter 5: Pointers and Arrays

In C and C++ pointers and arrays have an intimate relationship, it makes sense to advance your knowledge of them together, you may see.

HTH

a7

1 Like

if you care about the name of the animation, you could keep it with the array (and the size of the array) in a structure. Then you make an array of structure and pick randomly an entry in that array

here is an example (typed here, not tested) that would print a random animation every 3s (Serial Monitor @ 115200 bauds)

byte Left2Right[]  = {2, 3, 4, 5, 6, 7, 8, 9};
byte Right2Left[]  = {9, 8, 7, 6, 5, 4, 3, 2};
byte LeftOut2In1[] = {2, 9, 3, 8, 4, 7, 5, 6};
byte RightOut2In[] = {9, 2, 8, 3, 7, 4, 6, 5};
byte In2Out1[]     = {5, 6, 4, 7, 3, 8, 2, 9};
byte In2Out2[]     = {6, 5, 7, 4, 8, 3, 9, 2};

struct t_animation {
  const char* name;
  byte  length;
  byte* list;
};

t_animation animationList[] = {
  {"Left2Right ",  sizeof Left2Right,  Left2Right},
  {"Right2Left ",  sizeof Right2Left,  Right2Left},
  {"LeftOut2In1", sizeof LeftOut2In1, LeftOut2In1},
  {"RightOut2In", sizeof RightOut2In, RightOut2In},
  {"In2Out1    ", sizeof In2Out1,     In2Out1},
  {"In2Out2    ", sizeof In2Out2,     In2Out2},
};
const byte animationCount = sizeof animationList / sizeof animationList[0];

void playAnimation(byte index) {
  Serial.print(F("Playing animation: ")); Serial.print(animationList[index].name);
  Serial.print(F("\t"));
  for (byte i = 0; i < animationList[index].length; i++) {
    Serial.print(animationList[index].list[i]); Serial.write(' ');
  }
  Serial.println();
}

void setup() {
  Serial.begin(115200); Serial.println();
}

void loop() {
  byte randomAnimationIndex = random(0, animationCount); // pick one of the animations
  playAnimation(randomAnimationIndex);
  delay(3000);
}

@J-M-L # 11 code tested in 108 seconds using wokwi.com seems to work fine.

a7

@alto777 Thank you so MUCH!!! The pointers thing wasn't going well for me. The typos weren't going to help either (I would have caught those eventually) The serial.begin I just threw in to troubleshoot....didn't consider where I put it, but it makes sense it shouldn't be in the loop. I'm not connecting this to LED's, I'm using this to control a relay board (active low relays) to control power to a bunch of wall outlets.