angle calculation from magnetometer data

Hi all,

I am using 9DOF board and arduino mega. I need to count an angle in degrees from magnetometer X and Y axis. The 9DOF board is sending a string sentences like this: $-2,-2,229,8,-35,13,-13,59,-190# The X and Y magnetometer values are the third and the second from the end of string sentence. I’m using this code to parse those values and count the angle.

onst int NUMBER_OF_FIELDS = 9; // how many comma-separated fields we expect
int fieldIndex = 0;             // the current field being received
int values[NUMBER_OF_FIELDS];// array holding values for all the fields


void setup()
{
  Serial.begin(9600);
  Serial2.begin(57600); // Initialize serial port to send and receive at 9600 baud
}

void loop()
{

  if( Serial2.available()) {
    for(fieldIndex = 0; fieldIndex  < 9; fieldIndex ++)
    {
      values[fieldIndex] = Serial2.parseInt(); // get a numeric value

    }
    //Serial.print( fieldIndex);
    //Serial.println(" fields received:");
    for(int i=0; i <  fieldIndex; i++)
    {
       int val = values[6];
       int val1 = values[7];
       
       float kampas = atan2(val1,val);
       
       if (kampas >= 0){
       float kampas1 = kampas*180/PI;
     Serial.println(kampas1);
       }
       else {
        float kampas1 = kampas*(-180)/PI;
       Serial.println(kampas1);
     }
    }
    fieldIndex = 0;  // ready to start over
  }
}

But this code didn’t work. I think first values are right, but later the code starts posting a random values… :frowning: Can anyone help for me?

atan2() takes radians what are you giving it?

Looking in to this sample https://github.com/rob42/FreeIMU-20121106_1323/blob/master/libraries/HMC58X3/examples/HMC58X3_basic/HMC58X3_basic.pde the values seems right...

Isolate the inputs and outputs from your calculation and just focus on those. Do you know what the input values are, what the expected output value is and what the actual output value is, when the problem occurs?

Something wrong is in my parsing code…

const int NUMBER_OF_FIELDS = 9; // how many comma-separated fields we expect
int fieldIndex = 0;             // the current field being received
int values[NUMBER_OF_FIELDS];   // array holding values for all the fields


void setup()
{
  Serial.begin(9600);
 //Serial2.begin(57600); // Initialize serial port to send and receive at 9600 baud
}

void loop()
{

  if( Serial.available()) {
    for(fieldIndex = 0; fieldIndex  < 9; fieldIndex ++)
    {
      values[fieldIndex] = Serial.parseInt(); // get a numeric value

    }
    Serial.print( fieldIndex);
    Serial.println(" fields received:");
    for(int i=0; i <  fieldIndex; i++)
    {
       Serial.println(values[i]);
    }
    fieldIndex = 0;  // ready to start over
  }
}

To test this code a copied some data from my sensor and it looks like that:

$27,-9,230,7,-33,14,39,43,-194#

$27,-10,229,4,-32,12,39,43,-194#

$26,-9,229,4,-35,16,39,43,-194#

$26,-9,230,9,-35,14,39,43,-194#

$26,-10,228,6,-34,12,39,43,-194#

$27,-11,230,4,-33,19,39,43,-194#

$26,-11,231,6,-35,10,39,43,-194#

$25,-11,229,5,-35,19,39,43,-195#

$25,-11,230,4,-38,10,39,43,-195#

$24,-11,230,6,-34,15,39,43,-195#

$26,-11,230,3,-32,18,39,43,-195#

Then serial monitor show these values:

9 fields received:
27
-9
230
7
-33
14
39
43
-194
9 fields received:
27
-10
229
4
-32
12
39
43
-194
9 fields received:
26
-9
229
4
-35
16
39
43
-194
9 fields received:
26
-9
230
9
-35
14
39
43
-194
9 fields received:
26
-10
228
6
-34
12
39
43
-194
9 fields received:
27
-11
230
4
-33
19
39
436  <----- Here it start failing
-11
9 fields received:
231
6
-35
10
39
43
-194
2195
25
9 fields received:
-11
230
4
-38
10
39
43
0
39
9 fields received:
43
-195
26
-11
230
3
-32
18
39

I pointed the place where it starts failing. Any ideas?

At first glance it looks as if your parsing code is getting out of sync with the input stream.

I suggest you modify your example to show the input and output from the parsing code so that you can see what it was actually trying to parse - as opposed to what you intended it to be parsing.

If I understand You right I have already done it. I grab some real data from my sensor and tested it with my code and showed the results. I think with this code I'm filling up some king of arduino memory because if I'm parsing for example 4 fields the code works fine 12 time, but if I'm parsing 9 fields it's only parse 8 times right values.

mantazzz: I grab some real data from my sensor and tested it with my code and showed the results.

Unfortunately the code doesn't show the input string that was processed to produce each input value. That's a limitation of using parseInt, because you never get to see the original string before it was parsed.

If it worked, that would be fine. But, given that it doesn't, I think you will need to read and explicitly parse the input string so that you can see what character sequence was actually received by your sketch (that may not be what you think your source sent), how the sketch separated it into fields, and how it converted each field into an integer. The error could have occurred at any of these steps so you need to investigate to see where it goes wrong.