Difference between revisions of "GY-271 HMC5883L 3-Axis Magnetic Electronic Compass Module"

From Wiki
Jump to: navigation, search
(Experimental Procedures for Arduino)
 
Line 68: Line 68:
 
<br>
 
<br>
 
'''Step 2:''' Compile and upload the code.
 
'''Step 2:''' Compile and upload the code.
<pre>
+
<pre>/*
#include <Wire.h>
+
* HMC5883L Demo.
#include <HMC5883L.h>
+
* dipmicro electronics, 2014
HMC5883L compass;
+
*
 +
* Hardware Used:
 +
*
 +
* Arduino UNO or compatible
 +
* GY271 module (dipmicro part DE4196
 +
*  Arduino GND -> GY271/HMC5883L GND
 +
*  Arduino 3.3V -> GY271/HMC5883L VCC
 +
*  Arduino A4 (SDA) -> GY271/HMC5883L SDA
 +
*  Arduino A5 (SCL) -> GY271/HMC5883L SCL
 +
*/
 +
 
 +
#include <Wire.h> //I2C Arduino Library
 +
 
 +
#define HMC5883L_ADDR 0x1E //0011110b, I2C 7bit address of HMC5883
 +
 
 +
bool haveHMC5883L = false;
 +
 
 +
bool detectHMC5883L ()
 +
{
 +
  // read identification registers
 +
  Wire.beginTransmission(HMC5883L_ADDR); //open communication with HMC5883
 +
  Wire.write(10); //select Identification register A
 +
  Wire.endTransmission();
 +
  Wire.requestFrom(HMC5883L_ADDR, 3);
 +
  if(3 == Wire.available()) {
 +
    char a = Wire.read();
 +
    char b = Wire.read();
 +
    char c = Wire.read();
 +
    if(a == 'H' && b == '4' && c == '3')
 +
      return true;
 +
  }
 +
 
 +
  return false;
 +
}
 +
 
 
void setup()
 
void setup()
 
{
 
{
Serial.begin(9600);
+
  //Initialize Serial and I2C communications
Wire.begin();
+
  Serial.begin(9600);
compass = HMC5883L();
+
  Serial.println("GY271 TEST");
compass.SetScale(1.3);
+
  Wire.begin();
  compass.SetMeasurementMode(Measurement_Continuous);
+
  // lower I2C clock http://www.gammon.com.au/forum/?id=10896
 +
  TWBR = 78; // 25 kHz
 +
  TWSR |= _BV (TWPS0); // change prescaler 
 
}
 
}
 +
 
void loop()
 
void loop()
 
