Hi,
I bought this Module: http://www.ebay.de/itm/New-10DOF-9-axis-Attitude-Indicator-L3G4200D-ADXL345-HMC5883L-BMP085-Module-/350646462688?pt=LH_DefaultDomain_0&hash=item51a42868e0#ht_4341wt_1166
I am able to read all sensors via I2C/TWI. So far so good.
With the HMC5883L I have some trouble regarding the values.
I use the library from here (Arduino 1+ Version): https://www.loveelectronics.co.uk/products/140/3-axis-magnetometer---hmc5883-breakout-board which includes an example explained here: https://www.loveelectronics.co.uk/Tutorials/8/hmc5883l-tutorial-and-arduino-library
I get readings but the behavior is a bit strange. I put the IMU flat on the table or floor. When I turn it 360 degrees, the values (or the compass I display via Processing) go 360 degrees too.
But: around 160 of these degrees are done by turning the IMU only about 45 degree. So the compass goes way to fast in 45 degrees and way too slow in the other 315 degrees.
I think I can rule out interference. I put it at different spots and as far away from every magnet or electronic component as possible. I always get the some behavior.
Does someone have an idea on what may be wrong?
Thanks Robert
Arduino Sketch:
#include <Wire.h>
#include <HMC5883L.h>
// Store our compass as a variable.
HMC5883L compass;
// Record any errors that may occur in the compass.
int error = 0;
// Out setup routine, here we will configure the microcontroller and compass.
void setup()
{
// Initialize the serial port.
Serial.begin(115200);
Wire.begin(); // Start the I2C interface.
compass = HMC5883L(); // Construct a new HMC5883 compass.
compass.SetScale(1.3); // Set the scale of the compass. ==> If return is read it returns an error. Stange as the value is correct, also regarding the library.
compass.SetMeasurementMode(Measurement_Continuous); // Set the measurement mode to Continuous
}
void loop()
{
// Retrived the scaled values from the compass (scaled to the configured scale).
MagnetometerScaled scaled = compass.ReadScaledAxis();
// Calculate heading when the magnetometer is level, then correct for signs of axis.
float heading = atan2(scaled.YAxis, scaled.XAxis);
// Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
// Find yours here: http://www.magnetic-declination.com/
// Mine is: 2? 37' W, which is 2.617 Degrees, or (which we need) 0.0456752665 radians, I will use 0.0457
// If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
//float declinationAngle = 0.0457;
//heading += declinationAngle;
// Correct for when signs are reversed.
if(heading < 0)
heading += 2*PI;
// Check for wrap due to addition of declination.
if(heading > 2*PI)
heading -= 2*PI;
// Convert radians to degrees for readability.
float headingDegrees = heading * 180/M_PI;
Serial.println(headingDegrees);
delay(100);
}
Processing Sketch:
import processing.serial.*;
import controlP5.*;
Serial myPort; // Create object from Serial class
ControlP5 cp5;
float angle;
void setup()
{
size(600, 600);
frameRate(20);
smooth();
myPort = new Serial(this, "COM15", 115200);
}
void draw()
{
background(255);
strokeWeight(1);
lineAngle(0, 300, 0, 600);
lineAngle(300, 600, 90, 600);
strokeWeight(3);
lineAngle(300, 300, -angle, 250);
Comm();
}
void lineAngle(int x, int y, float angle, float length)
{
line(x, y, x+cos(radians(angle))*length, y-sin(radians(angle))*length); //==> for Degrees
//line(x, y, x+cos(angle)*length, y-sin(angle)*length); // ==> for Radians
}
public void Comm(){
while (myPort.available () > 0) {
String myString = myPort.readStringUntil(10);
if (myString != null) {
print ("received: ");
print (millis());
print(" - ");
print(myString);
angle = Float.parseFloat(myString);
}
}
}
};