气压高度传感器 - 从零开始认识各种传感器【第十五期】

气压高度传感器|从零开始认识各种传感器

1、什么是气压高度传感器 

气压高度传感器是通过气压的变化来测量所处高度的传感器,它在测量的过程中不易受到障碍物的影响,测量高度范围广,可进行绝对海拔高度测量和相对高度测量。目前智能手机及智能穿戴设备上也大多集成了气压传感器,以确定所处的海拔高度,增强GPS和导航的定位精确性。

 

2、气压高度传感器工作原理

使用气压传感器通过测量大气压力的变化可以计算当前高度。因为随着海拔的增加,大气压力会逐渐下降。这是由于大气压力是由气体的重量在地面上产生的压力,随着海拔的升高,所处位置的大气层的厚度减小,大气压力也会减小。那么高度就可以通过测量大气压力的变化来确定。

 

应用气压公式可以算出高度,那么气压传感器可用作气压高度计:

 

公式中:P是当前压力;P0是海平面的压力 (h=0);高度 (h) 以m为单位。当然,这个公式包含了大气成分和环境温度为15度的假定,具体使用时需要进行温度补偿。
在测量气压时都需要一个基准值,通常是标准大气压。通过测量环境中的实际气压并将其与标准值比较,传感器可以计算出相对的气压变化,从而提供高度变化信息。

3、常见的气压高度传感器的种类 

常见的气压高度传感器可以分成压阻式,电容式和MEMS三种。它们都是利用测量用的介质,如电阻,电容,微机械部件等,其由于气压变化产生形变,导致电阻值,电容值等发生变化的特点,来测量气压的变化。
压阻型传感器的基本原理是材料的电阻随着外部气压的变化而变化,这种变化可以通过电路测量并转换为相应的气压值。
电容型传感器利用电容与气体介质之间的关系,电容值会随气压变化而改变,通过测量电容变化来推断气压的变化。
微电子机械系统(MEMS)传感器使用了微型机械结构,例如微小的薄膜或悬浮的微机械部件,当气压变化时,这些微结构也会受到影响,导致电信号的变化。

3.1 压阻式气压高度传感器

 

压阻式气压传感器通常使用硅单晶板作为隔膜,也就是气压压力接收元件。通过在其表面上扩散杂质形成电阻桥电路,将施加压力时产生的变形转化为电阻值变化,来计算压力(气压)。电阻的电阻率因施加在该电阻上的压力而变化的现象称为压阻效应。目前新型的气压传感器IC大多使用MEMS结构(即隔膜结构和压阻集成在一起),以及温度校正处理、控制电路等的集成电路(ASIC)集成在一个封装里,可以轻松获得高精度的气压信息。

 

3.2 电容式气压高度传感器

 

电容式气压传感器基于电容与气体介质之间的关系。气压的变化会引起电容值的变化,通过测量电容的变化,可以推断气压的改变。电容式气压传感器常用于气象观测和高度测量中。

 

它对比压阻式气压传感器,具有以下几个优点:

功耗更低:压阻式在测量时应用惠斯通电桥,会消耗能量,而电容式的测量原理几乎不消耗电流;
噪声更低:压阻式的热噪声从根本上限制了气压计的灵敏度和分辨率;
电容式具有更高的温度稳定性:而压阻式对温度很敏感;
从原理上来说, 电容式对气压变化更为敏感,从而有更高的精度。

3.3 MEMS气压高度传感器

 

典型的MEMS压力传感器是将一块硅薄片盖在填充参考压力气体(或真空)的腔室上。腔室和环境之间的气压差使薄片弯曲变形而产生机械应力,从而产生成正比的电信号。集成的芯片ASIC可检测该信号并将其数字化。
MEMS气压传感器的传感薄片可以是机械式,电容式,或者压阻式。它具有体积小巧、噪声低,功耗低的特点,而且高度差测量精确度可以达到cm级别;适用于智能手机、平板电脑、无人机、增强现实(AR)和虚拟现实(VR)、智能家电等应用,是目前主流应用的气压传感器类型。

4、气压高度传感器实验演示 

我们来演示使用 MCU 读取显示气压高度传感器的数据。实验中使用的是一款MEMS气压高度传感器。将气压传感器上下移动,可以看到,上升时气压值减小,下降时气压值增大,气压值变化反映了当前高度的变化。

 

完整代码如下:

from breakout_colourlcd240x240 import BreakoutColourLCD240x240
from machine import I2C, ADC, Pin, Timer, PWM
import time, math,array
from utime import sleep
reset_pin = Pin(8,Pin.IN,Pin.PULL_UP)
i2c = I2C(0, scl=Pin(21), sda=Pin(20), freq=400_000)
ms5611_c = [0, 0, 0, 0, 0, 0, 0, 0]
GY63_ADDRESS = 0x77
print(i2c.scan())
def reset():
    i2c.writeto(GY63_ADDRESS, bytearray([0x1E]))
    time.sleep(0.01)
