Return two values from Arduino function

Hi everyone;

I'm use this custom function to derive Lat Lon data including two returns.

float secondpoints(float CurLat , float CurLon, float Distance, float Bearing) {
  r_CurLon = radians(CurLon);
  r_CurLat = radians(CurLat);
  r_Bearing = radians(Bearing);
  float DestLat = asin(sin(r_CurLat) * cos(Distance / Eradius) + cos(r_CurLat) * sin(Distance / Eradius) * cos(r_Bearing));
  float DestLon = r_CurLon + atan2(sin(r_Bearing) * sin(Distance / Eradius) * cos(r_CurLat), cos(Distance / Eradius) - sin(r_CurLat) * sin(DestLat));
  DestLon = (DestLon + 3 * PI) / (2 * PI);
  int i = DestLon;
  DestLon = (DestLon - i) * (2 * PI) - PI; 

  return degrees(DestLat), degrees(DestLon);
}

When I calling the function like this it giving only one output as follows,

  float latitude, longitude = secondpoints(16.71104336, 8.79084659, 300, 226.4369444);

0.00000000
8.78880501

My problem is how to passing two float values from this function. This 0.0000000 is wrong value and it wasn't passing from function. I hope your help to solve this.
Thank You.

the above statement is using the comma operator which evaluates a sequence of comma seperated expressions and returns of value of the right-most expression
hence the function returns the result of degrees(DestLon)
you could return two values using parameter passing by reference, e.g.

void secondpoints(float CurLat , float CurLon, float Distance, float Bearing, float &DestLat, float &DestLon) {
  r_CurLon = radians(CurLon);
  r_CurLat = radians(CurLat);
  r_Bearing = radians(Bearing);
  DestLat = asin(sin(r_CurLat) * cos(Distance / Eradius) + cos(r_CurLat) * sin(Distance / Eradius) * cos(r_Bearing));
  DestLon = r_CurLon + atan2(sin(r_Bearing) * sin(Distance / Eradius) * cos(r_CurLat), cos(Distance / Eradius) - sin(r_CurLat) * sin(DestLat));
  DestLon = (DestLon + 3 * PI) / (2 * PI);
  int i = DestLon;
  DestLon = (DestLon - i) * (2 * PI) - PI; 
}
1 Like

C++ does not let you return 2 values

you need to pack them in a structure and return the structure or indeed pass them as parameters by reference (or pointer) which is easier

just for the sake of completeness, with a structure you would do something like this

struct t_positionDegrees {
 float latitudeDegrees;
 float longitudeDegrees;
};

t_positionDegrees secondpoints(float CurLat , float CurLon, float Distance, float Bearing) {
  t_positionDegrees destination;
  r_CurLon = radians(CurLon);
  r_CurLat = radians(CurLat);
  r_Bearing = radians(Bearing);
  float DestLat = asin(sin(r_CurLat) * cos(Distance / Eradius) + cos(r_CurLat) * sin(Distance / Eradius) * cos(r_Bearing));
  float DestLon = r_CurLon + atan2(sin(r_Bearing) * sin(Distance / Eradius) * cos(r_CurLat), cos(Distance / Eradius) - sin(r_CurLat) * sin(DestLat));
  DestLon = (DestLon + 3 * PI) / (2 * PI);
  int i = DestLon;
  DestLon = (DestLon - i) * (2 * PI) - PI; 

destination.latitudeDegrees =  degrees(DestLat);
destination.longitudeDegrees =   degrees(DestLon);

  return destination ; // return by copy
}

and call this with

t_positionDegrees dest = secondpoints(CurLat , CurLon,  Distance, Bearing) ;
2 Likes

Here is a simple example to show how to return the values as a struct:

struct myFloats_t {
    float longitude;
    float latitude;
} lonlat;

myFloats_t retStruct () {
    myFloats_t localStruct;
    localStruct.longitude = 6.1234;
    localStruct.latitude = 8.778;
    return localStruct;
}
void setup() {
    // put your setup code here, to run once:
    Serial.begin(115200);
    lonlat = retStruct();
    Serial.println( lonlat.longitude );
    Serial.println( lonlat.latitude );

}

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

}

Output:

6.12
8.78
2 Likes

sorry I was editing & typing something similar when you were adding the example.

1 Like

No reason to say sorry :slightly_smiling_face:- more examples are even better :+1:

1 Like

I have restructured your beautiful example as follows in order to map my understanding of programming using "user-defined function (UDF)" to which we may optionally pass parameters. Here, I have copied two items of the source structure (lonlat) into the corresponding two items of the destination structure (localStruct) using UDF and return statement.

struct myFloats_t
{
  float longitude;
  float latitude;
};

myFloats_t srcStruct;  //source struct
myFloats_t destStruct; //destination struct
myFloats_t retStruct(float x, float y); //UDF declaration

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

  destStruct = retStruct(6.1234, 8.778);
  Serial.println( destStruct.longitude, 2);
  Serial.println(destStruct.latitude, 2 );
}

void loop()
{

}

myFloats_t retStruct (float lon, float lat)
{
  srcStruct.longitude = lon; //updating source structure bu UDF
  srcStruct.latitude = lat;  //updating source structure by UDF
  return srcStruct; //copy two items of source stureture into dest struct
}
2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.