{
 
{
MagnetometerRaw raw = compass.ReadRawAxis();
+
  bool detect = detectHMC5883L();
MagnetometerScaled scaled = compass.ReadScaledAxis();
+
 
float xHeading = atan2(scaled.YAxis, scaled.XAxis);
+
  if(!haveHMC5883L)
float yHeading = atan2(scaled.ZAxis, scaled.XAxis);
+
  {
  float zHeading = atan2(scaled.ZAxis, scaled.YAxis);
+
    if(detect)
if(xHeading < 0) xHeading += 2*PI;
+
    {
if(xHeading > 2*PI) xHeading -= 2*PI;
+
      haveHMC5883L = true;
if(yHeading < 0) yHeading += 2*PI;  
+
      Serial.println("We have HMC5883L, moving on");
if(yHeading > 2*PI) yHeading -= 2*PI;
+
      // Put the HMC5883 IC into the correct operating mode
if(zHeading < 0) zHeading += 2*PI;
+
      Wire.beginTransmission(HMC5883L_ADDR); //open communication with HMC5883
  if(zHeading > 2*PI) zHeading -= 2*PI;
+
      Wire.write(0x02); //select mode register
float xDegrees = xHeading * 180/M_PI;
+
      Wire.write(0x00); //continuous measurement mode
float yDegrees = yHeading * 180/M_PI;
+
      Wire.endTransmission();
float zDegrees = zHeading * 180/M_PI;
+
    }
Serial.print(xDegrees);
+
    else
Serial.print(",");
+
    {  
Serial.print(yDegrees);
+
      Serial.println("No HMC5883L detected!");
Serial.print(",");
+
      delay(2000);
Serial.print(zDegrees);
+
      return;
Serial.println(";");
+
    }
delay(100);
+
  }
 +
  else
 +
  {
 +
    if(!detect) {
 +
      haveHMC5883L = false;
 +
      Serial.println("Lost connection to HMC5883L!");
 +
      delay(2000);
 +
      return;
 +
    }
 +
  }
 +
 
 +
  int x,y,z; //triple axis data
 +
 
 +
  //Tell the HMC5883 where to begin reading data
 +
  Wire.beginTransmission(HMC5883L_ADDR);
 +
  Wire.write(0x03); //select register 3, X MSB register
 +
  Wire.endTransmission();
 +
 
 +
  //Read data from each axis, 2 registers per axis
 +
  Wire.requestFrom(HMC5883L_ADDR, 6);
 +
  if(6<=Wire.available()){
 +
    x = Wire.read()<<8; //X msb
 +
    x |= Wire.read(); //X lsb
 +
    z = Wire.read()<<8; //Z msb
 +
    z |= Wire.read(); //Z lsb
 +
    y = Wire.read()<<8; //Y msb
 +
    y |= Wire.read(); //Y lsb
 +
  }
 +
 
 +
  //Print out values of each axis
 +
  Serial.print("x: ");
 +
  Serial.print(x);
 +
  Serial.print(" y: ");
 +
  Serial.print(y);
 +
  Serial.print(" z: ");
 +
  Serial.println(z);
 +
 
 +
  delay(250);
 
}
 
}
 +
 
 
</pre>
 
</pre>
 
The serial monitor shows the results (X plane angle, Y plane angle, Z plane angle in degrees) of different positions of the module.
 
The serial monitor shows the results (X plane angle, Y plane angle, Z plane angle in degrees) of different positions of the module.
 
<br>
 
<br>
 
[[File:GY-271 HMC5883L_4.jpg]]
 
[[File:GY-271 HMC5883L_4.jpg]]
 +
 
=='''Resource'''==
 
=='''Resource'''==
 
