산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

아두이노와 프로세싱으로 실시간 디지털 나침반 만들기

이 아두이노 프로젝트에서는 아두이노, MEMS 마그네토미터, 프로세싱 IDE를 사용해 멋진 나침반을 만드는 방법을 알아보겠습니다. 나침반 시연 비디오입니다:

개요

이 프로젝트에는 지구 자기장을 측정하기 위한 MEMS 마그네토미터, 아두이노 보드, 점퍼 와이어만 필요합니다. 예제로 GY-80 브레이크아웃 보드에 통합된 3축 마그네토미터 HMC5883L을 사용하겠습니다.

나침반 작동 원리

아두이노 부분

먼저 I2C 프로토콜로 아두이노 보드를 통해 센서에서 데이터를 가져옵니다. 그런 다음 센서의 X축과 Y축 값을 사용해 헤딩(방위각)을 계산하고 시리얼 포트를 통해 프로세싱 IDE로 값을 전송합니다. 다음 코드가 이 작업을 수행합니다:

/* 아두이노 나침반
 * by Dejan Nedelkovski,
 * www.HowToMechatronics.com
 */
#include <Wire.h> // I2C 아두이노 라이브러리
#define Magnetometer_mX0 0x03
#define Magnetometer_mX1 0x04
#define Magnetometer_mZ0 0x05
#define Magnetometer_mZ1 0x06
#define Magnetometer_mY0 0x07
#define Magnetometer_mY1 0x08
int mX0, mX1, mX_out;
int mY0, mY1, mY_out;
int mZ0, mZ1, mZ_out;
float heading, headingDegrees, headingFiltered, declination;
float Xm, Ym, Zm;
#define Magnetometer 0x1E // HMC5883의 I2C 7비트 주소
void setup() {
  // 시리얼 및 I2C 통신 초기화
  Serial.begin(115200);
  Wire.begin();
  delay(100);
  Wire.beginTransmission(Magnetometer);
  Wire.write(0x02); // 모드 레지스터 선택
  Wire.write(0x00); // 연속 측정 모드
  Wire.endTransmission();
}
void loop() {
  //---- X축
  Wire.beginTransmission(Magnetometer);
  Wire.write(Magnetometer_mX1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer, 1);
  if(Wire.available() <= 1) { mX0 = Wire.read(); }
  Wire.beginTransmission(Magnetometer);
  Wire.write(Magnetometer_mX0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer, 1);
  if(Wire.available() <= 1) { mX1 = Wire.read(); }
  //---- Y축
  Wire.beginTransmission(Magnetometer);
  Wire.write(Magnetometer_mY1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer, 1);
  if(Wire.available() <= 1) { mY0 = Wire.read(); }
  Wire.beginTransmission(Magnetometer);
  Wire.write(Magnetometer_mY0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer, 1);
  if(Wire.available() <= 1) { mY1 = Wire.read(); }
  //---- Z축
  Wire.beginTransmission(Magnetometer);
  Wire.write(Magnetometer_mZ1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer, 1);
  if(Wire.available() <= 1) { mZ0 = Wire.read(); }
  Wire.beginTransmission(Magnetometer);
  Wire.write(Magnetometer_mZ0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer, 1);
  if(Wire.available() <= 1) { mZ1 = Wire.read(); }
  //---- X축
  mX1 = mX1 << 8;
  mX_out = mX0 + mX1; // 원시 데이터
  // 데이터시트: 0.92 mG/digit
  Xm = mX_out * 0.00092; // 가우스 단위
  // 지구 자기장은 0.25~0.65 가우스 범위이므로 대략 이 값들이 나와야 함
  //---- Y축
  mY1 = mY1 << 8;
  mY_out = mY0 + mY1;
  Ym = mY_out * 0.00092;
  //---- Z축
  mZ1 = mZ1 << 8;
  mZ_out = mZ0 + mZ1;
  Zm = mZ_out * 0.00092;
  // ==============================
  // 헤딩 계산
  heading = atan2(Ym, Xm);
  // 위치에 따른 편각 보정
  // 편각은 https://www.ngdc.noaa.gov/geomag-web/ 에서 확인 가능
  // 내 위치에서는 4.2도 = 0.073 라디안
  declination = 0.073;
  heading += declination;
  // 부호 반전 시 보정
  if(heading < 0) heading += 2 * PI;
  // 편각 추가로 인한 보정
  if(heading > 2 * PI) heading -= 2 * PI;
  headingDegrees = heading * 180 / PI; // 도 단위 헤딩
  // 출력 각도 평활화 / 로우패스 필터
  headingFiltered = headingFiltered * 0.85 + headingDegrees * 0.15;
  // 헤딩 값을 시리얼 포트로 프로세싱 IDE에 전송
  Serial.println(headingFiltered);
  delay(50);
}

