磁传感器
磁传感器是把磁场、电流、应力应变、温度、光等外界因素引起敏感元件磁性能变化转换成电信号,以这种方式来检测相应物理量的器件。
磁传感器广泛用于现代工业和电子产品中以感应磁场强度来测量电流、位置、方向等物理参数。在现有技术中,有许多不同类型的传感器用于测量磁场和其他参数。
磁传感器是把磁场、电流、应力应变、温度、光等外界因素引起敏感元件磁性能变化转换成电信号,以这种方式来检测相应物理量的器件。磁传感器分为三类:指南针、磁场感应器、位置传感器。指南针:地球会产生磁场,如果你能测地球表面磁场就可以做指南针。电流传感器:电流传感器也是磁场传感器。电流传感器可以用在家用电器、智能电网、电动车、风力发电等等。位置传感器: 如果一个磁体和磁传感器相互之间有位置变化,这个位置变化是线性的就是线性传感器,如果转动的就是转动传感器。
大生活中用到很多磁传感器,比如说指南针,电脑硬盘、家用电器等等。
在传统产业改造中的应用及市场
据报道,1995年仅工业过程控制传感器的全球市场已达到260亿美元;2001年计算机HDD用SV-GMR磁头的市场超过了4000亿日元(约合34亿美元)。若采用新型微型磁传感器,既使操作更简便,又提高了可靠性,增长了器件寿命,降低了成本。
使用新型磁传感器可以显着提高测量和控制精度,如使用GMI(巨磁阻抗)磁场传感器,检测分辨率和常用磁通门磁强计一样,而响应速度却快了一倍,消耗功率仅为后者的1%;若用霍尔器件,其分辨率仅4A/m,而所需外场比前者高300余倍;在应力检测中,SI 传感器的灵敏度是常用电阻丝的2000倍高,是半导体应变规的20~40倍。工业机床的油压或气压汽缸活塞位置检测,广泛采用套在活塞杆上的永磁环和AMR元件组成的磁传感器,检测精度达0.1mm,检测速度可在0~500mm/s内以高低速度变换;改用GMI或SV-GMR传感器后,测量精度至少可以提高1个数量级。在机床数控化时代,数字磁尺帮助设计师们实现了闭环控制。使用绝对信号输出的磁尺,则不受噪声、电源电压波动等干扰,也不必原点复位。使用工作状态磁敏开关,还可以完成手动与数控之间的转换。
旋转磁编码器在旋转量的检测控制中起关键作用,它在数控机床、机器人、工厂自动化设备的位置检测、传输速度控制,磁盘、打印机之类的自动化设备通讯设备的旋转量检测中都是不可缺少的重要部件。其检测对象是光磁图形,不受油雾粉尘的影响,因此比目前最先进的光编码器的可靠性高寿命长,尤其适合于自动焊接、油漆机器人和与钢铁有关的位置检测以及各种金属、木材、塑料等加工行业的应用。而仍大量使用光编码器,由于这种器件易受粉尘、油污和烟雾的影响,用在自动焊接、油漆机器人、纺织和钢铁、木料、塑料等的加工中,可靠性极差。应用AMR、GMR 、GMI敏感元件构成的旋转磁编码器,就不存在上述缺点,因此,它们的市场需求年增长率在30%以上。在家用电器和节能产品中也也有其广泛的应用潜力,在节能环保产品中也大有用武之地。若使用微型磁编码器和控制微机一体化,更有利于简化控制系统结构,减少元件数和占空体积,这在精密制造和加工业中意义十分重大。
在环境监测中的应用
环境保护的前提是对各个环境参数(温度、气压、大气成份、噪声。..。..。)的监测,这里需要使用多种大量的传感器。采用强磁致伸缩非晶磁弹微型磁传感器,可以同时测量真空或密闭空间的温度和气压,而且不用接插件,可以遥测和远距离访问。在食品包装、环境科学实验等方面,应用前景广阔。
在交通管制中的应用
交通事故和交通阻塞是城市中和城市间交通存在的一个大问题。国内外都在加强高速公路行车支持道路系统(AHS)、智能运输系统(ITS)和道路交通信息系统(VICS)等的开发与建设。在这些新系统中,高灵敏度、高速响应微型磁传感器大有用武之地。例如,用分辨率可达1nT的GMI和SI传感器,可构成ITS传感器(作高速路上的道路标志,测车轮角度,货车近接距离),汽车通过记录仪(测通行方向、速度、车身长度、车种识别),停车场成批车辆传感器,加速度传感器(测车辆通过时路桥的振动等)。
磁传感器在电子罗盘中的应用
几个世纪以来,人们在导航中一直使用磁罗盘。有资料显示早在二千多年前中国人就开始使用天然磁石-一种磁铁矿来指示水平方向。电子罗盘(数字罗盘,电子指南针,数字指南针)是测量方位角(航向角)比较经济的一种电子仪器。如今电子指南针广泛应用于汽车和手持电子罗盘,手表,手机,对讲机,雷达探测器,望远镜,探星仪,穆斯林麦加探测器(穆斯林钟),手持 GPS 系统,寻路器,武器/导弹导航( 航位推测 ),位置/方位系统,安全/定位设备,汽车、航海和航空的高性能导航设备,电子游戏机设备等需要方向或姿态显示的设备。
地球本身是一个大磁铁,地球表面的磁场大约为0.5Oe,地磁场平行地球表面并始终指向北方。利用GMR薄膜可做成用来探测地磁场的传感器。图5显示这种传感器的具体工作原理。我们可以制出能够探测磁场X和Y方向分量的集成GMR传感器。此传感器可作为罗盘并应用在各种交通工具上作为导航装置。美国的NVE公司已经把GMR传感器用在车辆的交通控制系统上。例如,放置在高速公路边的GMR传感器可以计算和区别通过传感器的车辆。如果同时分开放置两个GMR传感器,还可以探测出通过车辆的速度和车辆的长度,当然GMR也可用在公路的收费亭,从而实现收费的自动控制。另外高灵敏度和低磁场的传感器可以用在航空、航天及卫星通信技术上。大家知道,在军事工业中随着吸波技术的发展,军事物件可以通过覆盖一层吸波材料而隐蔽,但是它们无论如何都会产生磁场,因此通过GMR磁场传感器可以把隐蔽的物体找出来。当然,GMR磁场传感器可以应用在卫星上,用来探测地球表面上的物体和底下的矿藏分布。
门磁传感器在智能家居中的应用
在智能家居门禁系统中门磁开关的作用是负责门磁通电否,通电带磁(闭门),断电消磁(开门),门磁安装于门与门套上,开关安装于屋内,配合自动闭门器使用,一般可承受150公斤的拉力。
有线门磁为嵌入式安装更加隐蔽,感应门窗的开合,适用于木质或铝合金门窗发出有线常闭/常开开关信号。门磁是用来探测门、窗、抽屉等是否被非法打开或移动。它由无线发射器和磁块两部分组成。门磁系统其实和床磁等原理相同。
Android系统提供了对传感器的支持,如果手机的硬件提供了这些传感器的话,那么我们就可以通过代码获取手机外部的状态。比如说手机的摆放状态、外界的磁场、温度和压力等等。
对于我们开发者来说,开发传感器十分简单。只需要注册监听器,接收回调的数据就行了,下面来详细介绍下各传感器的开发。
使用
第一步
// 获取传感器管理对象
SensorManager mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);12
第二步
// 获取传感器的类型(TYPE_ACCELEROMETER:加速度传感器)
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);12
这里我们除了可以获取加速度传感器之外,还可以获取其他类型的传感器,如:
* Sensor.TYPE_ORIENTATION:方向传感器。
* Sensor.TYPE_GYROSCOPE:陀螺仪传感器。
* Sensor.TYPE_MAGNETIC_FIELD:磁场传感器。
* Sensor.TYPE_GRAVITY:重力传感器。
* Sensor.TYPE_LINEAR_ACCELERATION:线性加速度传感器。
* Sensor.TYPE_AMBIENT_TEMPERATURE:温度传感器。
* Sensor.TYPE_LIGHT:光传感器。
* Sensor.TYPE_PRESSURE:压力传感器。
第三步
在onResume()方法中监听传感器传回的数据:
@Override
protected void onResume() {
super.onResume();
// 为加速度传感器注册监听器
mSensorManager.registerListener(new SensorEventListener() {
// 当传感器的值改变的时候回调该方法
@Override
public void onSensorChanged(SensorEvent event) {
}
// 当传感器精度发生改变时回调该方法
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}, mSensor, SensorManager.SENSOR_DELAY_GAME);
}1234567891011121314151617
其中,registerListener(SensorEventListener listener, Sensor sensor,int samplingPeriodUs)的三个参数说明如下:
listener:监听传感器时间的监听器,该监听器需要实现SensorEventListener接口。
sensor:传感器对象。
samplingPeriodUs:指定获取传感器频率,一共有如下几种:
* SensorManager.SENSOR_DELAY_FASTEST:最快,延迟最小,同时也最消耗资源,一般只有特别依赖传感器的应用使用该频率,否则不推荐。
* SensorManager.SENSOR_DELAY_GAME:适合游戏的频率,一般有实时性要求的应用适合使用这种频率。
* SensorManager.SENSOR_DELAY_NORMAL:正常频率,一般对实时性要求不高的应用适合使用这种频率。
* SensorManager.SENSOR_DELAY_UI:适合普通应用的频率,这种模式比较省电,而且系统开销小,但延迟大,因此只适合普通小程序使用。
并在onStop()方法中取消注册:
@Override
protected void onStop() {
super.onStop();
// 取消监听
mSensorManager.unregisterListener(this);
}123456
简单3步,就完成了监听加速度传感器的开发,是不是so easy?
下面一个列子,演示了完整的监听加速度传感器的开发,并将结果显示到屏幕上:
public class MainAcTIvity extends AppCompatAcTIvity implements SensorEventListener{
private SensorManager mSensorManager;
private TextView mTxtValue;
private Sensor mSensor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTxtValue = (TextView) findViewById(R.id.txt_value);
// 获取传感器管理对象
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
// 获取传感器的类型(TYPE_ACCELEROMETER:加速度传感器)
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
@Override
protected void onResume() {
super.onResume();
// 为加速度传感器注册监听器
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);
}
@Override
protected void onStop() {
super.onStop();
// 取消监听
mSensorManager.unregisterListener(this);
}
// 当传感器的值改变的时候回调该方法
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
StringBuilder sb = new StringBuilder();
sb.append(“X方向的加速度:”);
sb.append(values[0]);
sb.append(“\nY方向的加速度:”);
sb.append(values[1]);
sb.append(“\nZ方向的加速度:”);
sb.append(values[2]);
mTxtValue.setText(sb.toString());
}
// 当传感器精度发生改变时回调该方法
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
运行结果:
方向传感器
方向传感器用于感应手机的摆放位置,它给我们返回了三个角度,这三个角度可以确定手机的摆放状态。
* 第一个角度:表示手机顶部朝向与正北方的夹角。当手机绕着Z轴旋转时,该角度值发生改变。比如,当该角度为0度时,表明手机顶部朝向正北;该角度为90度时,表明手机顶部朝向正东;该角度为180度时,表明手机朝向正南;该角度为270度时,表明手机顶部朝向正西。
* 第二个角度:表示手机顶部或尾部翘起的高度。当手机绕着X轴倾斜时,该角度值发生变化,该角度的取值范围是-180~180度。假设手机屏幕朝上水平放在桌子上,如果桌子是完全水平的,该角度值应该是0度。假如从手机顶部开始抬起,直到将手机沿X轴旋转180度(屏幕向下水平放在桌子上),在这个旋转的过程中,该角度值会从0度变化到-180度。也就是说,从手机顶部抬起时,该角度的值会逐渐减少,直到等于-180度;如果从手机底部开始抬起,直到将手机沿X轴旋转180度(屏幕向下水平放在桌子上),该角度的值会从0度变化到180度,也就是说,从手机底部抬起时,该角度的值会逐渐增大,直到等于180度。
* 第三个角度:表示手机左侧或右侧翘起的角度。当手机绕着Y轴倾斜时,该角度值发生改变。该角度的取值范围是:-90~90度。假设将手机屏幕朝上水平放在桌面上,如果桌面是完全水平的,该角度应该为0度。如果将手机从左侧开始慢慢抬起,知道将手机沿着Y轴旋转90度(手机与桌面垂直),在这个旋转的过程中,该角度值会从0度变化到-90度。也就是说,从手机左侧开始抬起时,该角度的值会逐渐的减少,知道等于-90度。如果从手机的右侧抬起,则刚好相反,会从0度变化,直到90度。
通过在应用程序中使用方向传感器,可以实现如:地图导航、水平仪、指南针等应用。
陀螺仪传感器
陀螺仪传感器用于感应手机的旋转速度。陀螺仪传感器给我们返回了当前设备的X、Y、Z三个坐标轴(坐标系统与加速度传感器一模一样)的旋转速度。旋转速度的单位是弧度/秒,旋转速度为:
正值代表逆时针旋转,负值代表顺时针旋转。关于返回的三个角速度说明如下:
* 第一个值:代表该设备绕X轴旋转的角速度。
* 第二个值:代表该设备绕Y轴旋转的角速度。
* 第三个值:代表该设备绕Z轴旋转的角速度。
磁场传感器
磁场感应器主要读取设备周围的磁场强度。即便是设备周围没有任何直接的磁场,设备也会始终处于地球的磁场中,除非你不在地球。。随着手机设备摆放状态的改变,周围磁场在手机的X、Y、Z方向上的影响也会发生改变。磁场传感器会返回三个数据,分别代表周围磁场分解到X、Y、Z三个方向的磁场分量,磁场数据的单位是微特斯拉。
重力传感器
重力传感器会返回一个三维向量,这个三维向量可显示重力的方向和强度。重力传感器的坐标系统和加速度传感器的坐标系统相同。
线性加速度传感器
线性加速度传感器返回一个三维向量显示设备在各个方向的加速度(不包含重力加速度)。线性加速度传感器的坐标系统和加速度传感器的坐标系统相同。
线性加速度传感器、重力传感器、加速度传感器,这三者输出值的关系如下:
加速度传感器 = 重力传感器 + 线性加速度传感器。
温度传感器
温度传感器用于获取设备所处环境的温度。温度传感器会返回一个数据,代表手机设备周围的温度,单位是摄氏度。
光传感器
光传感器用于获取设备周围光的强度。光传感器会返回一个数据,代表手机周围光的强度,单位是勒克斯。
压力传感器
压力传感器用于获取设备周围压力的大小。压力传感器会返回一个数据,代表设备周围压力的大小。
心率传感器
心率传感器是在5.0之后新增的一个传感器,用于返回佩戴设备的人每分钟的心跳次数。该传感器返回的数据准确性可以通过SensorEvent的accuracy进行判断,如果该属性值为:SENSOR_STATUS_UNRELIABLE或SENSOR_STATUS_NO_CONTACT,则表明传感器返回的数据是不太可靠的,应该丢弃。
在使用心率传感器时,需要增加如下权限:
《uses-permission android:name=“android.permission.BODY_SENSORS”/》1
实例(获取各传感器数据并展示)
public class MainActivity extends AppCompatActivity implements SensorEventListener{
private SensorManager mSensorManager;
private TextView mTxtValue1;
private TextView mTxtValue2;
private TextView mTxtValue3;
private TextView mTxtValue4;
private TextView mTxtValue5;
private TextView mTxtValue6;
private TextView mTxtValue7;
private TextView mTxtValue8;
private TextView mTxtValue9;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTxtValue1 = (TextView) findViewById(R.id.txt_value1);
mTxtValue2 = (TextView) findViewById(R.id.txt_value2);
mTxtValue3 = (TextView) findViewById(R.id.txt_value3);
mTxtValue4 = (TextView) findViewById(R.id.txt_value4);
mTxtValue5 = (TextView) findViewById(R.id.txt_value5);
mTxtValue6 = (TextView) findViewById(R.id.txt_value6);
mTxtValue7 = (TextView) findViewById(R.id.txt_value7);
mTxtValue8 = (TextView) findViewById(R.id.txt_value8);
mTxtValue9 = (TextView) findViewById(R.id.txt_value9);
// 获取传感器管理对象
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
// 为加速度传感器注册监听器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
// 为方向传感器注册监听器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_GAME);
// 为陀螺仪传感器注册监听器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);
// 为磁场传感器注册监听器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_GAME);
// 为重力传感器注册监听器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY), SensorManager.SENSOR_DELAY_GAME);
// 为线性加速度传感器注册监听器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION), SensorManager.SENSOR_DELAY_GAME);
// 为温度传感器注册监听器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE), SensorManager.SENSOR_DELAY_GAME);
// 为光传感器注册监听器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT), SensorManager.SENSOR_DELAY_GAME);
// 为压力传感器注册监听器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE), SensorManager.SENSOR_DELAY_GAME);
}
@Override
protected void onStop() {
super.onStop();
// 取消监听
mSensorManager.unregisterListener(this);
}
// 当传感器的值改变的时候回调该方法
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
// 获取传感器类型
int type = event.sensor.getType();
StringBuilder sb;
switch (type){
case Sensor.TYPE_ACCELEROMETER:
sb = new StringBuilder();
sb.append(“加速度传感器返回数据:”);
sb.append(“\nX方向的加速度:”);
sb.append(values[0]);
sb.append(“\nY方向的加速度:”);
sb.append(values[1]);
sb.append(“\nZ方向的加速度:”);
sb.append(values[2]);
mTxtValue1.setText(sb.toString());
break;
case Sensor.TYPE_ORIENTATION:
sb = new StringBuilder();
sb.append(“\n方向传感器返回数据:”);
sb.append(“\n绕Z轴转过的角度:”);
sb.append(values[0]);
sb.append(“\n绕X轴转过的角度:”);
sb.append(values[1]);
sb.append(“\n绕Y轴转过的角度:”);
sb.append(values[2]);
mTxtValue2.setText(sb.toString());
break;
case Sensor.TYPE_GYROSCOPE:
sb = new StringBuilder();
sb.append(“\n陀螺仪传感器返回数据:”);
sb.append(“\n绕X轴旋转的角速度:”);
sb.append(values[0]);
sb.append(“\n绕Y轴旋转的角速度:”);
sb.append(values[1]);
sb.append(“\n绕Z轴旋转的角速度:”);
sb.append(values[2]);
mTxtValue3.setText(sb.toString());
break;
case Sensor.TYPE_MAGNETIC_FIELD:
sb = new StringBuilder();
sb.append(“\n磁场传感器返回数据:”);
sb.append(“\nX轴方向上的磁场强度:”);
sb.append(values[0]);
sb.append(“\nY轴方向上的磁场强度:”);
sb.append(values[1]);
sb.append(“\nZ轴方向上的磁场强度:”);
sb.append(values[2]);
mTxtValue4.setText(sb.toString());
break;
case Sensor.TYPE_GRAVITY:
sb = new StringBuilder();
sb.append(“\n重力传感器返回数据:”);
sb.append(“\nX轴方向上的重力:”);
sb.append(values[0]);
sb.append(“\nY轴方向上的重力:”);
sb.append(values[1]);
sb.append(“\nZ轴方向上的重力:”);
sb.append(values[2]);
mTxtValue5.setText(sb.toString());
break;
case Sensor.TYPE_LINEAR_ACCELERATION:
sb = new StringBuilder();
sb.append(“\n线性加速度传感器返回数据:”);
sb.append(“\nX轴方向上的线性加速度:”);
sb.append(values[0]);
sb.append(“\nY轴方向上的线性加速度:”);
sb.append(values[1]);
sb.append(“\nZ轴方向上的线性加速度:”);
sb.append(values[2]);
mTxtValue6.setText(sb.toString());
break;
case Sensor.TYPE_AMBIENT_TEMPERATURE:
sb = new StringBuilder();
sb.append(“\n温度传感器返回数据:”);
sb.append(“\n当前温度为:”);
sb.append(values[0]);
mTxtValue7.setText(sb.toString());
break;
case Sensor.TYPE_LIGHT:
sb = new StringBuilder();
sb.append(“\n光传感器返回数据:”);
sb.append(“\n当前光的强度为:”);
sb.append(values[0]);
mTxtValue8.setText(sb.toString());
break;
case Sensor.TYPE_PRESSURE:
sb = new StringBuilder();
sb.append(“\n压力传感器返回数据:”);
sb.append(“\n当前压力为:”);
sb.append(values[0]);
mTxtValue9.setText(sb.toString());
break;
}
}
// 当传感器精度发生改变时回调该方法
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}