아두이노에 자력계를 설정하는 방법
자기계측기는 하나 이상의 축을 따라 자기장을 측정합니다. 자기계측기를 사용하면 아두이노를 디지털 나침반으로 만들 수 있습니다. 원격 조종 차량의 내비게이션 및 안내 시스템에 매우 유용하며, 전선의 전류를 감지하는 데에도 사용할 수 있습니다.
이 글에서는 아두이노를 이용해 디지털 나침반을 만들기 위해 자력계를 사용하는 방법을 알아보겠습니다. 하지만 그 전에 한 가지 주의할 점이 있습니다.
아두이노용 자력계 중 가장 잘 알려진 것은 HMC5883L입니다. 이 글을 작성하기 위해 eBay에서 HMC5883L을 찾아 주문했는데, 아무리 시도해도 작동하지 않았습니다. 나중에 알고 보니 제가 구매한 자력계는 HMC5883L 이라고 표기되어 있었지만 실제로는 QMC5883L이었습니다 .
HMC5883L용으로 작성된 라이브러리는 QMC5883L과 호환되지 않습니다. 따라서 온라인에서 자력계를 구매할 때는 HMC5883L이 아니라 QMC5883L일 가능성이 높다는 점을 유념해야 합니다. HMC5883L에 대한 튜토리얼은 이미 온라인에 많이 있으므로, 이 글에서는 QMC5883L 자력계를 설정하고 프로그래밍하는 방법을 살펴보겠습니다.

QMC5883L 자력계 개요
QMC5883L은 Vcc, 접지, SCL, SDA, DRDY의 5개 핀을 가지고 있습니다.

QMC5883L 핀 다이어그램
센서 칩은 기판 상단에 있습니다. 자력계 및 기타 방향 센서에는 화살표가 표시되어 있습니다. 이 화살표는 PCB에 대한 센서의 방향을 나타냅니다. 이 자력계는 x, y, z 세 축의 자기장을 감지합니다. z축은 x축과 y축에 수직으로 위아래 방향을 가리킵니다.
QMC5883L 자력계를 아두이노에 연결하는 방법
QMC5883L은 I2C 통신을 사용하여 아두이노와 연결하므로 데이터선 두 개와 전원선 두 개만 있으면 됩니다.
다음과 같이 자력계를 아두이노에 연결하세요:

QMC5883L 배선도
아두이노에서 QMC5883L 자력계를 프로그래밍하는 방법
설명에는 아래 라이브러리를 따라하라고 나왔지만,
Sunfounder에서 제공하는 라이브러리를 사용하여 자력계를 프로그래밍하겠습니다. 이 웹페이지 의 리소스 섹션에서 해당 라이브러리를 다운로드하세요 . 라이브러리를 다운로드하고 설치한 후, 아래 코드를 아두이노에 업로드하십시오.
라이브러리 매니저에서 검색해서 알아보니 아래처럼 나온다. 이론적인 방법을 알려는 목적이니 알아서 프로그래밍한다.

이 프로그램은 자력계의 각 축에서 얻은 원시 값을 시리얼 모니터로 출력합니다.
#include <Wire.h>
#include <QMC5883L.h>
QMC5883L compass;
void setup() {
Wire.begin();
Serial.begin(9600);
compass.init();
}
void loop() {
int x, y, z;
compass.read(&x, &y, &z);
Serial.print("x: ");
Serial.print(x);
Serial.print(" y: ");
Serial.print(y);
Serial.print(" z: ");
Serial.println(z);
delay(250);
}
코드 설명
자력계가 I2C를 사용하므로 Wire 라이브러리를 포함해야 합니다. 또한 QMC5883L 라이브러리도 포함해야 합니다. 다음으로 라이브러리의 함수에 접근할 수 있도록 QMC5883L 클래스의 멤버인 compass 객체를 생성합니다.
setup() 섹션에서 Wire.begin()으로 I2C 인터페이스를 초기화합니다. 그런 다음 시리얼 모니터를 초기화하고 QMC5883L 클래스의 init() 함수로 compass 객체를 초기화합니다.
loop() 섹션에서는 몇 가지 int 변수를 선언해야 합니다. QMC5883L은 각 축별로 별도의 자기장 측정값을 출력합니다. 따라서 x, y, z 축별로 변수를 선언하겠습니다. 이제 센서에서 측정값을 가져올 수 있습니다.
QMC5883L 라이브러리에는 센서 값을 읽어오는 read() 함수가 있습니다. read() 함수는 세 개의 매개변수를 받습니다. 첫 번째 매개변수는 센서의 x축 측정값을 저장할 변수입니다. 두 번째 매개변수는 y축 측정값을 저장할 변수입니다. 세 번째 매개변수는 z축 측정값을 저장할 변수입니다.
이제 x, y, z 변수를 시리얼 모니터에 출력하기만 하면 됩니다. 따라서 x, y, z 변수를 출력하기 위한 일련의 Serial.print() 함수를 사용합니다. 루프 끝에서는 출력을 약간 늦추기 위해 250밀리초 동안 지연합니다.
자기계측기가 연결되고 코드가 아두이노에 업로드되면 시리얼 모니터를 여세요.

