|
|
@@ -0,0 +1,111 @@
|
|
|
+/*
|
|
|
+ HMC5883L Triple Axis Digital Compass. Output for HMC5883L_processing.pde
|
|
|
+ Read more: http://www.jarzebski.pl/arduino/czujniki-i-sensory/3-osiowy-magnetometr-hmc5883l.html
|
|
|
+ GIT: https://github.com/jarzebski/Arduino-HMC5883L
|
|
|
+ Web: http://www.jarzebski.pl
|
|
|
+ (c) 2014 by Korneliusz Jarzebski
|
|
|
+*/
|
|
|
+
|
|
|
+#include <Wire.h>
|
|
|
+#include <HMC5883L.h>
|
|
|
+
|
|
|
+HMC5883L compass;
|
|
|
+
|
|
|
+int previousDegree;
|
|
|
+
|
|
|
+void setup()
|
|
|
+{
|
|
|
+ Serial.begin(9600);
|
|
|
+
|
|
|
+ // Initialize HMC5883L
|
|
|
+ while (!compass.begin())
|
|
|
+ {
|
|
|
+ delay(500);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Set measurement range
|
|
|
+ compass.setRange(HMC5883L_RANGE_1_3GA);
|
|
|
+
|
|
|
+ // Set measurement mode
|
|
|
+ compass.setMeasurementMode(HMC5883L_CONTINOUS);
|
|
|
+
|
|
|
+ // Set data rate
|
|
|
+ compass.setDataRate(HMC5883L_DATARATE_30HZ);
|
|
|
+
|
|
|
+ // Set number of samples averaged
|
|
|
+ compass.setSamples(HMC5883L_SAMPLES_8);
|
|
|
+
|
|
|
+ // Set calibration offset. See HMC5883L_calibration.ino
|
|
|
+ compass.setOffset(0, 0);
|
|
|
+}
|
|
|
+
|
|
|
+void loop()
|
|
|
+{
|
|
|
+ long x = micros();
|
|
|
+ Vector norm = compass.readNormalize();
|
|
|
+
|
|
|
+ // Calculate heading
|
|
|
+ float heading = atan2(norm.YAxis, norm.XAxis);
|
|
|
+
|
|
|
+ // Set declination angle on your location and fix heading
|
|
|
+ // You can find your declination on: http://magnetic-declination.com/
|
|
|
+ // (+) Positive or (-) for negative
|
|
|
+ // For Bytom / Poland declination angle is 4'26E (positive)
|
|
|
+ // Formula: (deg + (min / 60.0)) / (180 / M_PI);
|
|
|
+ float declinationAngle = (2.0 + (28.0 / 60.0)) / (180 / M_PI);
|
|
|
+ heading += declinationAngle;
|
|
|
+
|
|
|
+ // Correct for heading < 0deg and heading > 360deg
|
|
|
+ if (heading < 0)
|
|
|
+ {
|
|
|
+ heading += 2 * PI;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (heading > 2 * PI)
|
|
|
+ {
|
|
|
+ heading -= 2 * PI;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Convert to degrees
|
|
|
+ float headingDegrees = heading * 180/M_PI;
|
|
|
+
|
|
|
+ // Fix HMC5883L issue with angles
|
|
|
+ float fixedHeadingDegrees;
|
|
|
+
|
|
|
+ if (headingDegrees >= 1 && headingDegrees < 240)
|
|
|
+ {
|
|
|
+ fixedHeadingDegrees = map(headingDegrees, 0, 239, 0, 179);
|
|
|
+ } else
|
|
|
+ if (headingDegrees >= 240)
|
|
|
+ {
|
|
|
+ fixedHeadingDegrees = map(headingDegrees, 240, 360, 180, 360);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Smooth angles rotation for +/- 3deg
|
|
|
+ int smoothHeadingDegrees = round(fixedHeadingDegrees);
|
|
|
+
|
|
|
+ if (smoothHeadingDegrees < (previousDegree + 3) && smoothHeadingDegrees > (previousDegree - 3))
|
|
|
+ {
|
|
|
+ smoothHeadingDegrees = previousDegree;
|
|
|
+ }
|
|
|
+
|
|
|
+ previousDegree = smoothHeadingDegrees;
|
|
|
+
|
|
|
+ // Output
|
|
|
+ Serial.print(norm.XAxis);
|
|
|
+ Serial.print(":");
|
|
|
+ Serial.print(norm.YAxis);
|
|
|
+ Serial.print(":");
|
|
|
+ Serial.print(norm.ZAxis);
|
|
|
+ Serial.print(":");
|
|
|
+ Serial.print(headingDegrees);
|
|
|
+ Serial.print(":");
|
|
|
+ Serial.print(fixedHeadingDegrees);
|
|
|
+ Serial.print(":");
|
|
|
+ Serial.print(smoothHeadingDegrees);
|
|
|
+ Serial.println();
|
|
|
+
|
|
|
+ // One loop: ~5ms @ 115200 serial.
|
|
|
+ // We need delay ~28ms for allow data rate 30Hz (~33ms)
|
|
|
+ delay(30);
|
|
|
+}
|