TYPE_MAGNETIC_FIELD는 지구 자기장의 강도를 수치로 보여주는 센서로 주변 금속의 강도에 따라 맴돌이 전류가 발생하여

자기장이 영향을 받는 것을 이용해 간단한 금속탐지기 기능을 구현해 봅니다.


지자기장은 지구의 위치마다 달라 20~80정도로 차이가 발생하고 한국은 50정도 입니다.

좀더 성능 좋은 금속탐지기를 만들려면 TYPE_MAGNETIC_FIELD_UNCALIBRATED 센서를 이용해서

원래의 값을 받아와 보정 작업을 진행해야 합니다.



1 자기장 센서


1.1 자기장 센서 이벤트 값


TYPE_MAGNETIC_FIELD 센서가 작동 되면 리턴되는 값으로 다음과 같은 value를 넘겨 주며 단위는 μT(마이크로 테슬라)입니다.

리턴된 값은 센서에서 보내주는 값들을 자체 보정 해서 나온 수치 입니다.


Sensor

 Sensor event data

 표현 값

 측정 단위

 TYPE_MAGNETIC_FIELD

 SensorEvent.values[0]

 x축 지구자장 강도

 μT

 TYPE_MAGNETIC_FIELD

 SensorEvent.values[1]

 y축 지구자장 강도

 μT

 TYPE_MAGNETIC_FIELD

 SensorEvent.values[2]

 z축 지구자장 강도

 μT



2 자기장 센서 프로젝트

 

2.1 신규 프로젝트 생성


안드로이드 스튜디오에서 적당한 이름으로 프로젝트를 하나 생성합니다.



2.2 Layout 작성


activity_main.xml

 

자기장 센서가 보내오는 x, y, z축의 μT값들을 출력할 수 있는 TextView를 작성합니다.

그리고 간략한 금속 탐지 기능을 보여줄 TextView도 하나 생성 합니다.


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Megnetic Value"
        android:layout_marginTop="50dp"
        android:textSize="30dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:id="@+id/tvXaxis"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/tvTitle"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:textSize="25dp"
        android:text="X axis : 0"
        />
    <TextView
        android:id="@+id/tvYaxis"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/tvXaxis"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:textSize="25dp"
        android:text="Y axis : 0"
        />
    <TextView
        android:id="@+id/tvZaxis"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/tvYaxis"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:textSize="25dp"
        android:text="Z axis : 0"
        />
    <TextView
        android:id="@+id/tvMagnetic"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/tvZaxis"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:textSize="25dp"
        android:text="Magnetic : 0"
        />

</android.support.constraint.ConstraintLayout>



2.3 Java Source

 

MainActivity.java


소스를 보면 알겠지만 기존 센서와 동일한 프로세스로 작동이 됩니다.

자세한 설명은 생략 합니다. 기존 센서 예제를 확인 하세요.

onCreate에서 Sensor.TYPE_MAGNETIC_FIELD를 설정 하고 onSensorChanged에서 x, y, z 축의 magnetic 값을 받아와 출력 합니다.


지자기 총량을 구하는 공식은

Math.sqrt((magX * magX) + (magY * magY) + (magZ * magZ))

입니다.


package com.example.desk.sensormagnetic;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements SensorEventListener {

    private SensorManager sensorManager;
    private Sensor magSensor;
    int rotation;
    TextView tvXaxis, tvYaxis, tvZaxis, tvMagnetic;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tvXaxis = (TextView)findViewById(R.id.tvXaxis);
        tvYaxis = (TextView)findViewById(R.id.tvYaxis);
        tvZaxis = (TextView)findViewById(R.id.tvZaxis);
        tvMagnetic = (TextView)findViewById(R.id.tvMagnetic);

        sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        magSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    }

    @Override
    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this, magSensor, SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if(event.sensor ==magSensor) {
            float magX = event.values[0];
            float magY = event.values[1];
            float magZ = event.values[2];
            double magnitude = Math.sqrt((magX * magX) + (magY * magY) + (magZ * magZ));

            tvXaxis.setText("X axis : " + String.format("%.2f", magX));
            tvYaxis.setText("Y axis : " + String.format("%.2f", magY));
            tvZaxis.setText("Z axis : " + String.format("%.2f", magZ));
            tvMagnetic.setText("Magnetic : "  + String.format("%.2f", magnitude) + " \u00B5Tesla");
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
}


µ를 나타내기 위해 사용한 u00B5는 유니코드입니다.

인터넷에서 유니코드를 검색하면 표로 잘 나와있어서 앞자리+윗자리 숫자를 조합해서 사용하면 됩니다.


위키 백과사전에서 조금 뜯어왔습니다.


magnetic field sensor



3. 결과


3.1 결과 화면


프로젝트를 실제 핸드폰에서 테스트한 결과 화면인데요.

책상 위에 놓았을 때 하고 컴퓨터 위에 놓았을 때의 값을 비교해보고

책상 위에서 자석을 위치 했을 때의 값을 비교해 보았습니다.

방구석에 처박혀 있을 때 켜놓고 이리저리 굴러다니며 테스트하면 나름 재미있습니다.


magnetic field sensor

magnetic field sensor



3.2 Source Code

 

 

SensorMagnetic.7z



3.3 APK File


SensorMagnetic.apk


- copy coding -


+ Recent posts