Jump to content
  • 0

How to convert unsigned magnometer data to Degrees


gruberth96

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

Link to comment
Share on other sites

5 answers to this question

Recommended Posts

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

Link to comment
Share on other sites

Hi @aparna,

It's difficult to say on the accuracy. The main source of error will be from the module itself. The datasheet for the MMC34160PJ magnetometer claims header accuracy within 1% (if you use their proprietary software/algorithim as clarified on the second page of the datasheet), though with the Set/Reset functions to help eliminate the 1 degree in alignment error, the 2% in transverse sensitivity, and 3% error associated with temperature drift, you should be able to get reasonably close (though magnetic fields in your environment will definitely affect the heading.

In terms of the math itself, the atan2f is from the standard c library that is included (math.h). You can see what standard C libraries Xilinx uses in their Xilinx Standalone Library Documentation. Pi is rounded/estimated to 5 decimal places but that is a common practice to help make the calculations go faster.

Thanks,
JColvin

Link to comment
Share on other sites

Hi @aparna,

This code as is is specific to how we set up the material for the MMC34160PJ present on the Pmod CMPS2.

However, the code present in the spoiler tag from jpeyron that explains the degree() function that uses the arctangent function to convert data from the x and y axes from radians to degrees will be applicable for any magnetometer that measures in radians.

Thanks,
JColvin

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...