Android 自制金属探测仪(磁场传感器应用)

前言:

十年前传感器在智能设备上早已大行其道,迄今为止无论iOS亦或Android设备没有搭载传感器的屈指可数。今天依赖于完善的开发工具以及成熟的传感器技术的应用,我们得以展开一场完全依靠自己的双手开发一款金属探测仪的机会。

一:构思

传感器种类很多,包括温度、亮度、湿度以及磁场等。它们统称为Sensor,由其特有的管理者SensorManager来进行管理使用。当我们想要使用某种传感器,只需将SensorManager获取具体传感器的方法内传入特定参数即可。我们获得磁场传感器的实例应用后,会得到设备在三维空间中面向xyz三个坐标轴的地磁场强度(单位:微特斯拉)。如果说我们的设备处于一个三维环境中,只要任意一轴方向上磁感应强度发生了变化,那么我们就可以判定附近有磁场上的变化,无论xyz三个坐标轴的地磁场强度是否相等。事实上,磁场变化并不是在同一时刻围绕一个物体发生360°的变化,那么我们就可以以任意一轴上的磁感应变化来判断设备附件是否有金属(金属引起物体附近磁场变化)。

二:布局

我们就只创建一个活动,里面放入显示xyz三个坐标轴的地磁场强度 的控件。这里有TextViewProgressBarCircleProgress(第三方控件)。布局结构也非常简单,一个方向向下的线性布局。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Tesla Sensor"
            android:gravity="center"
            android:textSize="24sp"
            android:textStyle="bold"
            android:paddingTop="25dp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/text_view_x"
            android:gravity="center"/>

        <ProgressBar
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/progress_bar_x"
            style="@style/Widget.AppCompat.ProgressBar.Horizontal"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/text_view_y"
            android:gravity="center"/>

        <ProgressBar
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/progress_bar_y"
            style="@style/Widget.AppCompat.ProgressBar.Horizontal"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/text_view_z"
            android:gravity="center"/>

        <ProgressBar
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/progress_bar_z"
            style="@style/Widget.AppCompat.ProgressBar.Horizontal"/>

        <com.ihat.pihat.circleprogress.CircleProgress
            android:id="@+id/circle_progress_x"
            android:layout_width="100dp"
            android:layout_height="100dp"
            app:despText="X Detective"
            app:valueText="None"
            app:valueTextSize="13sp"
            app:despTextSize="07sp"
            app:roundProgressColor="@color/colorPrimaryDark"
            app:valueTextColor="@color/colorAccent"
            app:circleStrokeWidth="2dp"
            android:layout_gravity="center"/>

        <com.ihat.pihat.circleprogress.CircleProgress
            android:id="@+id/circle_progress_y"
            android:layout_width="100dp"
            android:layout_height="100dp"
            app:despText="Y Detective"
            app:valueText="None"
            app:valueTextSize="13sp"
            app:despTextSize="07sp"
            app:roundProgressColor="@color/colorPrimaryDark"
            app:valueTextColor="@color/colorAccent"
            app:circleStrokeWidth="2dp"
            android:layout_gravity="center"
            />

        <com.ihat.pihat.circleprogress.CircleProgress
            android:id="@+id/circle_progress_z"
            android:layout_width="100dp"
            android:layout_height="100dp"
            app:despText="Z Detective"
            app:valueText="None"
            app:valueTextSize="13sp"
            app:despTextSize="07sp"
            app:roundProgressColor="@color/colorPrimaryDark"
            app:valueTextColor="@color/colorAccent"
            app:circleStrokeWidth="2dp"
            android:layout_gravity="center"/>

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

预览如下:
在这里插入图片描述

三:代码:

这里也没什么特别难以理解的地方。onSensorChanged()内是磁场传感器数值发生改变时回调的方法,里面传入我们想要更新的控件的逻辑即可。另外不要忘了注册SensorManager()的监听器,以及及时卸载即可。

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.media.SoundPool;
import android.net.Uri;
import android.os.Bundle;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.ayst.dashboardview.DashboardView;
import com.ihat.pihat.circleprogress.CircleProgress;

public class MainActivity extends AppCompatActivity implements SensorEventListener {

    private SensorManager sensorManager;
    private Sensor sensor;
    private TextView textViewX;
    private TextView textViewY;
    private TextView textViewZ;
    private ProgressBar progressBarX;
    private ProgressBar progressBarY;
    private ProgressBar progressBarZ;
    private SoundPool soundPool;
    
