Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ void loop()
uint32_t currentX = 0;
uint32_t currentY = 0;
uint32_t currentZ = 0;
double normalizedX = 0;
double normalizedY = 0;
double normalizedZ = 0;
double scaledX = 0;
double scaledY = 0;
double scaledZ = 0;

// This reads the X, Y and Z channels consecutively
// (Useful if you have one or more channels disabled)
Expand All @@ -75,25 +75,29 @@ void loop()
Serial.print("\tZ axis raw value: ");
Serial.println(currentZ);

// The magnetic field values are 18-bit unsigned. The zero (mid) point is 2^17 (131072).
// Normalize each field to +/- 1.0
normalizedX = (double)currentX - 131072.0;
normalizedX /= 131072.0;
normalizedY = (double)currentY - 131072.0;
normalizedY /= 131072.0;
normalizedZ = (double)currentZ - 131072.0;
normalizedZ /= 131072.0;
// The magnetic field values are 18-bit unsigned. The _approximate_ zero (mid) point is 2^17 (131072).
// Here we scale each field to +/- 1.0 to make it easier to convert to Gauss.
//
// Please note: to properly correct and calibrate the X, Y and Z channels, you need to determine true
// offsets (zero points) and scale factors (gains) for all three channels. Futher details can be found at:
// https://thecavepearlproject.org/2015/05/22/calibrating-any-compass-or-accelerometer-for-arduino/
scaledX = (double)currentX - 131072.0;
scaledX /= 131072.0;
scaledY = (double)currentY - 131072.0;
scaledY /= 131072.0;
scaledZ = (double)currentZ - 131072.0;
scaledZ /= 131072.0;

// The magnetometer full scale is +/- 8 Gauss
// Multiply the normalized values by 8 to convert to Gauss
// Multiply the scaled values by 8 to convert to Gauss
Serial.print("X axis field (Gauss): ");
Serial.print(normalizedX * 8, 5); // Print with 5 decimal places
Serial.print(scaledX * 8, 5); // Print with 5 decimal places

Serial.print("\tY axis field (Gauss): ");
Serial.print(normalizedY * 8, 5);
Serial.print(scaledY * 8, 5);

Serial.print("\tZ axis field (Gauss): ");
Serial.println(normalizedZ * 8, 5);
Serial.println(scaledZ * 8, 5);

Serial.println();
delay(100);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,28 +46,32 @@ void loop()
uint32_t rawValueX = 0;
uint32_t rawValueY = 0;
uint32_t rawValueZ = 0;
double normalizedX = 0;
double normalizedY = 0;
double normalizedZ = 0;
double scaledX = 0;
double scaledY = 0;
double scaledZ = 0;
double heading = 0;

// Read all three channels simultaneously
myMag.getMeasurementXYZ(&rawValueX, &rawValueY, &rawValueZ);

// The magnetic field values are 18-bit unsigned. The zero (mid) point is 2^17 (131072).
// Normalize each field to +/- 1.0
normalizedX = (double)rawValueX - 131072.0;
normalizedX /= 131072.0;
// The magnetic field values are 18-bit unsigned. The _approximate_ zero (mid) point is 2^17 (131072).
// Here we scale each field to +/- 1.0 to make it easier to calculate an approximate heading.
//
// Please note: to properly correct and calibrate the X, Y and Z channels, you need to determine true
// offsets (zero points) and scale factors (gains) for all three channels. Futher details can be found at:
// https://thecavepearlproject.org/2015/05/22/calibrating-any-compass-or-accelerometer-for-arduino/
scaledX = (double)rawValueX - 131072.0;
scaledX /= 131072.0;

normalizedY = (double)rawValueY - 131072.0;
normalizedY /= 131072.0;
scaledY = (double)rawValueY - 131072.0;
scaledY /= 131072.0;

normalizedZ = (double)rawValueZ - 131072.0;
normalizedZ /= 131072.0;
scaledZ = (double)rawValueZ - 131072.0;
scaledZ /= 131072.0;