QMC5883L 아두이노 시리얼 모니터의 원시 데이터 출력
여기 표시된 원시 값은 각 축을 따라 측정된 자기장의 크기(단위: 마이크로테슬라)입니다.
막대 자석을 가지고 있다면, 자석의 북극을 x축 앞에 놓으면 x값이 크게 감소하는 것을 확인할 수 있습니다. 자석을 y축과 z축 앞에 놓으면 값이 마찬가지로 감소할 것입니다.
하지만 자석이 없어도 센서는 지구의 자기장을 감지할 만큼 충분히 민감합니다. 이제 이 측정값을 활용하여 나침반 방향을 구해 보겠습니다.
QMC5883L과 아두이노를 이용해 디지털 나침반 만드는 방법
자기장은 다양한 원인에 의해 생성됩니다. 도선을 통해 흐르는 전류(I)는 자기장(B)을 생성합니다.

도선 주변의 자기장
하지만 여러분이 가장 잘 알고 있는 자기장은 지구의 철 핵이 만들어내는 자기장일 것입니다.

자석이 있는 지구 자기장 선
지구의 자기장은 지구 전체를 둘러싸고 있으며, 이 덕분에 우리는 나침반을 항해 도구로 사용할 수 있습니다.
진북 vs 자북
지도에서 보이는 북쪽 방향은 지구 자전축과 일치하는 진북을 가리킵니다.

지도상의 진북과 지구 자전축의 차이
진북은 북극을 정확히 가리킵니다. 하지만 나침반은 지구 자전축의 북극이 아니라 지구 자기장의 북극을 가리킵니다.

지구의 북극과 나침반의 북쪽 방향
현재 자북극은 진북극에서 약 310마일 떨어져 있습니다. 즉, 우리가 항해에 사용하는 북쪽 방향과 나침반 바늘이 가리키는 북쪽 방향이 다르다는 뜻입니다. 이 두 방향의 차이를 자기편각이라고 합니다.

자북과 진북, 자편차 화살표 포함
나침반의 편각은 지구상의 위치에 따라 달라집니다. 진북에서 최대 15도까지 차이가 날 수 있습니다. 나침반의 북쪽 방향을 지도상의 북쪽과 연관시키려면 나침반의 방위각에 편각을 더하면 됩니다.
아두이노 QMC5883L 나침반용 코드
아래 스케치는 각 축에서 자력계 측정값을 받아 나침반 방향을 도 단위로 출력합니다. 또한 북, 남, 동, 서의 방위도 표시합니다. 자력계를 연결한 후, 이 코드를 아두이노에 업로드하세요.
#include <Wire.h>
#include <QMC5883L.h>
QMC5883L compass;
void setup() {
Wire.begin();
Serial.begin(9600);
compass.init();
}
void loop() {
int x, y, z;
String cardinal;
compass.read(&x, &y, &z);
float headingRadians = atan2(y, x);
float headingDegrees = headingRadians * 180 / PI;
float declinationAngle = 11.41666666666667;
headingDegrees += declinationAngle;
if (headingDegrees < 0) {
headingDegrees += 360;
}
if (headingDegrees > 348.75 || headingDegrees < 11.25) {
cardinal = " N";
}
else if (headingDegrees > 11.25 && headingDegrees < 33.75) {
cardinal = " NNE";
}
else if (headingDegrees > 33.75 && headingDegrees < 56.25) {
cardinal = " NE";
}
else if (headingDegrees > 56.25 && headingDegrees < 78.75) {
cardinal = " ENE";
}
else if (headingDegrees > 78.75 && headingDegrees < 101.25) {
cardinal = " E";
}
else if (headingDegrees > 101.25 && headingDegrees < 123.75) {
cardinal = " ESE";
}
else if (headingDegrees > 123.75 && headingDegrees < 146.25) {
cardinal = " SE";
}
else if (headingDegrees > 146.25 && headingDegrees < 168.75) {
cardinal = " SSE";
}
else if (headingDegrees > 168.75 && headingDegrees < 191.25) {
cardinal = " S";
}
else if (headingDegrees > 191.25 && headingDegrees < 213.75) {
cardinal = " SSW";
}
else if (headingDegrees > 213.75 && headingDegrees < 236.25) {
cardinal = " SW";
}
else if (headingDegrees > 236.25 && headingDegrees < 258.75) {
cardinal = " WSW";
}
else if (headingDegrees > 258.75 && headingDegrees < 281.25) {
cardinal = " W";
}
else if (headingDegrees > 281.25 && headingDegrees < 303.75) {
cardinal = " WNW";
}
else if (headingDegrees > 303.75 && headingDegrees < 326.25) {
cardinal = " NW";
}
else if (headingDegrees > 326.25 && headingDegrees < 348.75) {
cardinal = " NNW";
}
Serial.print("Heading: ");
Serial.print(headingDegrees);
Serial.println(cardinal);
delay(250);
}
코드 설명
스케치는 첫 번째 스케치와 동일한 방식으로 시작됩니다. Wire 라이브러리와 QMC5883L 라이브러리를 포함시킨 후 나침반 객체를 생성합니다. 그런 다음 I2C 인터페이스를 초기화하고, 시리얼 모니터를 초기화하며, 자력계를 초기화합니다.
loop() 섹션에서는 각 축(x, y, z)에 대한 로컬 int 변수를 선언합니다. 스케치 후반부에 각도 단위의 방향을 기본 방위(cardinal direction)로 변환할 예정이므로, 기본 방위 값을 저장하기 위해 'cardinal'이라는 String 객체를 생성합니다.
다음으로 compass.read()를 사용하여 각 축의 자력계 측정값을 얻고, 해당 값을 x, y, z 변수에 저장합니다.
x, y, z 축척이 어떻게 각도로 변환되는지 알아보려면 나침반 그림을 살펴보겠습니다. 모든 나침반에서 북쪽은 0°, 동쪽은 90°, 남쪽은 180°, 서쪽은 270°입니다.