    // Third widget to show a progress information.
    private CircleProgress circleProgressX;
    private CircleProgress circleProgressY;
    private CircleProgress circleProgressZ;

    private void initView(){
        textViewX = (TextView) findViewById(R.id.text_view_x);
        textViewY = (TextView) findViewById(R.id.text_view_y);
        textViewZ = (TextView) findViewById(R.id.text_view_z);
        progressBarX = (ProgressBar) findViewById(R.id.progress_bar_x);
        progressBarY = (ProgressBar) findViewById(R.id.progress_bar_y);
        progressBarZ = (ProgressBar) findViewById(R.id.progress_bar_z);
        circleProgressX = (CircleProgress) findViewById(R.id.circle_progress_x);
        circleProgressY = (CircleProgress) findViewById(R.id.circle_progress_y);
        circleProgressZ = (CircleProgress) findViewById(R.id.circle_progress_z);

    }

    // Init the Sensor and SensorManager, notice the parameter of (Sensor.TYPE_MAGNETIC_FIELD),
    // we get magnetic sensor to use.
    private void initSensor(){
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    }

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

        initView();

        initSensor();

    }

    @Override
    protected void onResume() {
        super.onResume();
        // Register SensorManager listener.
        sensorManager.registerListener(MainActivity.this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
    }


    @Override
    protected void onPause() {
        super.onPause();
        // Unregister SensorManager listener when callback onPause().
        sensorManager.unregisterListener(this);
    }

    /**
     * Notice event is an array to store float values.
     * @param event event[0] for x axis, event[1] for y axis, event[2] for z axis.
     */
    @Override
    public void onSensorChanged(SensorEvent event) {
        textViewX.setText(String.valueOf(event.values[0]));
        progressBarX.setProgress(0 - (int) event.values[0]);
        circleProgressX.setValueText(String.valueOf(event.values[0]));
        circleProgressX.setSweepValue(-event.values[0]);

        textViewY.setText(String.valueOf(event.values[1]));
        progressBarY.setProgress((int) event.values[1]);
        circleProgressY.setValueText(String.valueOf(event.values[1]));
        circleProgressY.setSweepValue(event.values[1]);

        textViewZ.setText(String.valueOf(event.values[2]));
        progressBarZ.setProgress(0 - (int) event.values[2]);
        circleProgressZ.setValueText(String.valueOf(event.values[2]));
        circleProgressZ.setSweepValue(event.values[2]);

    }

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

    }
}

**附:**github 地址 :https://github.com/mcry416/metal_detective

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
简单的金属探测器,能够探测4-5厘米距离处的小硬币。 硬件组件: Arduino nano R3×1个 通用晶体管PNP×1个 LED(通用)×3 滑动开关×1个 按钮开关,推拉式×1个 压电蜂鸣器×1个 锂离子充电电池×2 软件应用程序和在线服务: Arduino IDE 手动工具和制造机: 烙铁(通用) 传统的金属探测器可以找到埋葬物品,并让您大致了解物体的位置 精确定位器使您可以固定对象的位置,挖掘时开一个较小的孔并提取物品。此外,它还可以用作应急响应者使用的手持式金属探测器,对访问控制检查站的人员进行安全检查。 上面描述的设备非常简单,包含一个检测器部分,该检测器部分由晶体管,带绕组和更多无源元件的铁氧体磁芯以及带有信号元件和校准开关的Arduino Nano微控制器组成。 使用金属探测器的方法如下。设备打开,并在几秒钟后按下校准开关。现在设备准备就绪可以检测金属物体。如果将探头靠近金属物体,LED会开始闪烁,并且蜂鸣器会发出间歇性声音。我们离拍摄对象越近,闪烁频率越高。考虑到它是一个非常简单的设备并且不需要任何设置,检测器的灵敏度令人惊讶地良好。在4-5厘米的距离内检测到一个小的金属硬币,在10厘米及以上的距离上检测到较大的金属物体。实际上,其目的是更精确地定位以前使用标准金属探测探测到的物体。Arduino代码取自arduinoprog.ru网站,由FLPROG可视化编程工具制成。 如果我们在黑暗的地方寻找物体,则正面还有一个LED可以照亮环境。按住校准开关5秒钟可以激活该二极管,这同样适用于停用。 该设备由两个串联的锂离子电池供电,功耗极低,待机模式下约为20mA,检测到金属物体时约为40-45mA,因此电池使用寿命非常长。最后,整个组件被组装成一个合适的组件盒子由PVC材料制成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值