Go Down

### Topic: returning two values from a function (Read 2113 times)previous topic - next topic

#### dustynrobots

##### Feb 14, 2012, 10:41 pm
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:
http://youtu.be/IHGXqud2m9Q

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))/(2*a1*a2); // 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(-a2*s2*Px + (a1 + a2*c2)*Py, (a1 + a2*c2)*Px + a2*s2*Py));

//return???
}

#### AWOL

#1
##### Feb 14, 2012, 10:44 pmLast Edit: Feb 14, 2012, 10:49 pm by AWOL Reason: 1
You could pass by reference, and not return anything.
Or you could return a struct.
Watch out for the function prototypes.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

#### Grumpy_Mike

#2
##### Feb 14, 2012, 10:46 pm
Quote
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.

#### dustynrobots

#3
##### Feb 14, 2012, 11:08 pm
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!

#### AWOL

#4
##### Feb 14, 2012, 11:10 pm
Just make sure you don't return a pointer to a local automatic variable.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

#### mromani

#5
##### Feb 14, 2012, 11:11 pm
Something along these lines:

Code: [Select]
`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);}`

Code: [Select]
`// inputs: x, y// outputs: a, bvoid 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);}`

#### mromani

#6
##### Feb 14, 2012, 11:14 pm
Quote
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

#### dustynrobots

#7
##### Feb 14, 2012, 11:21 pm
thanks! will work in implementing that now

#### retrolefty

#8
##### Feb 14, 2012, 11:31 pm
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

#### GoForSmoke

#9
##### Feb 15, 2012, 01:15 am
Well my beard is white and I use globals. For one thing, they stay allocated.
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

#### retrolefty

#10
##### Feb 15, 2012, 01:27 am

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'.

#### Grumpy_Mike

#11
##### Feb 15, 2012, 04:39 am
Well I am with you on the use of global variables, so what colour does it make my beard?

#### retrolefty

#12
##### Feb 15, 2012, 04:53 am

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:

#### Nick Gammon

#13
##### Feb 15, 2012, 09:33 am

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

That is probably the simplest.

Code: [Select]
`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.
Please post technical questions on the forum, not by personal message. Thanks!

http://www.gammon.com.au/electronics

Go Up

Please enter a valid email to subscribe

To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy