• 0
gruberth96

How to convert unsigned magnometer data to Degrees

Question

Hello, I am using the digilent CMPS2 module which uses the Memsic MMC34160PJ magnetometer. 

In the datasheet of chip CMPS2 there is a formula with actan(x/y)*180/pi.

Is it right to use for x and y only the LSB (8 bits) multiplied with the number 0,48.... as shown in the datasheet in point 1?

It‘s clear that I only get values between 0 and 90 degrees because the sensor delivers only unsigned values.

When I use atan2 I get values between 0 and 180 degrees.

I know it would be easier if I had signed data. But unfortunately the sensor delivers only unsigned values.

How is such a conversion form of unsigned magnometer data 0 to 360 degrees possible?

 

D359E0AF-C7D6-42B5-9A26-C41AB3A8FDE4.png

Share this post


Link to post
Share on other sites

1 answer to this question

Recommended Posts

  • 0

Hi @gruberth96,

On the resource center there is an Arduino project for the Pmod CMPS2. In the  CMPS2.cpp

The function Degree() converts the X and Y data to degrees

Spoiler

/**********************************************
Function: degree()

Date Last Modified: *
Description: This funciton determines the degree reading of the sensor.
    The reading is adjusted to match with conventional compass readings. This does
    not currently include any elliptical calculation to compensate for tilt of the
    sensor, so these readings will only be accurate when device is operated on a level
    surface
Input Param: none
Return: degree measurement integer
**********************************************/
int CMPS2::degree()
{
  int temp0 = 0;
  int temp1 = 0;
  int deg = 0;

  if(this->x < this->xMid)
  {
    if(this->y > this->yMid)
    {
      //Quadrant 1
      temp0 = this->y - this->yMid;
      temp1 = this->xMid - this->x;

      deg = (90) - ( atan((double)((temp0)/(double)(temp1))) * (180/3.14159) );
    }
    else
    {
      //Quadrant 2
      temp0 = this->yMid - this->y;
      temp1 = this->xMid - this->x;

      deg = (90) + ( atan((double)((temp0)/(double)(temp1))) * (180/3.14159) );
    }
  }
  else
  {
    if(this->y < this->yMid)
    {
      //Quadrant 3
      temp0 = this->yMid - this->y;
      temp1 = this->x - this->xMid;

      deg = (270) - ( atan((double)((temp0)/(double)(temp1))) * (180/3.14159) );
    }
    else
    {
      //Quadrant 4
      temp0 = this->y - this->yMid;
      temp1 = this->x - this->xMid;

      deg = (270) + ( atan((double)((temp0)/(double)(temp1))) * (180/3.14159) );
    }
  }

  deg = deg + declination;

  if(declination > 0)
  {
      if(deg > 360)
        deg = deg - 360;
  }
  else
  {
      if(deg < 0)
        deg = 360 + deg;
  }

  return deg;
}

 

We also have a Pmod CMPS2 IP core  available in the Vivado Library.  Looking at the Pmod CMPS2 IP Core main.c the function below converts the X and Y data and converts it to degrees

int DemoConvertDegree(PmodCMPS2 *InstancePtr, CMPS2_CalibrationData calib,

CMPS2_DataPacket data, int declination)

Spoiler

{

int tx, ty;

int deg;

if (data.x < calib.mid.x)

tx = (calib.mid.x - data.x);

else

tx = (data.x - calib.mid.x);

if (data.y < calib.mid.y)

ty = (calib.mid.y - data.y);

else

ty = (data.y - calib.mid.y);

if (data.x < calib.mid.x) {

if (data.y > calib.mid.y)

deg = 90 - atan2f(ty, tx) * 180 / 3.14159;

else

deg = 90 + atan2f(ty, tx) * 180 / 3.14159;

} else {

if (data.y < calib.mid.y)

deg = 270 - atan2f(ty, tx) * 180 / 3.14159;

else

deg = 270 + atan2f(ty, tx) * 180 / 3.14159;

}

thank you,

Jon

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now