Magnetometer values

Hello,

I’m using the NB-IoT shield on a Arduino ZERO.
I have tried several library’s for the LSM303AGR to get some magnetic values. This however won’t work…

How can i get the Magnetic values?

Hi @Paul93K

We pushed an update to our library

It now includes the magnetometer and some example code.

Kind regards,
Jan

Dear Jan,

The example gives me an error on line 36.
pinMode(MAG_INT, INPUT_PULLDOWN);
The error i get is:'MAG_INT' was not declared in this scope
Only the Accelerometer is on a i2c address in the shield isn’t it?

How can i fix it?

Im using the shield still on a Arduino ZERO.

Jan,

Now you got a magnetosensor library…
Where is the accelerometer library?

i Found it.

Dear @Paul93K

The library if for the LSM303, the library is for both accelerometer and magnetometer.
Example can be found here for the accelerometer: http://support.sodaq.com/sodaq-one/loraone-accelerometer-magnetometer/#LSM303AGR
The interruptpin for the accelerometer is connected to D4

The Magnetometer interrupt pin is not wired to an I/O pin.
You can solder a wire to the interruptpin pad. TP8, see image.

Kind regards,
Jan

Dear Jan,

I don’t need interrupts yet, the library works and i get all the numbers now.
However when i want to use the magnetovalues to calculate the degrees, i get really weird numbers…
With all the formula i use.
The values i get from the Magnetometer, do i need to do something to them before i can get the degrees?

Is it true that the values are the magnetic values?
If this is so, how do i get this to degrees?

	 getX: 0.04	 getY: -0.10	 getZ: 0.99	 getMagX: -18.00	 getMagY: -372.00	 getMagZ: -748.50

Hello,

Im trying to get North, East, South, West out of the Magnetometer.
I’m using the Arduino ZERO + NB-IoT shield, with Sodaq_LSM303AGR library.
The code i use is:

Init Magnetometer:

void initAccMagSensor(int8_t timer, int16_t timeout) {
accMagSensor = new Sodaq_LSM303AGR();
accMagSensor->rebootAccelerometer();
delay(timeout);
accMagSensor->rebootMagnetometer();
delay(timeout);
accMagSensor->enableAccelerometer(accMagSensor->HighResMode,accMagSensor-HrNormalLowPower100Hz, accMagSensor->XYZ, accMagSensor->Scale2g);
accMagSensor->enableMagnetometer(accMagSensor->MagHighResMode,accMagSensor-Hz100,accMagSensor->Continiuous);
delay(timer);
}

For getting the Axes:

double getMXAs() {
	return accMagSensor->getMagX();
}
double  getMYAs() {
	return accMagSensor->getMagY();
}
double getMZAs() {
	return accMagSensor->getMagZ();
}

I’ll get the average of 10 samples to get stabe numbers with the next code:

double middleAxes(String type, int8_t factor) {
double middle = 0;
for (int i = 0; i < (factor-1); i++) {
if (type.equals(“axas”)) {
middle += getAXAs();
} else if (type.equals(“ayas”)) {
middle += getAYAs();
} else if (type.equals(“azas”)) {
middle += getAZAs();
} else if (type.equals(“mxas”)) {
middle += getMXAs();
} else if (type.equals(“myas”)) {
middle += getMYAs();
} else if (type.equals(“mzas”)) {
middle += getMZAs();
}
}
return middle / factor;
}

Next up, I’m calculating the degrees with this code (this is done with the blog found on: https://blog.digilentinc.com/how-to-convert-magnetometer-data-into-compass-heading/):

int32_t getDegrees(){
float heading = 0;
double xGaussData = middleAxes(“mxas”, middleFactor);
double yGaussData = middleAxes(“myas”, middleFactor);
xGaussData *= 0.48828125;
yGaussData = 0.48828125;
if (xGaussData == 0 && yGaussData < 0){
heading = 90;
} else if (yGaussData >= 0){
heading = 0;
} else if (xGaussData != 0) {
heading = atan(yGaussData/xGaussData)
(180/PI);

  if (heading > 360){
  	heading = heading - 360;
  }
  if (heading < 0){
  	heading = heading + 360;
  }

}

DEBUG_STREAM.println("\t heading: " + String(heading));
getCourse(heading);
return 0;
}

To get a string out of the degrees i use the next code:

void getCourse(float heading){
String Course;
if (heading > 337.25 || heading < 22.5){
Course = “North”;
} else if (heading > 292.5 && heading < 337.25) {
Course = “North-West”;
} else if (heading > 247.5 && heading < 292.5) {
Course = “West”;
} else if (heading > 202.5 && heading < 247.5) {
Course = “South-West”;
} else if (heading > 157.5 && heading < 202.5) {
Course = “South”;
} else if (heading > 112.5 && heading < 157.5) {
Course = “South-East”;
} else if (heading > 67.5 && heading < 112.5) {
Course = “East”;
} else if (heading > 0 && heading < 37.5) {
Course = “North-East”;
}
DEBUG_STREAM.println("\t Course: " + Course);
}

The result i get is not what you should expect,
By what should be 0 degrees:

getMagX: -229.50	 getMagY: -6.00	 getMagZ: -720.00	 heading: 1.61
	 Course: North

By what should be 90 degrees:

getMagX: 48.00 getMagY: -180.00 getMagZ: -711.00 heading: 286.24
Course: West

By what should be 180 degrees:

getMagX: -121.50 getMagY: -447.00 getMagZ: -738.00 heading: 75.56
Course: East

By what should be 270 degrees:

getMagX: -412.50 getMagY: -270.00 getMagZ: -733.50 heading: 33.12
Course: North-East

Like you see above this is nothing like it should be,
What im doing wrong?

Thanks in advance,
Paul

Dear Jan,

The example gives me the same error as Paul on line 36.
pinMode(MAG_INT, INPUT_PULLDOWN);
The error i get is:‘MAG_INT’ was not declared in this scope

Because I didn’t find a clear answer about this on this stream, may I ask you to share some more information about the resolution of this error? I install the library LSM303AGR but this doesn’t change anything. I’m using a Sodaq One V3 board.

Many thanks for your kind answer,
Thierry

Dear @Thierry_Hustin,

We added the MAG_INT at a later stage to the boardfiles.
Can you update to the latest boardfiles?
And make sure you use the new SAND url

See: https://support.sodaq.com/sodaq-one/arduino-ide-setup/

Best regards,
Jan

Hello Jan,

Thanks a lot, I’ll try (this WE) and come back with the result.

Kind regards,
Thierry

1 Like