def init():
    reset()
    for i in range(8):
        ms5611_c[i] = prom(i)
def prom(coef_num):
    rxbuff = i2c.readfrom_mem(GY63_ADDRESS, 0XA0+coef_num*2, 3)
    return rxbuff[0] << 8 | rxbuff[1]    
def read_pressure():   
    i2c.writeto(GY63_ADDRESS, bytearray([0x48]))   
    time.sleep(0.02)    
    data = i2c.readfrom_mem(GY63_ADDRESS, 0, 3)    
    pressure = (data[0] << 16) + (data[1] << 8) + data[2]    
    return pressure
def read_temperature():
    i2c.writeto(GY63_ADDRESS, bytearray([0x58]))   
    time.sleep(0.02)    
    data = i2c.readfrom_mem(GY63_ADDRESS, 0, 3)    
    temperature = (data[0] << 16) + (data[1] << 8) + data[2]   
    return temperature
def calculate(ut, up):
    dT = ut - (ms5611_c[5] << 8)
    off = (ms5611_c[2] << 16) + ((ms5611_c[4]*dT) >> 7)
    sens = (ms5611_c[1] << 15) + ((ms5611_c[3]*dT) >> 8)
    temp = 2000 + ((dT*ms5611_c[6]) >> 23)   
    if (temp < 2000):
        delt = temp - 2000
        delt = 5 * delt *delt
        off = off - (delt >> 1)
        sens = sens - (delt >> 2)   
    if (temp < -1500):
        delt = temp + 1500
        delt = delt * delt
        off = off - (7 * delt)
        sens = sens - ((11 * delt) >> 1)   
    temp = temp - ((dT*dT) >> 31)
    press = (((int(up)*sens) >> 21) - off) >> 15
    return press, temp
flag = 0
total = 0
length = 10
buffer = array.array('H', (0 for _ in range(length)))
index = 0
position = 0
init_position = 0
current_press = 0
init()
#------------------------------------------------------------------
width = BreakoutColourLCD240x240.WIDTH
height = BreakoutColourLCD240x240.HEIGHT
display_buffer = bytearray(width * height*2)
display = BreakoutColourLCD240x240(display_buffer)

timer1 = Timer() 

stemp = ADC(2)                       
current_temp = 0                   
#-------------------------------------------------------------------
def display_init():
    
    display.set_pen(0,255,0)
    display.rectangle(58,30,13,160)
    display.circle(64,190,10)
    display.set_pen(255,0,0)
  
    display.text("current", 150, 20, 194, 2)
    display.text("value", 150, 35, 194, 2)
    display.update()
  
    for i in range(6):
        display.set_pen(0,200,0)
        display.pixel_span(80,27 + i*30,10)
        display.text(str(50 - i *10), 100, 20+i*30, 194, 2)
        display.set_pen(0,0,220)
        if i < 5:
            for j in range(4):
                display.pixel_span(80,33 + j*6 + i * 30,5)
        display.update()
    
#---------------------------------------------------------------------
def display_change(temp, color):
    global current_temp
    current_temp = temp
    #print(temp)
    display.set_pen(color[0], color[1], color[2])
    display.rectangle(58,30,13,160)
    display.circle(64,190,10)
    display.set_pen(0,0,150)
    display.rectangle(58,20,13,7+int((50-temp)/2)*6)
    display.set_pen(0,0,0)
    display.rectangle(150,50,90,40)
    display.set_pen(0,255,0)
    display.text(str(temp), 150, 50, 5, 5)
    display.update()
#----------------------------------------------------------------------
def get_temp():
    global init_position,current_press,index,length,position
    if reset_pin.value() == 0 :
        init_position = current_press
    up = read_pressure()
    ut = read_temperature()
    pressure, temperature = calculate(ut, up)
    buffer[index] = pressure
    index += 1
    index %= length
    for i in range (length) :
        current_press += buffer[i]
    current_press = current_press/length
#     print("Pressure:", current_press)
#     hight=(101325-current_press)/133*12
#     print("hight:", hight)
    position=int((current_press-init_position)*5)+25
    print(position)
    return position
#----------------------------------------------------------------------
def main():
    
    color = [0,255,0] 
    timer1 = Timer()
    display_init()
    timer1.init(freq=5,mode=Timer.PERIODIC, callback=lambda t:display_change(get_temp(), color))

    while True:
      sleep(0.1) 
main()

  • 26
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值