[solved]atan2() problem/bug?

Hello everyone,

I am working on a project where i have to translate the X and Y positions to a single rotation degree.
Thankfully there is a form of math atan2(x,y) developed for this, however i stumbled uppon a problem with this method on arduino.

I've written a basic code(which i will post bellow) to test this method but found out that it doesn't work the way i think it should work. If i turn my joystick around and insert their values (converted to -Pi to Pi) the end result of atan2(x,y) only results in either PI of 0, nothing inbetween or bellow.

I've tested the math but now with firmata on arduino and run it in processing and it works like a charm the way it should. So my best bet is that some floats/doubles get converted along the way somewhere in arduino, but i am not that familiour with the deeper code of arduino so I hope you guys can help me with that.

I am using arduino 1.6.13

double Degrees[2];
int potPins[]= {A0, A1};

void setup() {
  Serial.begin(9600);
  for(int i =0; i<(sizeof(potPins)/sizeof(int)); i++){
    pinMode(potPins[i], INPUT);
  }
}

void loop() {
  for(int i =0; i < (sizeof(potPins)/sizeof(int)); i++){
    Degrees[i] = doubleMap(analogRead(potPins[i]),0,975,-PI,PI);
    Serial.print(Degrees[i]);
    Serial.print("  ");
  }
  Serial.print(atan2(Degrees[1],Degrees[2]));
  Serial.println();
}

double doubleMap(double x, double in_min, double in_max, double out_min, double out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

I hope you guys can help or give me a new insight in the problem

  Serial.print(atan2(Degrees[1],Degrees[2]));
  1. That should be Degrees[0] and [1] instead of [1] and [2].
  2. The parameters to atan2() are (y,x), not (x,y).

oqibidipo:

  Serial.print(atan2(Degrees[1],Degrees[2]));
  1. That should be Degrees[0] and [1] instead of [1] and [2].
  2. The parameters to atan2() are (y,x), not (x,y).

This is true, but it still doesn't change the issue. Changing it still does the same thing.

It does change the issue, because it changes the code, which you haven't posted.

    pinMode(potPins[i], INPUT);

It is pointless to set the digital nature of a pin you use as an analog pin.

What values are you getting in serial monitor from this line? Serial.print(Degrees[i]);

Why map the values to PI/-PI? the whole point of atan2 is that you don't need to do this - it works on the ratio between the two values. Just subtract 512 to get zero where it needs to be.

Wait, tangent takes an angle and returns the ratio (toa), atan takes the x and y legs and returns an angle, why are you feeding it an angle?

Ok let me completely reformulate the question because we are going on details while the problem remains:

  • Problem: When i use atan2(a,b) and insert floats i expect to get values that change as a and b change but instead they eighter give me 0 or PI nothing inbetween and nothing inbetween 0 and -PI either.

  • My Question: Is this the same with you guys? If you use a arduino and insert 2 potentiometers and add them both into a atan2 function what are your results?

My Question: Is this the same with you guys?

No. When I call atan2() with good data, I get a good result.

That you don't seem to means that there is still a problem in your code. Prove that you've fixed the problems that have already been pointed out, that you dismissed as irrelevant. Prove that the data that you pass to atan2 IS good data. Prove that, given good data, atan2() returns bad results.

BartZuidervaart:
Ok let me completely reformulate the question because we are going on details while the problem remains:

  • Problem: When i use atan2(a,b) and insert floats i expect to get values that change as a and b change but instead they eighter give me 0 or PI nothing inbetween and nothing inbetween 0 and -PI either.

  • My Question: Is this the same with you guys? If you use a arduino and insert 2 potentiometers and add them both into a atan2 function what are your results?

You need to ISOLATE the problem.

You are getting garbage output and you think it's the fault of atan2(). I assure you, this is a classic case of GIGO (Garbage In. Garbage Out.).

You THINK you are getting good numbers from the pots. You think you are putting those numbers into Degrees properly.
As was asked earlier, what is your serial.print giving you for Degrees[0] and Degrees[1], and are you putting those numbers into atan2() correctly (again, not Degrees[1] and Degrees[2], but Degrees[0] and Degrees[1])?
*I guarantee you are not putting the numbers in there you think you are. *

I am an idiot.
That was it guys; atan2(Degrees[2],Degrees[1]) should have been atan2(Degrees[1],Degrees[0]), thank you very much for your help.
Sorry for the stubborness.

BartZuidervaart:
I am an idiot.
That was it guys; atan2(Degrees[2],Degrees[1]) should have been atan2(Degrees[1],Degrees[0]), thank you very much for your help.
Sorry for the stubborness.

Do you understand why it's 0 and 1? In C++, array indexes are an offset from the start of the array. The first element in an array is at offset zero.

PaulMurrayCbr:
Do you understand why it's 0 and 1? In C++, array indexes are an offset from the start of the array. The first element in an array is at offset zero.

Yeah i understand, for some reason i was completely blind to the Degrees[2] standing there.