[http://wiki.sunfounder.cc/images/a/af/HMC5883L.zip HMC5883L library][[File:LINK.jpg]]<br>
 
[http://wiki.sunfounder.cc/images/a/af/HMC5883L.zip HMC5883L library][[File:LINK.jpg]]<br>

Latest revision as of 08:05, 10 March 2021

Introduction

GY-271 HMC5883L 1.jpg
The Compass Module is designed for low-field magnetic sensing with a digital interface and perfect to give precise heading information. This compact sensor fits into small projects such as UAVs and robot navigation systems. The sensor converts any magnetic field to a differential voltage output on 3 axes. This voltage shift is the raw digital output value, which can then be used to calculate headings or sense magnetic fields coming from different directions.

Main Features

  1. Gold plating PCB, applying machine welding technology, superb technique and reliably quality guarantee!
  2. Name: HMC5883L Module (Triaxial Magnetic Field Module);
  3. Type: GY-271;
  4. Used Chip: HMC5883L;
  5. Power Supply: 3~5V;
  6. Communication Mode: Standard IIC communicating protocol;
  7. Measuring Range: ±1.3-8 Gauss.

Introduction of Pins

Pin Introduction
VCC Connected to the anode of the power supply (3~5v)
GND Connected to the cathode of the power supply
SCL I²C clock
SDA I²C data
DRDY Interrupting pin for data preparation, DRDY is pulled up inside and keeps the low level for 250μsec when the data are on the output register.

Principle

Honeywell HMC5883L is a kind of SMT High integration module that has a weakly magnetic sensor chip with digital interface. It is widely used in testing of low cost compass and magnetic field. HMC5883L contains the latest high resolution HMC118X series magnetoresistive sensor and Honeywell-patent integrated circuit including amplifier, automatic demagnetization driver, deviation calibration and 12-bit A/D converter that can keep the precision of compass ranging within 1°~2°. What’s more, it has simply equipped I2C series bus interfaces. 

GY-271 HMC5883L 2.jpg

Experimental Procedures for Arduino

GY-271 Arduino uno
VCC VCC
GND GND
SCL A5
SDA A4

Step 1: Connect the circuit:
GY-271 HMC5883L 3.jpg


The serial monitor shows the results (X plane angle, Y plane angle, Z plane angle in degrees) of different positions of the module.
Step 2: Compile and upload the code.

/*
 * HMC5883L Demo.
 * dipmicro electronics, 2014
 *
 * Hardware Used:
 * 
 * Arduino UNO or compatible
 * GY271 module (dipmicro part DE4196
 *  Arduino GND -> GY271/HMC5883L GND
 *  Arduino 3.3V -> GY271/HMC5883L VCC
 *  Arduino A4 (SDA) -> GY271/HMC5883L SDA
 *  Arduino A5 (SCL) -> GY271/HMC5883L SCL 
 */

#include <Wire.h> //I2C Arduino Library

#define HMC5883L_ADDR 0x1E //0011110b, I2C 7bit address of HMC5883

bool haveHMC5883L = false;

bool detectHMC5883L ()
{
  // read identification registers
  Wire.beginTransmission(HMC5883L_ADDR); //open communication with HMC5883
  Wire.write(10); //select Identification register A
  Wire.endTransmission();
  Wire.requestFrom(HMC5883L_ADDR, 3);
  if(3 == Wire.available()) {
    char a = Wire.read();
    char b = Wire.read();
    char c = Wire.read();
    if(a == 'H' && b == '4' && c == '3')
      return true;
  }

  return false;
}

void setup()
{
  //Initialize Serial and I2C communications
  Serial.begin(9600);
  Serial.println("GY271 TEST");
  Wire.begin();
  // lower I2C clock http://www.gammon.com.au/forum/?id=10896
  TWBR = 78;  // 25 kHz 
  TWSR |= _BV (TWPS0);  // change prescaler  
}

void loop()
{
  bool detect = detectHMC5883L();

  if(!haveHMC5883L) 
  {
    if(detect) 
    {
      haveHMC5883L = true;
      Serial.println("We have HMC5883L, moving on");
      // Put the HMC5883 IC into the correct operating mode
      Wire.beginTransmission(HMC5883L_ADDR); //open communication with HMC5883
      Wire.write(0x02); //select mode register
      Wire.write(0x00); //continuous measurement mode
      Wire.endTransmission();
    }
    else
    {  
      Serial.println("No HMC5883L detected!");
      delay(2000);
      return;
    }
  }
  else
  {
    if(!detect) {
      haveHMC5883L = false;
      Serial.println("Lost connection to HMC5883L!");
      delay(2000);
      return;
    }
  }
  
  int x,y,z; //triple axis data

  //Tell the HMC5883 where to begin reading data
  Wire.beginTransmission(HMC5883L_ADDR);
  Wire.write(0x03); //select register 3, X MSB register
  Wire.endTransmission();

 //Read data from each axis, 2 registers per axis
  Wire.requestFrom(HMC5883L_ADDR, 6);
  if(6<=Wire.available()){
    x = Wire.read()<<8; //X msb
    x |= Wire.read(); //X lsb
    z = Wire.read()<<8; //Z msb
    z |= Wire.read(); //Z lsb
    y = Wire.read()<<8; //Y msb
    y |= Wire.read(); //Y lsb
  }
  
  //Print out values of each axis
  Serial.print("x: ");
  Serial.print(x);
  Serial.print("  y: ");
  Serial.print(y);
  Serial.print("  z: ");
  Serial.println(z);
  
  delay(250);
}
  

The serial monitor shows the results (X plane angle, Y plane angle, Z plane angle in degrees) of different positions of the module.
GY-271 HMC5883L 4.jpg

Resource

HMC5883L libraryLINK.jpg