<iframe allowfullscreen="true" data-mediaembed="bilibili" frameborder="0" id="Rvvhgxue-1721874025747" src="https://player.bilibili.com/player.html?aid=1802504150"></iframe>
气压高度传感器|从零开始认识各种传感器
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()
标签:temp,current,从零开始,气压,传感器,第十五,display,delt
From: https://blog.csdn.net/m0_61036291/article/details/140682658