returning two values from a function

I’m breaking up some messy code into separate functions, and can’t seem to figure out how to pass two parameters into a function, and get two back. The passing part is easy - I can just call get_angles(somenumber, somenumber), but how do I make theta1 and theta2 available within the loop() or wherever I call the function? If anyone has insight or a good link to a reference that would be great! Thanks

Oh, and in case you’re interested, this function is supposed to pass an x,y position and return two joint angles, so I can control this:

double get_angles(double Px, double Py)
{
// first find theta2 where c2 = cos(theta2) and s2 = sin(theta2)
double c2 = (pow(Px,2) + pow(Py,2) - pow(a1,2) - pow(a2,2))/(2a1a2); // is btwn -1 and 1
double s2 = sqrt(1 - pow(c2,2));
double theta2 = degrees(atan2(s2,c2)); // solves for the angle in degrees and places in correct quadrant

// now find theta1 where c1 = cos(theta1) and s1 = sin(theta1)
double theta1 = degrees(atan2(-a2s2Px + (a1 + a2c2)Py, (a1 + a2c2)Px + a2s2Py));

//return???
}

You could pass by reference, and not return anything. Or you could return a struct. Watch out for the function prototypes.

and get two back.

You can't get two values back from a function, that is not the way C is built.

The closest you can get is to return a pointer to an array, or let it operate on global variables.

Alternatively you can pass an array pointer in and get the function to modify what it points to.

return a pointer to an array - how? You could pass by reference, and not return anything - how? Or you could return a struct - how? Watch out for the function prototypes - what do you mean?

or let it operate on global variables - okay so if I declare theta1 and theta2 as global, and the get_angles function does something to them, the new values of theta1 and theta2 will be available anywhere, correct?

thanks!

Just make sure you don't return a pointer to a local automatic variable.

Something along these lines:

``````struct angles {
double a;
double b;
};

struct angles f(double x, double y) {
struct angles ang;

ang.a = ....
ang.b = ....

return ang;
}

void loop() {
struct angles theAngles;

x = ...
y = ...

theAngles = f(x, y);
}
``````
``````// inputs: x, y
// outputs: a, b
void f(double x, double y, double* a, double* b) {
*a = ....
*b = ....

return;  // no return value
}

void loop() {
double theta1;
double theta2;

x = ...
y = ...

f(x, y, &theta1, &theta2);
}
``````

return a pointer to an array - how? You could pass by reference, and not return anything - how? Or you could return a struct - how? Watch out for the function prototypes - what do you mean?

Ok, not the simplest you can find around, but at least they should get you started:

http://en.wikipedia.org/wiki/Function_prototype

http://en.wikipedia.org/wiki/Pass_by_reference#Call_by_reference

http://en.wikipedia.org/wiki/Struct_%28C_programming_language%29

thanks! will work in implementing that now

While frowned upon by the grey beards, I would just tend to use global variables is such situations. As my sketches tend to be on the small size, and I'm the only one writing and using the code, I don't have too much difficulty tracking of what functions will have access to changing such variables and have not had a bug yet where the reason was the use of global variables Vs if I had used local scope variables and passed the return values.

Lefty

Well my beard is white and I use globals. For one thing, they stay allocated.

GoForSmoke: Well my beard is white and I use globals. For one thing, they stay allocated.

Well then both you and Santa Claus have white beards and therefore friendly by definition. While grey beards are always rather stern and abrupt with us less experienced 'Arduino programmers'. ;)

Well I am with you on the use of global variables, so what colour does it make my beard?

Grumpy_Mike: Well I am with you on the use of global variables, so what colour does it make my beard?

GM, due to your seniority and revered stature on this forum, I would give you first pick on any color (not colour!) you wished to paint your beard. Here is something to help you decide:

dustynrobots: You could pass by reference, and not return anything - how?

That is probably the simplest.

``````double a1 = 1, a2 = 2;

void get_angles(const double Px, const double Py, double & theta1, double & theta2)
{
// first find theta2 where c2 = cos(theta2) and s2 = sin(theta2)
double c2 = (pow(Px,2) + pow(Py,2) - pow(a1,2) - pow(a2,2))/(2*a1*a2); // is btwn -1 and 1
double s2 = sqrt(1 - pow(c2,2));
theta2 = degrees(atan2(s2,c2));  // solves for the angle in degrees and places in correct quadrant

// now find theta1 where c1 = cos(theta1) and s1 = sin(theta1)
theta1 = degrees(atan2(-a2*s2*Px + (a1 + a2*c2)*Py, (a1 + a2*c2)*Px + a2*s2*Py));
} // end of get_angles

void setup ()
{
double t1, t2;
get_angles (20, 30, t1, t2);
}

void loop () {}
``````

I noticed when I was doing this that you have a1 and a2 as variables which presumably are global. So you need to make up your mind if the function is going to be a "black box" (and thus pass everything to it). If not, passing some stuff and not others seems to be hedging your bets a bit.

In my example get_angles returns its results by reference (the last two arguments) so it needs "return" nothing.