// Magnetic north is oriented with the Y axis
// Convert the X and Y fields into heading using atan2 (Arc Tangent 2)
heading = atan2(normalizedX, 0 - normalizedY);
heading = atan2(scaledX, 0 - scaledY);

// atan2 returns a value between +PI and -PI
// Convert to degrees
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ volatile bool newDataAvailable = true;
uint32_t rawValueX = 0;
uint32_t rawValueY = 0;
uint32_t rawValueZ = 0;
double normalizedX = 0;
double normalizedY = 0;
double normalizedZ = 0;
double scaledX = 0;
double scaledY = 0;
double scaledZ = 0;
double heading = 0;

void setup()
Expand Down Expand Up @@ -97,20 +97,24 @@ void loop()
// The measurement is already complete, we do not need to start a new one
myMag.readFieldsXYZ(&rawValueX, &rawValueY, &rawValueZ);

// The magnetic field values are 18-bit unsigned. The zero (mid) point is 2^17 (131072).
// Normalize each field to +/- 1.0
normalizedX = (double)rawValueX - 131072.0;
normalizedX /= 131072.0;
// The magnetic field values are 18-bit unsigned. The _approximate_ zero (mid) point is 2^17 (131072).
// Here we scale each field to +/- 1.0 to make it easier to calculate an approximate heading.
//
// Please note: to properly correct and calibrate the X, Y and Z channels, you need to determine true
// offsets (zero points) and scale factors (gains) for all three channels. Futher details can be found at:
// https://thecavepearlproject.org/2015/05/22/calibrating-any-compass-or-accelerometer-for-arduino/
scaledX = (double)rawValueX - 131072.0;
scaledX /= 131072.0;

normalizedY = (double)rawValueY - 131072.0;
normalizedY /= 131072.0;
scaledY = (double)rawValueY - 131072.0;
scaledY /= 131072.0;

normalizedZ = (double)rawValueZ - 131072.0;
normalizedZ /= 131072.0;
scaledZ = (double)rawValueZ - 131072.0;
scaledZ /= 131072.0;

// Magnetic north is oriented with the Y axis
// Convert the X and Y fields into heading using atan2 (Arc Tangent 2)
heading = atan2(normalizedX, 0 - normalizedY);
heading = atan2(scaledX, 0 - scaledY);

// atan2 returns a value between +PI and -PI
// Convert to degrees
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ void loop()
uint32_t currentX = 0;
uint32_t currentY = 0;
uint32_t currentZ = 0;
double normalizedX = 0;
double normalizedY = 0;
double normalizedZ = 0;
double scaledX = 0;
double scaledY = 0;
double scaledZ = 0;

// This reads the X, Y and Z channels consecutively
// (Useful if you have one or more channels disabled)
Expand All @@ -77,25 +77,29 @@ void loop()
Serial.print("\tZ axis raw value: ");
Serial.println(currentZ);

// The magnetic field values are 18-bit unsigned. The zero (mid) point is 2^17 (131072).
// Normalize each field to +/- 1.0
normalizedX = (double)currentX - 131072.0;
normalizedX /= 131072.0;
normalizedY = (double)currentY - 131072.0;
normalizedY /= 131072.0;
normalizedZ = (double)currentZ - 131072.0;
normalizedZ /= 131072.0;
// The magnetic field values are 18-bit unsigned. The _approximate_ zero (mid) point is 2^17 (131072).
// Here we scale each field to +/- 1.0 to make it easier to convert to Gauss.
//
// Please note: to properly correct and calibrate the X, Y and Z channels, you need to determine true
// offsets (zero points) and scale factors (gains) for all three channels. Futher details can be found at:
// https://thecavepearlproject.org/2015/05/22/calibrating-any-compass-or-accelerometer-for-arduino/
scaledX = (double)currentX - 131072.0;
scaledX /= 131072.0;
scaledY = (double)currentY - 131072.0;
scaledY /= 131072.0;
scaledZ = (double)currentZ - 131072.0;
scaledZ /= 131072.0;

// The magnetometer full scale is +/- 8 Gauss
// Multiply the normalized values by 8 to convert to Gauss
// Multiply the scaled values by 8 to convert to Gauss
Serial.print("X axis field (Gauss): ");
Serial.print(normalizedX * 8, 5); // Print with 5 decimal places
Serial.print(scaledX * 8, 5); // Print with 5 decimal places