MEMS 마그네토미터 작동 원리와 데이터 가져오는 방법에 대한 자세한 내용은 저의 MEMS 센서 튜토리얼을 참조하세요.

프로세싱 IDE 부분

여기서는 먼저 시리얼 포트에서 들어오는 헤딩 값을 수신합니다. 이 방법에 대한 자세한 내용은 저의 아두이노와 프로세싱 튜토리얼을 참조하세요.

나침반은 실제로 이미지이며, 더 정확히 말하면 프로세싱 IDE에 로드된 여러 투명 이미지로 구성됩니다. 이미지는 스케치의 작업 디렉토리에 위치해야 합니다. draw() 섹션에서 image() 함수를 사용해 배경 이미지(선택 사항, 단순 색상 배경도 가능)를 로드합니다. 그런 다음 rotateZ() 함수를 사용해 헤딩 값으로 나침반 이미지를 회전시킵니다. 그 위에 나침반 화살표 이미지를 로드합니다.

프로세싱 IDE 코드는 다음과 같습니다:

/* 아두이노 나침반
 * by Dejan Nedelkovski,
 * www.HowToMechatronics.com
 */
import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;
Serial myPort;
PImage imgCompass;
PImage imgCompassArrow;
PImage background;
String data = "";
float heading;
void setup() {
  size(1920, 1080, P3D);
  smooth();
  imgCompass = loadImage("Compass.png");
  imgCompassArrow = loadImage("CompassArrow.png");
  background = loadImage("Background.png");
  myPort = new Serial(this, "COM4", 115200); // 시리얼 통신 시작
  myPort.bufferUntil('\n');
}
void draw() {
  image(background, 0, 0); // 배경 이미지 로드
  pushMatrix();
  translate(width/2, height/2, 0); // 좌표계를 화면 중앙으로 이동해 회전이 중앙에서 일어나게 함
  rotateZ(radians(-heading)); // Z축 기준 나침반 회전
  image(imgCompass, -960, -540); // 나침반 이미지 로드, 좌표계가 이동했으므로 -960x, -540y(화면 크기 절반)에 이미지 배치
  popMatrix(); // 좌표계를 원래 0,0,0 위치로 복원
  image(imgCompassArrow, 0, 0); // popMatrix()로 인해 rotateZ() 영향을 받지 않는 나침반 화살표 이미지 로드
  textSize(30);
  text("Heading: " + heading, 40, 40); // 화면에 헤딩 값 출력
  delay(40);
}
// 시리얼 포트에서 데이터 읽기 시작
void serialEvent(Serial myPort) {
  data = myPort.readStringUntil('\n'); // 시리얼 포트에서 데이터 읽어 문자열 변수 "data"에 저장
  heading = float(data); // 문자열 값을 float로 변환
}

프로젝트 파일, 이미지, 소스 코드 다운로드:

제조공정

  1. 아두이노로 모니터 앰비라이트(Ambilight) 시스템 직접 만들기
  2. 아두이노로 초음파 부양 장치 만들기: 단계별 가이드
  3. 아두이노, 1Sheeld, IR 제어로 만능 안드로이드 리모컨 만들기
  4. 아두이노와 스마트폰으로 만드는 스마트 전압계 – 초간단 DIY 프로젝트
  5. 아두이노 우노로 정밀 주파수 & 듀티 사이클 측정기 만들기
  6. 아두이노로 만드는 맞춤형 '펀처블' 키보드 버튼: 단계별 가이드
  7. 아두이노 소나 & 프로세싱으로 실시간 거리 측정 및 시각화
  8. 스마트 주차 카운터: 아두이노, 프로세싱, PHP로 실시간 차량 추적
  9. 볼트 IoT와 아두이노 우노로 구현하는 무선 LED 밝기 제어 (PWM 6채널)
  10. 스마트 아두이노 제어 로봇 팔 제작: 쉬운 DIY 튜토리얼