방위와 각도가 표시된 단위 원
센서의 x축을 이동하고자 하는 방향으로 향하게 하면 다음과 같습니다.

센서의 X축이 있는 단위 원
북쪽 0°와 x축이 가리키는 방향 사이에 각도가 형성됩니다.

센서의 X축과 각도 화살표가 있는 단위 원
센서의 x축과 y축이 단위원을 이룬다고 생각하면 북쪽 방향 화살표는 x축 성분과 y축 성분을 가지고 있음을 알 수 있습니다.

X축과 Y축 성분이 있는 단위 원
x 성분은 자력계의 x축 출력값을 마이크로테슬라 단위로 나타낸 것이고, y 성분은 자력계의 y축 출력값을 마이크로테슬라 단위로 나타낸 것입니다.
0° 북쪽과 센서의 x축 사이의 각도는 atan2()라는 삼각함수로 구할 수 있습니다. atan2() 함수는 센서의 x 및 y 출력값의 절대값을 입력으로 받아 라디안 단위의 각도를 반환합니다. 이는 라디안 단위의 방향 각도입니다:

Heading 있는 단위 원
위 스케치의 loop() 섹션에서, x축과 y축 값을 사용한 atan2() 함수의 출력을 저장하기 위해 headingRadians라는 부동 소수점 변수를 선언합니다. 다음으로 라디안을 각도로 변환하기 위해 float headingDegrees = headingRadians * 180 / PI 공식을 사용합니다. 결과값은 headingDegrees라는 또 다른 부동소수점 변수에 저장됩니다. 이제 센서의 x축이 북쪽을 기준으로 0°에서 가리키는 각도를 얻었습니다.
나침반 측정값에 자기편차를 더하는 방법
이제 자기편각을 추가해야 합니다. 현재 위치의 자기편각을 알아보려면 www.magneticdeclination.com 을 방문하세요 .
자기 편각은 각도와 분 단위로 제공되므로, 분 값을 각도로 변환하여 각도 값에 더해야 합니다. 분은 단순히 각도의 일부입니다. 1도에는 60분이 있습니다. 분 값을 60으로 나누어 분수 형태의 각도 성분을 구한 후, 이를 각도 값에 더하기만 하면 됩니다. 계산된 자기 편각을 'float declinationAngle ='이라고 표시된 줄에 입력하세요.
다음 줄에서는 headingDegrees 변수를 가져와 복합 덧셈 연산자를 사용하여 편각을 더합니다. 이제 자기 편각을 고려하여 조정된 각도 단위의 항로를 얻었습니다. 하지만 atan2() 함수에는 한 가지 특이점이 있습니다. 이 함수는 0°에서 180° 사이, 또는 0°에서 -180° 사이의 각도만 반환합니다:

atan2 출력 (도 포함)
이 상황에서 북쪽은 여전히 0°이고 동쪽은 여전히 90°입니다. 하지만 서쪽은 이제 -90°이고 남쪽은 +180° 또는 -180°입니다. 센서의 x축이 남서쪽을 가리키면 출력값은 atan2()-135°가 됩니다.