Serial.print("\tY axis field (Gauss): ");
Serial.print(normalizedY * 8, 5);
Serial.print(scaledY * 8, 5);

Serial.print("\tZ axis field (Gauss): ");
Serial.println(normalizedZ * 8, 5);
Serial.println(scaledZ * 8, 5);

Serial.println();
delay(100);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,28 +48,32 @@ void loop()
uint32_t rawValueX = 0;
uint32_t rawValueY = 0;
uint32_t rawValueZ = 0;
double normalizedX = 0;
double normalizedY = 0;
double normalizedZ = 0;
double scaledX = 0;
double scaledY = 0;
double scaledZ = 0;
double heading = 0;

// Read all three channels simultaneously
myMag.getMeasurementXYZ(&rawValueX, &rawValueY, &rawValueZ);

// The magnetic field values are 18-bit unsigned. The zero (mid) point is 2^17 (131072).
// Normalize each field to +/- 1.0
normalizedX = (double)rawValueX - 131072.0;
normalizedX /= 131072.0;
// The magnetic field values are 18-bit unsigned. The _approximate_ zero (mid) point is 2^17 (131072).
// Here we scale each field to +/- 1.0 to make it easier to calculate an approximate heading.
//
// Please note: to properly correct and calibrate the X, Y and Z channels, you need to determine true
// offsets (zero points) and scale factors (gains) for all three channels. Futher details can be found at:
// https://thecavepearlproject.org/2015/05/22/calibrating-any-compass-or-accelerometer-for-arduino/
scaledX = (double)rawValueX - 131072.0;
scaledX /= 131072.0;

normalizedY = (double)rawValueY - 131072.0;
normalizedY /= 131072.0;
scaledY = (double)rawValueY - 131072.0;
scaledY /= 131072.0;

normalizedZ = (double)rawValueZ - 131072.0;
normalizedZ /= 131072.0;
scaledZ = (double)rawValueZ - 131072.0;
scaledZ /= 131072.0;

// Magnetic north is oriented with the Y axis
// Convert the X and Y fields into heading using atan2 (Arc Tangent 2)
heading = atan2(normalizedX, 0 - normalizedY);
heading = atan2(scaledX, 0 - scaledY);

// atan2 returns a value between +PI and -PI
// Convert to degrees
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ volatile bool newDataAvailable = true;
uint32_t rawValueX = 0;
uint32_t rawValueY = 0;
uint32_t rawValueZ = 0;
double normalizedX = 0;
double normalizedY = 0;
double normalizedZ = 0;
double scaledX = 0;
double scaledY = 0;
double scaledZ = 0;
double heading = 0;

void setup()
Expand Down Expand Up @@ -98,20 +98,24 @@ void loop()
// The measurement is already complete, we do not need to start a new one
myMag.readFieldsXYZ(&rawValueX, &rawValueY, &rawValueZ);

// The magnetic field values are 18-bit unsigned. The zero (mid) point is 2^17 (131072).
// Normalize each field to +/- 1.0
normalizedX = (double)rawValueX - 131072.0;
normalizedX /= 131072.0;
// The magnetic field values are 18-bit unsigned. The _approximate_ zero (mid) point is 2^17 (131072).
// Here we scale each field to +/- 1.0 to make it easier to calculate an approximate heading.
//
// Please note: to properly correct and calibrate the X, Y and Z channels, you need to determine true
// offsets (zero points) and scale factors (gains) for all three channels. Futher details can be found at:
// https://thecavepearlproject.org/2015/05/22/calibrating-any-compass-or-accelerometer-for-arduino/
scaledX = (double)rawValueX - 131072.0;
scaledX /= 131072.0;

normalizedY = (double)rawValueY - 131072.0;
normalizedY /= 131072.0;
scaledY = (double)rawValueY - 131072.0;
scaledY /= 131072.0;

