Arduino Forum

Using Arduino => Programming Questions => Topic started by: 9fingers on Feb 11, 2017, 01:39 pm

Title: I'm stuck trying 2d arrays.
Post by: 9fingers on Feb 11, 2017, 01:39 pm
Code: [Select]
const int numReadings = 10;
const int numPorts = 2;
long numberofReadings=numReadings;
int readings[numReadings][numPorts];      // the readings from the analog input ports
int readIndex[numPorts];// the index of the current reading




I am trying to set up a two dimensional array to store readings from external sensors.
I have made the dimensions of the array numReadings and numPorts constants which will be used throughout the program calculating averages etc. I'm using small number to start with 10 reading and two sensors but this will increase once I have things working.

However my compile is failing at the first step saying:-

"declaration of 'readings' as multidimensional array must have bounds for all dimensions except the first"

which a) I don't understand and b) my code looks to be similar to other code segments in tutorials

Apologies in advance if this is a dumb question but I have tried and can't see my way out of this.

tia
Bob
Title: Re: I'm stuck trying 2d arrays.
Post by: AWOL on Feb 11, 2017, 01:54 pm
Post the code you're having problems with and the error messages you're seeing.
Title: Re: I'm stuck trying 2d arrays.
Post by: 9fingers on Feb 11, 2017, 02:08 pm
Post the code you're having problems with and the error messages you're seeing.
I rather thought I had done as you suggest?

The compiler is highlighting the fourth line down.

I can't see how to copy the actual error message in orange. How is this done?


The full code

is
Code: [Select]
//set up the global variables
const int numReadings = 10;
const int numPorts = 2;
long numberofReadings=numReadings;
int readings[numReadings][numPorts];      // the readings from the analog input ports
int readIndex[numPorts];// the index of the current reading


float total[numPorts];                  // the running totals for each port
float average[numPorts];                // the average for each port


void setup() {
  // initialize serial:
  Serial.begin(9600);
  analogReference(EXTERNAL);
  InitArray(readings,numReadings,numPorts); //call function to pre-fill the arrays
}

void loop() {
  average= GetNewAverage(readings, numReadings,numPorts);
  // send it to the computer as ASCII digits
  Serial.print(average);
  Serial.print("  ");
  delay(1000);        // delay in between reads for stability
  Serial.println("  ");
}
void InitArray(int readings[][],int nubReadings, int numPorts){
  // initialize all the readings to an initial read value from each port
  for (int j=0; j< numPorts; j++){
    int initReading=analogRead(j);
    for (int i = 0; i < numReadings; i++) readings[i][j] = initReading;
    total[j]=numberofReadings*initReading;
    average[j]=initReading;
  }
}
float GetNewAverage(int readings[][], int numReadings, int numPorts){
  for (int j=0;j<numPorts; j++){
    // subtract the last reading:
    total = total - readings[readIndex][j];
    // read from the sensor:
    readings[readIndex][j] = analogRead(j);
    // add the reading to the total:
    total = total + readings[readIndex][j];
    // advance to the next position in the array:
    readIndex = readIndex + 1;
    // if we're at the end of the array...
    if (readIndex >= numReadings) {
      // ...wrap around to the beginning:
      readIndex = 0;
    }
  }
}



and the error messages are:


Func7_2_dimensional_array:7: error: declaration of 'readings' as multidimensional array must have bounds for all dimensions except the first
Func7_2_dimensional_array:8: error: declaration of 'readings' as multidimensional array must have bounds for all dimensions except the first
Func7_2_dimensional_array.ino: In function 'void setup()':
Func7_2_dimensional_array:19: error: invalid conversion from 'int (*)[2]' to 'int'
Func7_2_dimensional_array:7: error: too many arguments to function 'void InitArray(int, int)'
Func7_2_dimensional_array:19: error: at this point in file
Func7_2_dimensional_array.ino: In function 'void loop()':
Func7_2_dimensional_array:23: error: invalid conversion from 'int (*)[2]' to 'int'
Func7_2_dimensional_array:8: error: too many arguments to function 'float GetNewAverage(int, int)'
Func7_2_dimensional_array:23: error: at this point in file
Func7_2_dimensional_array:23: error: incompatible types in assignment of 'float' to 'float [2]'
Func7_2_dimensional_array:25: error: call of overloaded 'print(float [2])' is ambiguous
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:58: note: candidates are: size_t Print::print(char) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:59: note:                 size_t Print::print(unsigned char, int) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:60: note:                 size_t Print::print(int, int) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:61: note:                 size_t Print::print(unsigned int, int) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:62: note:                 size_t Print::print(long int, int) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:63: note:                 size_t Print::print(long unsigned int, int) <near match>
Func7_2_dimensional_array.ino: At global scope:
Func7_2_dimensional_array:30: error: declaration of 'readings' as multidimensional array must have bounds for all dimensions except the first
Func7_2_dimensional_array:39: error: declaration of 'readings' as multidimensional array must have bounds for all dimensions except the first
Func7_2_dimensional_array.ino: In function 'float GetNewAverage(int, int)':
Func7_2_dimensional_array:42: error: invalid types 'int [10][2][int [2]]' for array subscript
Func7_2_dimensional_array:44: error: invalid types 'int [10][2][int [2]]' for array subscript
Func7_2_dimensional_array:46: error: invalid types 'int [10][2][int [2]]' for array subscript
Func7_2_dimensional_array:48: error: incompatible types in assignment of 'int*' to 'int [2]'
Func7_2_dimensional_array:50: error: ISO C++ forbids comparison between pointer and integer
Func7_2_dimensional_array:52: error: incompatible types in assignment of 'int' to 'int [2]'
Title: Re: I'm stuck trying 2d arrays.
Post by: AWOL on Feb 11, 2017, 02:25 pm
I rather thought I had done as you suggest?
If you had, do you really think I would be asking?

