Pass 2D array to function

Hello,

I am converting some working code for a PIC microcontroller to an Arduino.

I have an array defined as such:

char motor_speed[6][5]={"500", "1000", "1500", "2000", "2500", "3000"};

I call the function like this:

get_item( &speed_code, &motor_speed, "-Enter Motor Speed-", "RPM", 6, 5 );

The function is defined like this, and I can step through the values.

int get_item( byte *code, char *list, char *heading, char *units, byte count, int length )

list += length ;

The compiler is giving me an error:

error: cannot convert 'char ()[6][5]' to 'char' for argument '2' to 'int get_item(byte*, char*, char*, char*, byte, int)'

How do I pass arrays? The code needs to be generic, One array may be [6][5], another [3][8].

Thank you,

The code needs to be generic, One array may be [6][5], another [3][8].

You will need to pass sizes in, too, then.

Values are passed to functions in two ways - pass by value and pass be reference. Pass by value is the default for simple types - ints, floats, etc. Pass by reference is the default for complex types such as arrays. Basically, a pointer to the first byte of memory that the array is stored in is passed to the function. The additional information in the function's argument description defines how the data is indexed.

If the argument is defined as int *arr[3], the compiler knows how to locate arr[0][0], arr[0][3], arr[n][0], and arr[n][3]. This works fine for fixed size arrays.

When you want to pass generic arrays to a function, you have to use int **arr, and write your own indexing functions, as the compiler no longer knows how many rows and columns there are in the array, so it can't locate any specific element.

In your example, you have defined that the argument is a one dimensional array, but you are trying to pass it a 2 dimensional array.

As defined now, the character array does not contain strings (NULL-terminated arrays of characters). Is this intentional?

Why are you passing character representations of values to the function, instead of values? What does the function do with the array?

I am trying to write a menuing system for a character lcd.

In the example, the array was numbers, but it could have been “Slow”,“Medium”,“Fast”.

The function updates the speed_code variable based on which item is selected, i.e. 0 - 5.

list+=length; should move the list pointer to the start of the next value.

Here’s a little test program that would work in the CCS C compiler for PIC, but the Arduino compiler doesn’t like it:

error: cannot convert ‘char ()[5]’ to 'char’ for argument ‘1’ to ‘void print_strings(char*, byte, byte)’

char arr1[3][5]={"Slow", "Med", "Fast"};
char arr2[4][6]={"Left", "Right", "Up", "Down"};

void print_strings ( char *list, byte count, byte length ){
  
  for ( int i=0; i < count; i++ ){
    Serial.println ( list );
    list += length;
  }
}

void setup() {}

void loop() 
{
  print_strings( &arr1, 3, 5 );
  print_strings( &arr2, 4, 6 );
   while (1)  
   {
   }// end while(1)
}

How would I get this to compile and print:

Slow
Med
Fast
Left
Right
Up
Down

This compiles:

char arr1[3][5]={"Slow", "Med", "Fast"};
char arr2[4][6]={"Left", "Right", "Up", "Down"};

void print_strings ( char **list, byte count, byte length ){
  
  for ( int i=0; i < count; i++ ){
    Serial.println ( list[i] );
    list += length;
  }
}

void setup()
{
  Serial.begin(9600);
  
  char *row = arr1[0];
  print_strings( &row, 3, 5 );
  row = arr2[0];
  print_strings( &row, 4, 6 );
}

void loop() 
{
}

I use dual monitors at work. The Serial Monitor remembers where it was last opened and opens there (on the non-connected monitor). The option to move it does not exist, so I can’t really see what it prints.

The first value of each array are printing correctly, but the next values are not.

I tried commenting out the list += length; command since it seems that you are now able to reference each value with i, but that didn't work.

Thank you for your help.

For a character string I’d use the type char *, thus:

char * arr1[3] = {"Slow", "Med", "Fast"};
char * arr2[4] = {"Left", "Right", "Up", "Down"};

void print_strings ( char *list[], byte count){
  
  for ( int i=0; i < count; i++ ){
    Serial.println ( list[i] );
  }
}

void setup()
{
  Serial.begin(57600);
  
  print_strings( arr1, 3);
  print_strings( arr2, 4);
}

void loop() 
{
}

(fixed the bizarre thing with row, and removed the spurious list+=length)

You are passing a collection of (what look like) strings to the function. Why not do it right?

char *arr1[] = {"High", "Medium", "Low"};
char *arr2[] = {"Left", "Right", "Up", "Down"};

void printMe(char *array[], byte size)
{
   for(byte b=0; b<size; b++)
   {
     Serial.print(array[b]);
   }
}

void setup()
{
   Serial.begin(9600);
   printMe(arr1, sizeof(arr1)/sizeof(arr1[0]));
   printMe(arr2, sizeof(arr2)/sizeof(arr2[0]));
}

void loop()
{
}