normalizedZ = (double)rawValueZ - 131072.0;
normalizedZ /= 131072.0;
scaledZ = (double)rawValueZ - 131072.0;
scaledZ /= 131072.0;

// Magnetic north is oriented with the Y axis
// Convert the X and Y fields into heading using atan2 (Arc Tangent 2)
heading = atan2(normalizedX, 0 - normalizedY);
heading = atan2(scaledX, 0 - scaledY);

// atan2 returns a value between +PI and -PI
// Convert to degrees
Expand Down
41 changes: 26 additions & 15 deletions examples/Example7-I2C_Sensor_Offset/Example7-I2C_Sensor_Offset.ino
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ void setup()

void loop()
{
// The magnetic field values are 18-bit unsigned. The zero (mid) point is 2^17 (131072).
// The magnetic field values are 18-bit unsigned. The _approximate_ zero (mid) point is 2^17 (131072).
// Use static variables to hold the offset. Set to 131072 initially.
static uint32_t offsetX = 131072;
static uint32_t offsetY = 131072;
Expand All @@ -104,25 +104,29 @@ void loop()
myMag.getMeasurementXYZ(&currentX, &currentY, &currentZ);

// The magnetic field values are 18-bit unsigned.
// The zero (mid) point should be 2^17 (131072).
// Here we subtract the offset, then normalize each field to +/- 1.0,
// The _approximate_ zero (mid) point should be 2^17 (131072).
// Here we subtract the offset, then scale each field to +/- 1.0,
// then multiply by 8 to convert to Gauss
double normalizedX = (double)currentX - (double)offsetX; // Convert to double _before_ subtracting
normalizedX /= 131072.0;
normalizedX *= 8.0;
double normalizedY = (double)currentY - (double)offsetY; // Convert to double _before_ subtracting
normalizedY /= 131072.0;
normalizedY *= 8.0;
double normalizedZ = (double)currentZ - (double)offsetZ; // Convert to double _before_ subtracting
normalizedZ /= 131072.0;
normalizedZ *= 8.0;
//
// Please note: to properly correct and calibrate the X, Y and Z channels, you need to determine true
// offsets (zero points) and scale factors (gains) for all three channels. Futher details can be found at:
// https://thecavepearlproject.org/2015/05/22/calibrating-any-compass-or-accelerometer-for-arduino/
double scaledX = (double)currentX - (double)offsetX; // Convert to double _before_ subtracting
scaledX /= 131072.0;
scaledX *= 8.0;
double scaledY = (double)currentY - (double)offsetY; // Convert to double _before_ subtracting
scaledY /= 131072.0;
scaledY *= 8.0;
double scaledZ = (double)currentZ - (double)offsetZ; // Convert to double _before_ subtracting
scaledZ /= 131072.0;
scaledZ *= 8.0;

// Print the three channels with commas in between so the Serial Plotter can plot them
Serial.print(normalizedX, 5); // Print with 5 decimal places
Serial.print(scaledX, 5); // Print with 5 decimal places
Serial.print(",");
Serial.print(normalizedY, 5);
Serial.print(scaledY, 5);
Serial.print(",");
Serial.println(normalizedZ, 5);
Serial.println(scaledZ, 5);
}

bool updateOffset(uint32_t *offsetX, uint32_t *offsetY, uint32_t *offsetZ) // Update the offsets
Expand Down Expand Up @@ -154,6 +158,13 @@ bool updateOffset(uint32_t *offsetX, uint32_t *offsetY, uint32_t *offsetZ) // Up
*offsetX = (setX + resetX) / 2;
*offsetY = (setY + resetY) / 2;
*offsetZ = (setZ + resetZ) / 2;
//Serial.print("Offsets: ")
//Serial.print(*offsetX);
//Serial.print(", ");
//Serial.print(*offsetY);
//Serial.print(", ");
//Serial.print(*offsetZ);
//Serial.println();
}

return success;
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=SparkFun MMC5983MA Magnetometer Arduino Library
version=1.1.1
version=1.1.2
author=SparkFun Electronics
maintainer=SparkFun Electronics
sentence=A I2C/SPI library for the MMC5983MA magnetic compass sensor.
Expand Down