Return Values of Arrays of Functions, please help

( error )
arraytest.ino:11:34: error: cannot convert '' to 'float*' in assignment
array = {X_Axis, Y_Axis, Z_Axis};
^
arraytest.ino:12:10: error: return-statement with a value, in function returning 'void' [-fpermissive]
return xyzarray;
^~~~~~~~
arraytest.ino: In function 'void loop()':
arraytest.ino:18:31: error: variable or field 'adxl345measure' declared void
void adxl345measure(xyzarray);
^
arraytest.ino:18:23: error: 'xyzarray' was not declared in this scope
void adxl345measure(xyzarray);
^~~~~~~~
exit status 1

Compilation error: cannot convert '' to 'float*' in assignment

float X_Axis, Y_Axis, Z_Axis, XYZ_Axis;

void adxl345measure(froat array[]) {

  float xyzarray[3] = {0.0, 0.0, 0.0};

  X_Axis = 0.0392266;  
  Y_Axis = 0.0392266;  
  Z_Axis = 0.0392266;  

  array = {X_Axis, Y_Axis, Z_Axis};
  return xyzarray;
}

void loop() {

  adxl345measure(xyzarray);               
  delay(1000);             
  
}

Hi
Array is not a type of data, it is a set of several values. You can't assign arrays from the list other than at initialization time. And you can't return array from the function as return value.

What is your question, exactly?

Your code has many problems...

float ?

You didn't declare array?

and even if you did you can't do that... you need to assign the elements one at a time..

array[0] = X_Axis;
array[1] = Y_Axis;
array[2] = Z_Axis;

xyzarray only exists inside the function adxl345measure, so you can't pass it in.

What are you trying to do? Return an array from a function? You can only do this "by reference" - you pass it in as a parameter, and the function will update it directly.

float passedArray[3];

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

  adxl345measure(passedArray);      

  Serial.println(passedArray[0]);
  Serial.println(passedArray[1]);
  Serial.println(passedArray[2]);
}


void loop() 
{}


void adxl345measure(float array[3]) 
{
  array[0] = 1.1;
  array[1] = 2.2;
  array[2] = 3.3;
}

Thank you for your response.
Please give me some tips on how to get three measurements from a measurement routine like this one to return values.

pass a pointer to the array or a reference to a structure for the data to your function and let the function fills in that memory

in the example from @red_car you pass the array information (pointer to the start of the array , data type and array size) or you could use a struct and a reference

// the type where we will be collecting information
struct t_data {
  float samples[3];
  uint32_t samplingTime; 
};

t_data measure;

void adxl345measure(t_data & theData) { // the & denotes that you pass the parameter by reference 
  theData.samples[0] = 1.1;
  theData.samples[1] = 2.2;
  theData.samples[2] = 3.3;
  theData.samplingTime = millis();
}

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

  adxl345measure(measure);

  Serial.println(measure.samplingTime);
  Serial.println(measure.samples[0]);
  Serial.println(measure.samples[1]);
  Serial.println(measure.samples[2]);
}


void loop() {}

the structure gives you freedom to organise the data as you feel is more relevant, you could do for example

// the type where we will be collecting information
struct t_data {
  float x;
  float y;
  float z;
  uint32_t samplingTime;
};

t_data measure;

void adxl345measure(t_data & theData) { // the & denotes that you pass the parameter by reference
  theData.x = 1.1;
  theData.y = 2.2;
  theData.z = 3.3;
  theData.samplingTime = millis();
}

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

  adxl345measure(measure);

  Serial.println(measure.samplingTime);
  Serial.println(measure.x);
  Serial.println(measure.y);
  Serial.println(measure.z);
}


void loop() {}

and once you are there you are not far from OOP

// the type where we will be collecting information
class Adxl345measure {
  public:
    float x;
    float y;
    float z;
    uint32_t samplingTime;

    void acquire() {
      x = 1.1;
      y = 2.2;
      z = 3.3;
      samplingTime = millis();
    }
};

Adxl345measure data;

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

  data.acquire();

  // not always a good idea to access member variables directly, but just for the sake of example 
  Serial.println(data.samplingTime);
  Serial.println(data.x);
  Serial.println(data.y);
  Serial.println(data.z);
}


void loop() {}

This sounds like a perfect example of employing a little OO to the mix. I’m sure there are lots of other ways to do this, but I like structs….

I’m not sure what level of c++ developer you are, so this may be redundant to you but here’s a little refresher

If you know it’s always going to be an array, then you can declare an internal variable as an array and hold it there. Otherwise you can declare your struct an array declaration time, and hold many versions of your struct in memory.

Keep in mind, the previous poster mentioned, that you can only pass these by reference. So if something updates them outside your main program flow, the data can change unexpectedly.

Thank you all for the many methods you have presented! , & many advices!

I am not at the level of OOP techniques, so I will try to deal with STRUCTS first!

Structures are objects...

is this what you're trying to do?
return 3 floats from the function call in the array argument to that function?

void adxl345measure (
    float array [] )
{
    array [0] = 0.0392266;
    array [1] = 0.0392266;
    array [2] = 0.0392266;
}

float xyzarray [3];

void loop ()
{
    adxl345measure (xyzarray);

    Serial.print (" "); Serial.print (xyzarray [0], 6);
    Serial.print (" "); Serial.print (xyzarray [1], 6);
    Serial.print (" "); Serial.print (xyzarray [2], 6);
    Serial.println ();

    delay (1000);
}

void setup ()
{
    Serial.begin (9600);
}

let's keep that under the rug initially if that's less scary :slight_smile:

float X_Axis, Y_Axis, Z_Axis, XYZ_Axis;

void adxl345measure(float (&array)[3])
{
  X_Axis = 0.0392266;
  Y_Axis = 0.0392266;
  Z_Axis = 0.0392266;

  array[0] = X_Axis;
  array[1] = Y_Axis;
  array[2] = Z_Axis;
}

void setup()
{
  Serial.begin(115200);
  delay(200);

  float xyzarray[3] = { 0.0, 0.0, 0.0 };

  adxl345measure(xyzarray);

  Serial.println(xyzarray[0], 7);
  Serial.println(xyzarray[1], 7);
  Serial.println(xyzarray[2], 7);
}

void loop()
{
}

When the data items of the measure variable can be directly manipulated by the adxl345measure() function, then what is the necessity/benefit of creating another data space named thedata?

void adxl345measure()//(t_data & theData) 
{ // the & denotes that you pass the parameter by reference
  measure.samples[0] = 1.1;
  measure.samples[1] = 2.2;
  measure.samples[2] = 3.3;
  measure.samplingTime = millis();
}

you can use the function to deal with different containers and not depend on the global variable. (say you want to make five measures sort them in some sort of order)

You could even return a reference to an array if that happens to suit your needs (the syntax is horrible though).

float (& test(float (& arr)[3]))[3] {
  arr[0] += 1.23;
  arr[1] += 2.34;
  arr[2] += 3.45;
  return arr;
}

This could be convenient when passing the output of one function to an other, e.g.,

void setup() {
  Serial.begin(9600);

  float arr[3] {};
  for (float const& el: test(test(arr))) {
    Serial.println(el);
  }
}

with output:

2.46
4.68
6.90

[edit]

We could clean this up a little by using an alias.

template <class T, size_t n> using ArrayRef = T (&)[n];

ArrayRef<float, 3> test(ArrayRef<float, 3> arr) {
  // ...
  return arr;
}

[edit 2]

If you have access to the standard template library, using std::array would probably be the best option.