X축이 남서쪽을 가리키는 이미지
그러나 나침반에서는 이 방향이 225°가 됩니다. 따라서 headingDegrees 값을 나침반과 마찬가지로 0°에서 360° 사이의 값으로 변환해야 합니다. 이를 위해 필요한 것은 값이 0보다 작을 때 방향에 360°를 더하는 것뿐입니다. 이를 if 문으로 처리합니다. if 문은 "헤딩 각도가 0보다 작을 경우, 헤딩 각도 변수에 360°를 더하는 복합 연산을 수행하라"고 지시합니다. 다음 다이어그램으로 시각화하면 이해가 더 쉽습니다:

X축이 225도입니다
360°에 -135°를 더하면 각도가 225°가 되며, 위치는 변하지 않음을 알 수 있습니다. 따라서 이 시점에서 센서는 x축이 가리키는 방향에 따라 0°부터 360° 사이의 각도를 출력합니다.
방향을 각도로 알 수 있는 것도 좋지만, 나침반은 방위도 알려줍니다.

나침반 상세도
이 나침반에 방위각과 동서남북 방향을 표시하도록 만들어 봅시다. 그러기 위해서는 나침반을 여러 각도 범위로 나누어야 합니다.

나침반 (도 범위 표시)
일련의 if 및 else if 문을 사용하여 방향이 해당 각도 범위 내에 있을 때 방위 방향을 표시합니다. 먼저 "헤딩 각도가 348.75°보다 크거나 11.25°보다 작은 경우, 방위 방향을 북쪽을 나타내는 문자 N으로 설정한다"는 if 문으로 시작합니다.
그런 다음 일련의 else if 문으로 "헤딩 각도가 11.25°보다 크고 33.75°보다 작으면, 방위를 북북동(NNE)으로 설정한다"고 정의합니다. 각 방위별로 동일한 작업을 수행합니다.
각 방위별 각도 범위를 정의한 후 Serial.print(headingDegrees)와 Serial.println(cardinal)로 결과를 시리얼 모니터에 출력합니다. 루프 다음 실행 시 출력이 새 줄로 넘어가도록 하려면 줄바꿈이 필요한 위치에 Serial.println()을 사용합니다. 이후 출력 속도를 약간 늦추기 위해 250밀리초 지연을 추가합니다.
자력계가 아두이노에 연결되면 위 스케치를 업로드하고 시리얼 모니터를 엽니다. 각도 단위의 방향과 방위 방향이 출력되는 것을 확인할 수 있습니다:
자기계측기를 아두이노에 연결한 후, 위의 스케치를 업로드하고 시리얼 모니터를 여세요. 그러면 방향(도)과 방위(동서남북)가 출력되는 것을 볼 수 있습니다.

아두이노 QMC5883L 디지털 나침반 출력 (시리얼 모니터)
짐작하시겠지만, 자력계는 정말 유용한 센서입니다. 원격 조종 차량이 있다면, 자력계의 방향 정보를 이용해 차량의 이동 방향을 제어할 수 있습니다. 또는 풍향계 에 연결하여 바람이 부는 방향을 감지할 수도 있습니다.
읽어주셔서 감사합니다! 궁금한 점이 있으면 아래에 댓글을 남겨주세요.
이 튜토리얼의 원문 자료는 이 링크를 따라가세요.
'아두이노우노 R4' 카테고리의 다른 글
| 아두이노 UNO R4 WIFI를 사용하여 IoT 스마트 그리드를 구축하는 방법 (0) | 2026.04.09 |
|---|---|
| DIY 아두이노 휴대용 게임 콘솔 (레트로 게임 10개 포함) (0) | 2026.03.25 |
| 아두이노 나노 매터 보드는 전문가용 제피어 개발 플랫폼이 되었습니다. (0) | 2026.03.17 |
| 아두이노와 ADXL345 가속도계 방향 추적 3D 시각 (0) | 2026.02.17 |
| 아두이노 IDE에서 ATtiny85 프로그래밍 마스터 1 (1) | 2026.02.16 |
| LDR 및 서보 모터를 사용한 2축 태양광 추적기 아두이노 프로젝트 (0) | 2026.02.14 |
| 아두이노 OLED 메뉴 디스플레이 (2) | 2026.02.03 |
| 아두이노와 3-디스플레이 OLED 시계 (0) | 2026.02.03 |
취업, 창업의 막막함, 외주 관리, 제품 부재!
당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약,
아이디어는 있지만 구현할 기술이 없는 막막함.
우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.
이제 고민을 멈추고, 캐어랩을 만나세요!
코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.
제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!
귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.
캐어랩