How to pass an argument to a function (subroutine) and return an array

Hello Again,

I need some more help! From excellent advise received, I have a code section that randomly sorts
an array (Fisher–Yates shuffle). I have another section that can randomly pick a color (calls a function and returns an array based on a random number generated within the function). So... from my main
program, I want to pass an argument (my preselected random number) to a function. Based on this value, it returns an
array. Can anyone help. Code below.

Thanks!
Peter

/
*************************************************** 
This program attempts to solve the call a random number and color multiple times problem

****************************************************/

#include "Adafruit_TLC5947.h"

// How many boards do you have chained?
#define NUM_TLC5974 2

#define data   4
#define clock   5
#define latch   6
#define oe  -1  // set to -1 to not use the enable pin (its optional)

Adafruit_TLC5947 tlc = Adafruit_TLC5947(NUM_TLC5974, clock, data, latch);

int i;
int j;
int k;
  
void setup() {
  
  Serial.begin(9600);
  
  Serial.println("TLC5974 test");
  tlc.begin();
  if (oe >= 0) {
    pinMode(oe, OUTPUT);
    digitalWrite(oe, LOW);
  }
}

void loop() {

// Set all pins to off
  for(uint16_t i=0; i<12; i++) {
      tlc.setLED(i,0, 0, 0);
      tlc.write();
  }

  randomSeed(analogRead(A0));// a[] is the random pin selection
  byte a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
  byte n = 12;

  for (int i = n - 1; i > 0; --i) {
    int j = random(0, i + 1); // 0 = j = i
    // exchange a[j] and a[i]
    int t = a[i];
    a[i] = a[j];
    a[j] = t;
  }
  
  randomSeed(analogRead(A0));// b[] is the random color selection. I need to pass this value to the 'pick color function' 
  //Note, for simplicity, I have just three choices
  byte b[] = {0, 1, 2};
  byte n = 3;

  for (int i = n - 1; i > 0; --i) {
    int j = random(0, i + 1); // 0 = j = i
    // exchange a[j] and a[i]
    int t = b[i];
    b[i] = b[j];
    b[j] = t;
  }

//+++++Calls random color subroutine Repeats 3 times++++

for(uint16_t i=0; i<3; i++) {
int data1[3];
pin = a[i];

getRanColor(data1); // Obviously, this function call does not pass the b[0] to the function...
R = data1[0];
G = data1[1];
B = data1[2];
  tlc.setLED(pin,R,G,B);
  tlc.write();
  delay(1000);
  tlc.setLED(pin,0,0,0);
  tlc.write(); 
}
//+++++++++++++++++++++++++
}

// Here's my problem. This subroutine works fine if sel = random(3). However, I want it to choose the 'sel value' based on the random sort of b[i] above; even declaring b[] as a global variable does not help...
// I need to pass the b[i] argument to the subroutine but cannot figure out how to do this (and still return an array from the subroutine to the main program)

int getRanColor(int pdata[]){
int sel;
//sel = random(3);  // This was part of my original function
sel = b[i];	    // I need something like this that can take the b[i] defined above and drive the subroutine. 
		    // Doing some troubleshooting (not shown), I see that the 'passed' b[i] value is always zero
if (sel == 0){
   pdata[0] = 2095;
   pdata[1] = 0;
   pdata[2] = 0;
   }
if (sel == 1){
   pdata[0] = 2220;
   pdata[1] = 300;
   pdata[2] = 0;
   }
if (sel == 2){
   pdata[0] = 1800;
   pdata[1] = 998;
   pdata[2] = 0;
   }
}

One common way is to create the array in the calling function (or globally) and pass a pointer to it into the called function. Typically, you would also pass in its size.

You can just add a second parameter to your getRanColor() function

int getRanColor(int sel, int pdata[]) {
  //int sel;
  //sel = random(3);  // This was part of my original function
  //sel = b[i];      // I need something like this that can take the b[i] defined above and drive the subroutine.
  // Doing some troubleshooting (not shown), I see that the 'passed' b[i] value is always zero
  if (sel == 0) {
    pdata[0] = 2095;
    pdata[1] = 0;
    pdata[2] = 0;
  }
  if (sel == 1) {
    pdata[0] = 2220;
    pdata[1] = 300;
    pdata[2] = 0;
  }
  if (sel == 2) {
    pdata[0] = 1800;
    pdata[1] = 998;
    pdata[2] = 0;
  }
}

and then you call it with b like this:
* *    getRanColor(b[i], data1); // Obviously, this function call does not pass the b[0] to the function...* *

You're probably better of defining an array with the needed values.

// array with predefined RGB values
const int colours[][3] =
{
  {2095, 0, 0},
  {2020, 300, 0},
  {1800, 998, 0},
};


void setup()
{
  Serial.begin(57600);
  while (!Serial);

  for (uint8_t index = 0; index < 3; index++)
  {
    Serial.print("Index = "); Serial.println(index);
    Serial.print("R: "); Serial.println(colours[index][0]);
    Serial.print("G: "); Serial.println(colours[index][1]);
    Serial.print("B: "); Serial.println(colours[index][2]);
  }

  for (uint8_t randomCount = 0; randomCount < 10; randomCount++)
  {
    int index = random(0, 3);

    Serial.print("Random index = "); Serial.println(index);
    Serial.print("R: "); Serial.println(colours[index][0]);
    Serial.print("G: "); Serial.println(colours[index][1]);
    Serial.print("B: "); Serial.println(colours[index][2]);
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

In your code, you could use b[i] as the index

    tlc.setLED(pin, colours[b[i]][0], colours[b[i]][1], colours[b[i]][2]);

No need for your getRanColorfunction.

In the next steps you can move the colours array to PROGMEM so it does not waste RAM memory and you can make use of structs or classes for the colour.

I only have time for the latter ( I always need to study PROGMEM :frowning: )

// define a struct to hold RGB colours
struct COLOUR
{
  int red;
  int green;
  int blue;
};

// array with predefined array colours
const COLOUR colours[] = 
{
  {2095, 0, 0},
  {2020, 300, 0},
  {1800, 998, 0},
};

void setup()
{
  Serial.begin(57600);
  while (!Serial);

  for (uint8_t index = 0; index < 3; index++)
  {
    Serial.print("Index = "); Serial.println(index);
    Serial.print("R: "); Serial.println(colours[index].red);
    Serial.print("G: "); Serial.println(colours[index].green);
    Serial.print("B: "); Serial.println(colours[index].blue);
  }

}

void loop() {
  // put your main code here, to run repeatedly:

}

And in your code

    tlc.setLED(pin, colours[b[i]].red, colours[b[i]].green, colours[b[i]].blue);

Thanks again to the collective genius of you guys out there! I really appreciate your clever solutions!

Thanks Again!!
Peter