Code: [Select]
void InitArray(int readings[][],int nubReadings,
Your problem is "readings" in the function prototype - you need to tell the compiler the size of the second dimension (the "stride") of the array.
Also, "nubReadings" is not "numReadings"
Title: Re: I'm stuck trying 2d arrays.
Post by: 9fingers on Feb 11, 2017, 03:23 pm
Thank you.

I'm still in trouble sadly


The error suggests that numPorts is not declared somewhere but haven't I set is as a global in line 2?

Code: [Select]

//-----------------
//set up the global variables
const int numReadings = 10;
const int numPorts = 2;
long numberofReadings=numReadings;
int readings[numReadings][numPorts];      // the readings from the analog input ports
int readIndex[numPorts];// the index of the current reading


float total[numPorts];                  // the running totals for each port
float average[numPorts];                // the average for each port


void setup() {
  // initialize serial:
  Serial.begin(9600);
  analogReference(EXTERNAL);
  InitArray(readings,numReadings,numPorts); //call function to pre-fill the arrays
}

void loop() {
  average= GetNewAverage(readings);
  // send it to the computer as ASCII digits
  Serial.print(average);
  Serial.print("  ");
  delay(1000);        // delay in between reads for stability
  Serial.println("  ");
}
void InitArray(int readings[][numPorts]){
  // initialize all the readings to an initial read value from each port
  for (int j=0; j< numPorts; j++){
    int initReading=analogRead(j);
    for (int i = 0; i < numReadings; i++) readings[i][j] = initReading;
    total[j]=numberofReadings*initReading;
    average[j]=initReading;
  }
}
float GetNewAverage(int readings[][numPorts]){
  for (int j=0;j<numPorts; j++){
    // subtract the last reading:
    total = total - readings[readIndex][j];
    // read from the sensor:
    readings[readIndex][j] = analogRead(j);
    // add the reading to the total:
    total = total + readings[readIndex][j];
    // advance to the next position in the array:
    readIndex = readIndex + 1;
    // if we're at the end of the array...
    if (readIndex >= numReadings) {
      // ...wrap around to the beginning:
      readIndex = 0;
    }
  }
}



errors:

Func7_2_dimensional_array:7: error: 'numPorts' was not declared in this scope
Func7_2_dimensional_array:8: error: 'numPorts' was not declared in this scope
Func7_2_dimensional_array.ino: In function 'void setup()':
Func7_2_dimensional_array:7: error: too many arguments to function 'void InitArray()'
Func7_2_dimensional_array:19: error: at this point in file
Func7_2_dimensional_array.ino: In function 'void loop()':
Func7_2_dimensional_array:8: error: too many arguments to function 'float GetNewAverage()'
Func7_2_dimensional_array:23: error: at this point in file
Func7_2_dimensional_array:23: error: incompatible types in assignment of 'float' to 'float [2]'
Func7_2_dimensional_array:25: error: call of overloaded 'print(float [2])' is ambiguous
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:58: note: candidates are: size_t Print::print(char) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:59: note:                 size_t Print::print(unsigned char, int) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:60: note:                 size_t Print::print(int, int) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:61: note:                 size_t Print::print(unsigned int, int) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:62: note:                 size_t Print::print(long int, int) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:63: note:                 size_t Print::print(long unsigned int, int) <near match>
Func7_2_dimensional_array.ino: In function 'float GetNewAverage(int (*)[2])':
Func7_2_dimensional_array:42: error: invalid types 'int (*)[2][int [2]]' for array subscript
Func7_2_dimensional_array:44: error: invalid types 'int (*)[2][int [2]]' for array subscript
Func7_2_dimensional_array:46: error: invalid types 'int (*)[2][int [2]]' for array subscript
Func7_2_dimensional_array:48: error: incompatible types in assignment of 'int*' to 'int [2]'
Func7_2_dimensional_array:50: error: ISO C++ forbids comparison between pointer and integer
Func7_2_dimensional_array:52: error: incompatible types in assignment of 'int' to 'int [2]'
Title: Re: I'm stuck trying 2d arrays.
Post by: BobKay on Feb 11, 2017, 03:28 pm
The compiler is right.  A const int is a variable.  Array sizes must be declared with hard coded numbers (except optionally the first, if you have initializers).

Instead of
Code: [Select]
const int numReadings = 10;
const int numPorts = 2;

do this:
Code: [Select]
#define numReadings 10
#define numPorts 2
Title: Re: I'm stuck trying 2d arrays.
Post by: 9fingers on Feb 11, 2017, 03:49 pm
Thanks BobKay


Next problem - argh!

so (?) using #define means everytime I refer to numPorts, the compiler inserts 2

But it seems to want a "," or "..." and I don't follow that.

Sorry to be a pain

Bob

Code: [Select]

//-----------------
//set up the global variables
#define numReadings 10
#define numPorts 2
long numberofReadings=numReadings;
int readings[numReadings][numPorts];      // the readings from the analog input ports
int readIndex[numPorts];// the index of the current reading
float total[numPorts];                  // the running totals for each port
float average[numPorts];                // the average for each port


void setup() {
  // initialize serial:
  Serial.begin(9600);
  analogReference(EXTERNAL);
  InitArray(readings,numReadings,numPorts); //call function to pre-fill the arrays
}

void loop() {
  average= GetNewAverage(readings, numReadings,numPorts);
  // send it to the computer as ASCII digits
  Serial.print(average);
  Serial.print("  ");
  delay(1000);        // delay in between reads for stability
  Serial.println("  ");
}
void InitArray(int readings[][numPorts],int numReadings, int numPorts){
  // initialize all the readings to an initial read value from each port
  for (int j=0; j< numPorts; j++){
    int initReading=analogRead(j);
    for (int i = 0; i < numReadings; i++) readings[i][j] = initReading;
    total[j]=numberofReadings*initReading;
    average[j]=initReading;
  }
}
float GetNewAverage(int readings[][numPorts], int numReadings, int numPorts){
  for (int j=0;j<numPorts; j++){
    // subtract the last reading:
    total = total - readings[readIndex][j];
    // read from the sensor:
    readings[readIndex][j] = analogRead(j);
    // add the reading to the total:
    total = total + readings[readIndex][j];
    // advance to the next position in the array:
    readIndex = readIndex + 1;
    // if we're at the end of the array...
    if (readIndex >= numReadings) {
      // ...wrap around to the beginning:
      readIndex = 0;
    }
  }
}



errors:

Func7_2_dimensional_array:8: error: expected ',' or '...' before numeric constant
Func7_2_dimensional_array:9: error: expected ',' or '...' before numeric constant
Func7_2_dimensional_array.ino: In function 'void setup()':
Func7_2_dimensional_array:8: error: too many arguments to function 'void InitArray(int (*)[2], int)'
Func7_2_dimensional_array:16: error: at this point in file
Func7_2_dimensional_array.ino: In function 'void loop()':
Func7_2_dimensional_array:9: error: too many arguments to function 'float GetNewAverage(int (*)[2], int)'
Func7_2_dimensional_array:20: error: at this point in file
Func7_2_dimensional_array:20: error: incompatible types in assignment of 'float' to 'float [2]'
Func7_2_dimensional_array:22: error: call of overloaded 'print(float [2])' is ambiguous
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:58: note: candidates are: size_t Print::print(char) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:59: note:                 size_t Print::print(unsigned char, int) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:60: note:                 size_t Print::print(int, int) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:61: note:                 size_t Print::print(unsigned int, int) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:62: note:                 size_t Print::print(long int, int) <near match>
C:\Documents and Settings\RCM\Desktop\Calorimeter development environment\arduino-1.0.5\hardware\arduino\cores\arduino/Print.h:63: note:                 size_t Print::print(long unsigned int, int) <near match>
Func7_2_dimensional_array.ino: At global scope:
Func7_2_dimensional_array:27: error: expected ',' or '...' before numeric constant
Func7_2_dimensional_array:36: error: expected ',' or '...' before numeric constant
Func7_2_dimensional_array.ino: In function 'float GetNewAverage(int (*)[2], int)':
Func7_2_dimensional_array:39: error: invalid types 'int (*)[2][int [2]]' for array subscript
Func7_2_dimensional_array:41: error: invalid types 'int (*)[2][int [2]]' for array subscript
Func7_2_dimensional_array:43: error: invalid types 'int (*)[2][int [2]]' for array subscript
Func7_2_dimensional_array:45: error: incompatible types in assignment of 'int*' to 'int [2]'
Func7_2_dimensional_array:47: error: ISO C++ forbids comparison between pointer and integer
Func7_2_dimensional_array:49: error: incompatible types in assignment of 'int' to 'int [2]'
Title: Re: I'm stuck trying 2d arrays.
Post by: AWOL on Feb 11, 2017, 03:49 pm
The compiler is right.  A const int is a variable.  

Nonsense.
Title: Re: I'm stuck trying 2d arrays.
Post by: AWOL on Feb 11, 2017, 03:51 pm
Code: [Select]
float GetNewAverage(int readings[][numPorts], int numReadings, int numPorts){
Here you promised the compiler that your function would return a float.

Are your pants a tad warm?
Title: Re: I'm stuck trying 2d arrays.
Post by: AWOL on Feb 11, 2017, 04:03 pm
Code: [Select]
total = total + readings[readIndex][j];
Can I suggest that you're also a little shaky on 1d arrays? (Hint: readIndex, total)
Title: Re: I'm stuck trying 2d arrays.
Post by: RayLivingston on Feb 11, 2017, 04:32 pm
Here's what you wrote:

Code: [Select]

#define numReadings 10
#define numPorts 2
...
float GetNewAverage(int readings[][numPorts], int numReadings, int numPorts){
...
}


Here's what the compiler sees after the pre-processor does its thing:

Code: [Select]



...
float GetNewAverage(int readings[][2], int 10, int 2){
...
}


See the problem?

Regards,
Ray L.
Title: Re: I'm stuck trying 2d arrays.
Post by: 9fingers on Feb 11, 2017, 05:12 pm
OK I do appreciate your patience Guys.

I'll pick up your points later please Ray L and AWOL

Firstly who is correct out of AWOL and BobKay

Should I be using

Code: [Select]
int const numPorts =2;   

or

Code: [Select]
#define numports 2

I can then sort that out and move on to the other points
I will also get one function working first and use that the inform changes to the second function.
small steps at a time!

TIA

Bob
Title: Re: I'm stuck trying 2d arrays.
Post by: AWOL on Feb 11, 2017, 05:19 pm
I don't know if you can use
Code: [Select]
int const numPorts =2;, but you most certainly can use
Code: [Select]
const int numPorts =2;

You can use the #define method, but this is C++, and the preprocessor is so  C, and, as you've seen, it can trip up the unwary.
Title: Re: I'm stuck trying 2d arrays.
Post by: econjack on Feb 11, 2017, 05:50 pm
You define readIndex[] as an array:

int readIndex[numPorts];

but towards the bottom of the program you use:

   readIndex = 0;


Most compilers are not going to like that. If the compiler did what you're trying to do with that statement, it would move the array to memory location 0. My guess is that there's some pretty important stuff already stored there.
Title: Re: I'm stuck trying 2d arrays.
Post by: AWOL on Feb 11, 2017, 05:52 pm
You define readIndex[] as an array:

int readIndex[numPorts];

but towards the bottom of the program you use:

   readIndex = 0;


Most compilers are not going to like that. If the compiler did what you're trying to do with that statement, it would move the array to memory location 0. My guess is that there's some pretty important stuff already stored there.
The compiler shouldn't allow that, and will give an invalid lvalue assignment error
Title: Re: I'm stuck trying 2d arrays.
Post by: 9fingers on Feb 11, 2017, 05:59 pm
Ok I will stick with
Code: [Select]
const int numPorts=2;

I've cut the code down to one function and one call in set up and nothing in loop()

to keep it simple.

It may now be more a case of me not understanding function calls properly?

we now have
Code: [Select]

//-----------------
//set up the global variables
const int numReadings =10;
const int numPorts =2;
long numberofReadings=numReadings;
int readings[numReadings][numPorts];      // the readings from the analog input ports
int readIndex[numPorts];// the index of the current reading
float total[numPorts];                  // the running totals for each port
float average[numPorts];                // the average for each port


void setup() {
  // initialize serial:
  Serial.begin(9600);
  analogReference(EXTERNAL);
  InitArray(readings,numReadings,numPorts); //call function to pre-fill the arrays
}

void loop() {
}
void InitArray(int readings[][numPorts],numReadings,numPorts){
  // initialize all the readings to an initial read value from each port
  for (int j=0; j< numPorts; j++){
    int initReading=analogRead(j);
    for (int i = 0; i < numReadings; i++) readings[i][j] = initReading;
    total[j]=numberofReadings*initReading;
    average[j]=initReading;
  }
}


and Errors:

Func9_2_dimensional_array:7: error: 'numPorts' was not declared in this scope
Func9_2_dimensional_array:7: error: 'numReadings' has not been declared
Func9_2_dimensional_array:7: error: 'numPorts' has not been declared
Func9_2_dimensional_array.ino: In function 'void setup()':
Func9_2_dimensional_array:17: error: invalid conversion from 'int (*)[2]' to 'int'
Func9_2_dimensional_array:7: error: too many arguments to function 'void InitArray(int, int)'
Func9_2_dimensional_array:17: error: at this point in file
Func9_2_dimensional_array.ino: At global scope:
Func9_2_dimensional_array:22: error: 'numReadings' is not a type
Func9_2_dimensional_array:22: error: 'numPorts' is not a type
Title: Re: I'm stuck trying 2d arrays.
Post by: AWOL on Feb 11, 2017, 06:11 pm
Which version of the IDE are you using and what board are you compiling for?
Title: Re: I'm stuck trying 2d arrays.
Post by: AWOL on Feb 11, 2017, 06:13 pm
Code: [Select]
void InitArray(int readings[][numPorts],int numReadings, int numPorts){
Title: Re: I'm stuck trying 2d arrays.
Post by: econjack on Feb 11, 2017, 06:38 pm
The compiler shouldn't allow that, and will give an invalid lvalue assignment error
Which is why I said most compilers won't like that. It's trying to replace a constant lvalue. To a beginner, which is easier to understand: The compiler won't like that, or You're trying to reassign a constant lvalue? A beginner probably doesn't even know what an lvalue is.
Title: Re: I'm stuck trying 2d arrays.
Post by: 9fingers on Feb 11, 2017, 06:43 pm
Which version of the IDE are you using and what board are you compiling for?
I am using ver 1.0.5 and the target is the UNO board
Title: Re: I'm stuck trying 2d arrays.
Post by: econjack on Feb 11, 2017, 06:47 pm
I am using ver 1.0.5 and the target is the UNO board
Good grief...you're way behind. I'd update your IDE to 1.8.1.
Title: Re: I'm stuck trying 2d arrays.
Post by: 9fingers on Feb 11, 2017, 07:37 pm
Good grief...you're way behind. I'd update your IDE to 1.8.1.
Sounds a bit like suggesting I need to change the engine when the headlamps are not bright enough!

I'm not using any of the latest hardware and only using quite basic features of the language.
Title: Re: I'm stuck trying 2d arrays.
Post by: AWOL on Feb 11, 2017, 07:49 pm
Quote
Sounds a bit like suggesting I need to change the engine when the headlamps are not bright enough!
Different IDEs will give different error messages, which is why I asked; I couldn't match the error messages with what I was seeing.

Quote
only using quite basic features of the language.
sp. "misusing"
Title: Re: I'm stuck trying 2d arrays.
Post by: 9fingers on Feb 11, 2017, 08:06 pm
Different IDEs will give different error messages, which is why I asked; I couldn't match the error messages with what I was seeing.
 sp. "misusing"
No problem. My reply was directed to Econjack.

I could set up a fresh version of IDE on another machine if it helps you to help me. Let me know your preference.

Yup "Misusing" is probably more correct but I'm hoping to improve! I've not done any serious programming since the mid 70s using Algol 60 but that is long forgotten I'm afraid.
Title: Re: I'm stuck trying 2d arrays.
Post by: AWOL on Feb 11, 2017, 08:08 pm
I'm not saying an update will cause the code to compile, but at least we'll be singing from the same hymn-sheet.
Title: Re: I'm stuck trying 2d arrays.
Post by: 9fingers on Feb 11, 2017, 08:13 pm
OK Awol, Which version would you suggest I install 1.8.1 in the interest of musical harmony or something else?