陀螺仪传感器 - 从零开始认识各种传感器【第十一期】

1、什么是陀螺仪传感器

陀螺仪传感器又叫做角速度传感器。它是能检测到物体在空间中的姿态,朝向及转动角度的传感器。它被广泛应用于航空航天导航,便携智能设备体感检测,以及汽车姿态的传感等各个方面。陀螺仪与加速度计的主要区别就是陀螺仪主要用来测量角速度的,而加速度计是测线性加速度的。

图1 陀螺仪传感器

2、陀螺仪传感器是如何工作的

陀螺仪传感器是惯性测量元件,一个旋转物体的旋转轴所指的方向在不受外力影响时,是不会改变的。人们根据这个旋转轴保持指向不变的特性,用它来检测当前方向和角度的改变。例如,在被测物体相对于 x轴,y轴,或者z轴发生角度转变时,由于旋转轴的方向保持不变,那么通过测量万向节连接环的角度变化,即可获知被测物体当前的角度变化以及角速度。

图2 陀螺仪传感器工作原理

3、常见的陀螺仪传感器的种类

从早期的机械式陀螺仪发展到现在,市场上主流的陀螺仪可分为激光陀螺仪,光纤陀螺仪和MEMS陀螺仪三种类型。

3.1 激光陀螺仪

激光陀螺仪的实现基于塞格尼克理论:当光束在一个环形的通道中前进时,如果环形通道本身具有一个转动速度,那么光线沿着通道转动的方向转一圈的时间要比沿着这个通道反向转一圈所需要的时间要多。也就是说当光学环路转动时,在正反两个方向上,光学环路的光程相对于环路静止时都会产生变化。通过检测两条光路的相位差或干涉条纹的变化,即可得到光路旋转的角速度,这就是激光陀螺仪的工作原理。激光陀螺仪的一个缺点是:在很低的速度下会受到锁定现象的影响,从而无法正确检测旋转。

图3 激光陀螺仪原理

3.2 光纤陀螺仪传感器

光纤陀螺仪的实现也基于塞格尼克理论:但它的设计更加巧妙,它直接通过光纤来制造环形介质通道。相比激光陀螺仪,它不需要光学镜的精密加工和光腔的严格密封,而且从根本上避免了激光锁定问题,体积也可以做得更小。

图4 光纤陀螺仪传感器原理

3.3 MEMS陀螺仪传感器

MEMS 陀螺仪是用微机械加工工艺制造的陀螺仪,它通过自身振动引发科里奥利力,从而检测角速度变化。在旋转体系中进行直线运动的质点由于惯性,在旋转体系中直线运动的物体会发生偏移,这个导致偏移产生的 "虚拟" 力便被称为科里奥利力。

图5 科里奥利力产生原理

MEMS陀螺仪通过振动来诱导和探测科里奥利力,从而对角速度进行测量。它精度相对较低,但具有体积小,低成本低功耗,易于集成和数据输出简单的优点,广泛应用在消费级市场。

图6 MEMS陀螺仪工作原理

3.4 四种陀螺仪传感器的比较

图7 陀螺仪传感器特性比较

从三种陀螺仪传感器的比较表格可以看出,激光陀螺仪的精度最高,但是在低速旋转时会有闭锁效应。光纤陀螺仪由于其较低的价格和体积,广泛应用于高精度导航应用。而MEMS陀螺仪结构简单,体积最小,在消费电子中得到广泛的应用。

4、陀螺仪传感器实验演示

我们来演示使用 MCU 读取显示陀螺仪传感器的数据。实验中使用的是一款集成了3轴加速度计和3轴陀螺仪的 MAX6050 传感器,我们屏幕上的立体方块来显示其给出的陀螺仪的数据。可以看到,随着我们改变陀螺仪的位置和角度,立方体也随之发生相同方向的姿态变化,陀螺仪旋转时,方块也同步旋转。

图8 树莓派读取陀螺仪传感器展示

具体代码如下:

python 复制代码
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 )

import time
from math import pi,sin,exp,sqrt,floor,cos
import time, array, uctypes, rp_devices as devs
import mpu6050
#########################################################
###
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

def sine(x,offset):
    return (sin(x/120*pi+offset)+1)*120
############################################################
###
xAxis = machine.ADC(machine.Pin(28))
yAxis = machine.ADC(machine.Pin(29))
st7789_res = 0
st7789_dc  = 1
CENTER_Y = int(disp_width/2)
CENTER_X = int(disp_height/2)
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=62500000, 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)

#############################################################
dis_h = 150
dis_w = 150

dis_buff_0 = array.array('H', (0 for _ in range(dis_h*dis_w*2)))

dis_a=bytearray(150)
dis_b=bytearray(150)
###

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 = 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 = machine.I2C(0,scl=machine.Pin(21), sda=machine.Pin(20))     #initializing the I2C method for ESP32
mpu= mpu6050.accel(i2c)
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
#     display.fill_rect(0,0,100,100,0)
#     display.fill(0)
    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.clear( 0x0000)
mpu_value = {}
display.set_window(125,45,150,150)
spi0.init(bits=16)
while True:

    mpu_value=mpu.get_values()
    drawcube(mpu_value["GyX"]/32767.5,mpu_value["GyY"]/32767.5,mpu_value["GyZ"]/32767.5)
    
    
    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

   

其他相关文件请点此查看

相关推荐
好看资源平台4 分钟前
网络爬虫——综合实战项目:多平台房源信息采集与分析系统
爬虫·python
进击的六角龙25 分钟前
深入浅出:使用Python调用API实现智能天气预报
开发语言·python
檀越剑指大厂26 分钟前
【Python系列】浅析 Python 中的字典更新与应用场景
开发语言·python
湫ccc33 分钟前
Python简介以及解释器安装(保姆级教学)
开发语言·python
孤独且没人爱的纸鹤36 分钟前
【深度学习】:从人工神经网络的基础原理到循环神经网络的先进技术,跨越智能算法的关键发展阶段及其未来趋势,探索技术进步与应用挑战
人工智能·python·深度学习·机器学习·ai
羊小猪~~40 分钟前
tensorflow案例7--数据增强与测试集, 训练集, 验证集的构建
人工智能·python·深度学习·机器学习·cnn·tensorflow·neo4j
lzhlizihang42 分钟前
python如何使用spark操作hive
hive·python·spark
q0_0p43 分钟前
牛客小白月赛105 (Python题解) A~E
python·牛客
极客代码1 小时前
【Python TensorFlow】进阶指南(续篇三)
开发语言·人工智能·python·深度学习·tensorflow
庞传奇1 小时前
TensorFlow 的基本概念和使用场景
人工智能·python·tensorflow