본문 바로가기
아두이노

3축 지자기장(자이로)센서 GY-273 HMC5883L 제대로 작동하지 않는다면

by 구루가 되고픈 2019. 1. 11.

3축 지자기장(자이로) 센서 GY-273 HMC5883L이 제대로 작동하지 않는다면

 

 

 

아두이노 우노에 연결한 HMC5883L 센서

 

 

아두이노로 구상하고 있는 프로젝트가 있어 몇가지 부품을 구입하면서 3축 자기장 센서인 HMC5883L을 구입하였습니다.

 

I2C통신방식이라 회로는 워낙 간단해서 브레드보드에 회로구성 후에 기본코드를 넣고 컴파일해서 업로딩 후에 시리얼 모니터로 결과를 확인했는데....

 

어라 x, y, z값이 바뀌어야 하는데 안바뀝니다.

 

컴파일과 업로드는 문제가 없었고, 그리고 기본코드는 이미 검증된 것인데 뭐가 문제일지.....

 

 

/*
An Arduino code example for interfacing with the HMC5883
 
by: Jordan McConnell
SparkFun Electronics
created on: 6/30/11
license: OSHW 1.0, http://freedomdefined.org/OSHW
 
Analog input 4 I2C SDA
Analog input 5 I2C SCL
*/
 
#include <Wire.h> //I2C Arduino Library
 
#define address 0x1E //0011110b, I2C 7bit address of HMC5883
 
void setup(){
  //Initialize Serial and I2C communications
  Serial.begin(9600);
  Wire.begin();
 
  //Put the HMC5883 IC into the correct operating mode
  Wire.beginTransmission(address); //open communication with HMC5883
  Wire.send(0x02); //select mode register
  Wire.send(0x00); //continuous measurement mode
  Wire.endTransmission();
}
 
void loop(){
 
  int x,y,z; //triple axis data
 
  //Tell the HMC5883 where to begin reading data
  Wire.beginTransmission(address);
  Wire.send(0x03); //select register 3, X MSB register
  Wire.endTransmission();
 
//Read data from each axis, 2 registers per axis
  Wire.requestFrom(address, 6);
  if(6<=Wire.available()){
    x = Wire.receive()<<8; //X msb
    x |= Wire.receive(); //X lsb
    z = Wire.receive()<<8; //Z msb
    z |= Wire.receive(); //Z lsb
    y = Wire.receive()<<8; //Y msb
    y |= Wire.receive(); //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);
} 

 

 

일단 I2C 인터페이스 센서들이 제대로 작동을 안할땐 주소값부터 체크해 봐야겠죠

 

IIC Scanner로 주소값부터 체크해봅니다.

 

 

I2C 스캐너로 주소값 확인

 

 

어라 주소가 0x0D가 나오네요.

 

다시 구글링해보니 이 자기장 센서는 0x1E에 주소가 고정되어 있다는데 왜 주소가 다르지?

 

일단 코드상에서 주소를 0x0D로 바꿔서 업로드 후 시리얼 모니터로 값을 살펴봅니다.

 

어라 값이 안나오네, 주소를 바꿔주긴 했으나 주소만의 문제는 아니었네요.

 

 

그래서 본격적으로 구글링에 들어갑니다.

 

구글링을 해보니 저 같은 문제를 외국친구들도 다수 경험하고 있는것 같았습니다.

 

https://forum.arduino.cc/index.php?topic=498793.0

 

위 링크로 들어가 보시면 의견들을 주고받고는 있으나 딱히 답은 없는듯 합니다.

 

계속 파다보니 일단 제가 구매한 이 제품은 정품이 아니란걸 알게 되었습니다.

 

정품과 칩셋 번호가 다릅니다.

 

정품은 L883으로 인쇄되어 있는데, 이건 5883으로 흐릿하게 인쇄가 되어 있네요.

 

아무튼 정품이 아니더라도 작동을 하니까 팔았겠지란 마음으로 상당히 많은 페이지를 뒤집니다.

 

그리고 드디어 찾았습니다.

 

일단 정답이 있는 페이지는 아래 링크입니다.

 

https://core-electronics.com.au/hmc5883l-triple-axis-compass-magnetometer-sensor-module.html

 

링크로 들어가보면 일단 반가운 사진이 뜹니다.

 

 

두 센서 비교 (칩셋이 다름을 알수 있음)

 

 

이 페이지에서 제공하고 있는 정품과 가품의 비교사진입니다.

 

설명을 보니 이 저가의 센서는 중국산 클론 제품으로 QMC5883이라고 설명하고 있습니다.

 

칩셋이 다르다보니 코드가 실행되어도 원하는 데이터값이 나오지 않는것 같습니다.

 

이 페이지에서 데이터쉬트와 라이브러리, 샘플코드까지 친절히 제공하고 있습니다.

 

 

 

 

github에서 적합한 라이브러리를 다운로드

 

 

게다가 한글 설명까지 있네요. 

 

고마우신분들....

 

헤더파일을 보니 정확히 주소가 0x0D로 선언되어 있습니다.

 

 

 

 

바로 라이브러리를 다운받아 설치하고 아래 샘플코드를 설치하고 돌려봅니다.

 

 

#include <Wire.h>
#include <MechaQMC5883.h>


MechaQMC5883 qmc;


void setup() {
  Wire.begin();
  Serial.begin(9600);
  qmc.init();
  //qmc.setMode(Mode_Continuous,ODR_200Hz,RNG_2G,OSR_256);
}


void loop() {
  int x,y,z;
  qmc.read(&x,&y,&z);


  Serial.print("x: ");
  Serial.print(x);
  Serial.print(" y: ");
  Serial.print(y);
  Serial.print(" z: ");
  Serial.print(z);
  Serial.println();
  delay(100);

 

 

그런데 코드가 정말 간결합니다.

 

오히려 정품 센서보다 코드가 간결한건 뭔 매력이죠. ㅎㅎ

 

코드는 간결하지만 결과는 잘 나와주고 있습니다.

 

 

센서값 모니터링

 

 

 

그런데 측정되는 센서값이 정확하진 않습니다.

 

센서를 수평에 맞춰도 약간은 치우친것처럼 값이 나오네요.

 

이건 적당히 프로그램으로 보정해줘야할것 같습니다.

 

그래도 아주 정밀한 작업이 아닌경우를 제외하고는 사용하기에는 무리가 없어 보입니다.

 

이상 GY-273 3축 지자기장(자이로)센서 테스트와 트러블 슈팅이었습니다.