大家好,欢迎来到IT知识分享网。
磁感应传感器|从零开始认识各种传感器
1、什么是磁感应传感器
磁感应传感器又叫做磁力计,是可以测量磁场大小或方向的设备。因为地球本质上是一个巨大的磁铁。磁力计可让您测量空间中某一点的磁场强度以及磁场方向。
图1 磁力计
磁力计已广泛应用于各种应用。它们用于测量地球磁场、地理测量、探测潜艇,以及用于金属/武器探测器等方面。近年来,磁力计已经集成电路化并出现在多种电子产品中。 智能手机中的指南针功能就是由磁力计来实现的。导航功能也会借助磁力计,尤其是在城市中没有良好信号的地方。
2、磁感应传感器是如何工作的
磁感应传感器是通过测量磁场的强度和方向来工作的,它通常包含一个灵敏的磁性元件,当置于磁场中时,磁性元件会受到力的作用,导致它在磁场中发生运动。
图2 磁感应传感器工作原理
指南针就是一种简单类型的磁力计,其磁针根据周围磁场改变方向。磁化针的振荡频率与周围磁场强度的平方根成正比,根据震荡频率,就可以测量出磁场的强度。
在一个具体的导航应用中,地磁场是一个矢量,对于一个固定的地点来说,这个矢量可以被分解为两个与当地水平面平行的分量和一个与当地水平面垂直的分量。如果保持罗盘与和当地的水平面平行,那么罗盘中磁力计的三个轴就对应了这三个分量,从而确定了地面上的对应位置。
图3 罗盘导航工作原理
3、常见的磁感应传感器的种类
目前常用的主要是两种磁力计:磁电阻式磁力计和霍尔效应磁力计。他们采用了不同的测量原理。
磁电阻式磁力计是利用磁电阻效应,即材料的电阻会随着外部磁场的改变而发生变化。其应用包括磁罗盘、旋转位置传感、电流传感等。钻井定向、线位置测量、偏航速率传感器和虚拟实景中的头部轨迹跟踪。
霍尔效应磁力计是测量由于霍尔效应产生的电压,这种磁力计响应速度快,对于快速变化的磁场非常敏感,因此在许多应用中得到广泛应用,如导航系统和电动汽车。
3.1 磁电阻式磁力计
某些金属或半导体在遇到外加磁场时, 电阻值会随着外加磁场的大小发生变化,这种现象叫做磁阻效应。
图4 磁阻效应原理
磁电阻式磁力计的基本结构是由四个磁阻组成的惠斯通电桥,利用惠斯通电桥检测磁阻的变化。电桥中R1/R2/R3/R4 阻值相同都是R,但是R1/R2和R3/R4具有相反的磁化特性。
在没有外界磁场的情况下,电桥的输出为零。当检测到外界磁场的时候,R1/R2阻值增加∆R而R3/R4减少∆R。电桥输出一个微小的电压差∆V,它正比于外界磁场作用下的磁阻变化∆R。这就是磁阻式磁力计的工作原理。
图5 惠斯通电桥
3.2 霍尔效应磁力计
霍尔效应磁力计利用霍尔效应来测量磁感应强度。所谓霍尔效应就是,当有电流垂直于外磁场通过半导体时,载流子发生偏转,垂直于电流和磁场的方向会产生一附加电场,从而在半导体的两端产生电势差,这一现象就是霍尔效应(这个电势差也被称为霍尔电势差)。
图6 霍尔效应原理
霍尔磁力计通过测量霍尔电势差,经过信号放大和滤波器处理后,可以得到磁场的强度和方向信息。
3.3 两种磁感应传感器的比较
图7 磁感应传感器特性比较
这张表格给出了两者的一般性对比,由于测量原理的不同,两种传感器的特性各有不同。通常来说磁阻式磁力计的灵敏度和精度更高;霍尔磁力计的响应速度会更快。使用者可以根据自己的需求选择。
4、磁感应传感器实验演示
我们来演示使用 MCU 读取显示磁感应传感器的数据。实验中使用的是一款常见的三轴磁力计。我们移动磁力进行x,y,z 轴方向的旋转,可以看到屏幕显示的正方体根据检测的数据也出现相应的旋转动作。
图8 树莓派读取磁感应传感器展示
代码如下:
main.py
import uos import machine import st7789 as st7789 from fonts import vga2_8x8 as font1 from fonts import vga1_16x32 as font2 import random import framebuf machine.freq(200_000_000 ) #from DMA import DMA import time from math import pi,sin,exp,sqrt,floor,cos import time, array, uctypes, rp_devices as devs import math # w, h = 240, 220 j=0 i=0 x,y=0,0 offset_adc=0 offset_dis=0 x_Value=0 y_Value=0 disp_width = 240 disp_height = 240 st7789_res = 0 st7789_dc = 1 spi_sck=machine.Pin(2) spi_tx=machine.Pin(3) reset=machine.Pin(st7789_res, machine.Pin.OUT) dc=machine.Pin(st7789_dc, machine.Pin.OUT) spi0=machine.SPI(0,baudrate=, phase=1, polarity=1,bits = 8 , sck=spi_sck, mosi=spi_tx) display = st7789.ST7789(spi0, disp_width, disp_width,reset,dc,xstart=0, ystart=0, rotation=3) display.clear(st7789.BLACK) dis_h = 150 dis_w = 150 dis_buff_0 = array.array('H', (0 for _ in range(dis_h*dis_w*2))) DMA_CHAN_0 = 0 dma_chan_0 = devs.DMA_CHANS[DMA_CHAN_0] #dma_0 = devs.DMA_DEVICE dma_chan_0.READ_ADDR_REG = uctypes.addressof(dis_buff_0) dma_chan_0.WRITE_ADDR_REG = devs.SPI0_SSPDR dma_chan_0.TRANS_COUNT_REG = len(dis_buff_0)#int(len(dis_buff_0)/2) dma_chan_0.CTRL_TRIG_REG = 0 dma_chan_0.CTRL_TRIG.BUSY = 0 #print(dma_chan_0.CTRL_TRIG.BUSY) dma_chan_0.CTRL_TRIG.CHAIN_TO = DMA_CHAN_0 dma_chan_0.CTRL_TRIG.INCR_WRITE = 0 dma_chan_0.CTRL_TRIG.INCR_READ = 1 dma_chan_0.CTRL_TRIG.TREQ_SEL = devs.DREQ_SPI0_TX # dma_chan_0.CTRL_TRIG.DATA_SIZE = 1 I2C_TEST = machine.I2C(0,scl=machine.Pin(21), sda=machine.Pin(20)) #initializing the I2C method for ESP32 #BM1422GMV I2C_TEST.writeto_mem(14,0x1B,bytes([152])) I2C_TEST.writeto_mem(14,0x5C,bytes([0])) I2C_TEST.writeto_mem(14,0x5D,bytes([0])) I2C_TEST.writeto_mem(14,0x1C,bytes([12])) I2C_TEST.writeto_mem(14,0x6C,bytes([45])) I2C_TEST.writeto_mem(14,0x72,bytes([45])) I2C_TEST.writeto_mem(14,0x78,bytes([45])) I2C_TEST.writeto_mem(14,0x1D,bytes([64])) unsigned_x=0 unsigned_y=0 unsigned_z=0 signed_x=0 signed_y=0 signed_z=0 def read_component(): global signed_x,signed_y,signed_z,unsigned_x,unsigned_y,unsigned_z unsigned_x = I2C_TEST.readfrom_mem(14, 0x10,2) unsigned_y = I2C_TEST.readfrom_mem(14, 0x12,2) unsigned_z = I2C_TEST.readfrom_mem(14, 0x14,2) signed_x=((unsigned_x[1]<<8)|unsigned_x[0]) - 256-380 signed_y=((unsigned_y[1]<<8)|unsigned_y[0]) - 256-170 signed_z=((unsigned_z[1]<<8)|unsigned_z[0]) - 230-200 def line( x0, y0, x1, y1, color): """ Draw a single pixel wide line starting at x0, y0 and ending at x1, y1. Args: x0 (int): Start point x coordinate y0 (int): Start point y coordinate x1 (int): End point x coordinate y1 (int): End point y coordinate color (int): 565 encoded color """ global dis_buff_0,dis_h,dis_w steep = abs(y1 - y0) > abs(x1 - x0) if steep: x0, y0 = y0, x0 x1, y1 = y1, x1 if x0 > x1: x0, x1 = x1, x0 y0, y1 = y1, y0 dx = x1 - x0 dy = abs(y1 - y0) err = dx // 2 if y0 < y1: ystep = 1 else: ystep = -1 while x0 <= x1: if steep: # self.pixel(y0, x0, color) dis_buff_0[(y0-1)*dis_h+x0] = color else: # self.pixel(x0, y0, color) dis_buff_0[(x0-1)*dis_h+y0] = color err -= dy if err < 0: y0 += ystep err += dx x0 += 1 cube=[[-40,-40,-40],[-40,40,-40],[40,40,-40],[40,-40,-40],[-40,-40,40],[-40,40,40],[40,40,40],[40,-40,40]] lineid=[1,2,2,3,3,4,4,1,5,6,6,7,7,8,8,5,8,4,7,3,6,2,5,1] def matconv(a,matrix): res=[0,0,0] for i in range(0,3): res[i]=matrix[i][0]*a[0]+matrix[i][1]*a[1]+matrix[i][2]*a[2] for i in range(0,3): a[i]=res[i] return a def rotate(obj,x,y,z): x=x/pi y=y/pi z=z/pi rz=[[cos(z),-sin(z),0],[sin(z),cos(z),0],[0,0,1]] ry=[[1,0,0],[0,cos(y),-sin(y)],[0,sin(y),cos(y)]] rx=[[cos(x),0,sin(x)],[0,1,0],[-sin(x),0,cos(x)]] matconv(matconv(matconv(obj,rz),ry),rx) buff_1=bytearray(24) buff_2=bytearray(24) buff_pre_1=bytearray(24) buff_pre_2=bytearray(24) def drawcube(x,y,z): global buff_1,buff_2,buff_pre_1,buff_pre_2,mpu_value for i in range (0,24,2): line(buff_pre_1[i],buff_pre_1[i+1],buff_pre_2[i],buff_pre_2[i+1],st7789.BLACK) for i in range(0,8): rotate(cube[i],x,y,z) for i in range(0,24,2): buff_1[i]=int(75+cube[lineid[i]-1][0]) buff_1[i+1]=int(75+cube[lineid[i]-1][1]) buff_2[i]=int(75+cube[lineid[i+1]-1][0]) buff_2[i+1]=int(75+cube[lineid[i+1]-1][1]) for i in range (0,24,2): line(buff_1[i],buff_1[i+1],buff_2[i],buff_2[i+1],st7789.BLUE) buff_pre_1 = buff_1 buff_pre_2 = buff_2 display.set_window(125,45,150,150) ROT_X_Y=0 ROT_X_Z=0 ROT_Y_Z=0 BM_X_Y_pre=0 BM_X_Z_pre=0 BM_Y_Z_pre=0 while True: read_component() BM_X_Y=math.atan2(float(signed_y),float(signed_x))*57.3+180 BM_X_Z=math.atan2(float(signed_z),float(signed_x))*57.3+180 BM_Y_Z=math.atan2(float(signed_z),float(signed_y))*57.3+180 if BM_X_Y_pre >300 and BM_X_Y <60 : ROT_X_Y= -360 elif BM_X_Y_pre <60 and BM_X_Y >300 : ROT_X_Y= 360 else : ROT_X_Y=0 if BM_X_Z_pre >300 and BM_X_Z <60 : ROT_X_Z= -360 elif BM_X_Z_pre <60 and BM_X_Z >300 : ROT_X_Z= 360 else : ROT_X_Z=0 if BM_Y_Z_pre >300 and BM_Y_Z <60 : ROT_Y_Z= -360 elif BM_Y_Z_pre <60 and BM_Y_Z >300 : ROT_Y_Z= 360 else : ROT_Y_Z=0 drawcube((BM_X_Y_pre-BM_X_Y+ROT_X_Y)/36,(BM_X_Z_pre-BM_X_Z+ROT_X_Z)/36,(BM_Y_Z_pre-BM_Y_Z+ROT_Y_Z)/36) print((BM_X_Y_pre-BM_X_Y+ROT_X_Y)/36,(BM_X_Z_pre-BM_X_Z+ROT_X_Z)/36,(BM_Y_Z_pre-BM_Y_Z+ROT_Y_Z)/36) BM_X_Y_pre=BM_X_Y BM_X_Z_pre=BM_X_Z BM_Y_Z_pre=BM_Y_Z dc.off() display.write(st7789.ST7789_RAMWR, b"" ) dma_chan_0.READ_ADDR_REG = uctypes.addressof(dis_buff_0) dc.on() dma_chan_0.CTRL_TRIG.EN = 1 while dma_chan_0.CTRL_TRIG.BUSY: pass dma_chan_0.CTRL_TRIG.EN = 0
其余代码文件请点此查看。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/155927.html