当前位置: 首页 > article >正文

树莓派4B-用串口读取JY901S陀螺仪数据

相关知识介绍

陀螺仪是一种用来感测与维持方向的装置,基于角动量的理论设计出来的。陀螺仪主要是由一个位于轴心可以旋转的轮子构成,陀螺仪一旦开始旋转,由于轮子的「角动量」,陀螺仪有抗拒方向改变的趋向。陀螺仪多用于导航、定位等系统

JY901S是9轴姿态角度传感器,支持串口和 IIC 两种数字接口。串口速率2400bps~921600bps 可调, IIC 接口支持全速 400K 速率,本文均是使用串口。

9轴分别为加速度传感器(即加速计)、角速度传感器(即陀螺仪)、磁感应传感器(即电子罗盘)。

连接说明

我是用的USB转TTL电平串口模块与树莓派连接,用的型号是CH340。

在windows电脑上的端口号都是ComX,在Liunx系统下的端口号如果是直接插在树莓派USB接口上的话就是写

‘/dev/ttyAMA0’否则就是’/dev/ttyAMA0’,具体如下。

port = '/dev/ttyUSB0' # use '/dev/ttyAMA0' for USB or '/dev/ttyAMA0' for GPIO

注意:RX和TX是需要反着接的,无论是直接连在GPIO上还是用USB转TTL,否则会出现问题。

轴向说明

如上图所示,模块的轴向在上图的右上方,向右为 X 轴,向上 Y 轴,垂直模块向外为 Z 轴。旋转的方向按右手法则定义,即右手大拇指指向轴向,四指弯曲的方向即为绕该轴 旋转的方向。X 轴角度即为绕 X 轴旋转方向的角度,Y 轴角度即为绕 Y 轴旋转方向的角度, Z 轴角度即为绕 Z

测试结果

完整代码

#coding:UTF-8
import serial
 
ACCData=[0.0]*8
GYROData=[0.0]*8
AngleData=[0.0]*8          
FrameState = 0            #通过0x后面的值判断属于哪一种情况
Bytenum = 0               #读取到这一段的第几位
CheckSum = 0              #求和校验位         
 
a = [0.0]*3
w = [0.0]*3
Angle = [0.0]*3

def DueData(inputdata):   #新增的核心程序,对读取的数据进行划分,各自读到对应的数组里
    global  FrameState
    global  Bytenum
    global  CheckSum
    global  a
    global  w
    global  Angle
    for data in inputdata:  #在输入的数据进行遍历
        # print(inputdata)
        # print(data, type(data))
        if FrameState==0:   #当未确定状态的时候,进入以下判断
            if data ==0x55 and Bytenum==0: #0x55位于第一位时候,开始读取数据,增大bytenum
                CheckSum=data
                Bytenum=1
                continue
            elif data==0x51 and Bytenum==1:#在byte不为0 且 识别到 0x51 的时候,改变frame
                CheckSum+=data
                FrameState=1
                Bytenum=2
            elif data==0x52 and Bytenum==1: #同理
                CheckSum+=data
                FrameState=2
                Bytenum=2
            elif data==0x53 and Bytenum==1:
                CheckSum+=data
                FrameState=3
                Bytenum=2
        elif FrameState==1: # acc    #已确定数据代表加速度
            
            if Bytenum<10:            # 读取8个数据
                ACCData[Bytenum-2]=data # 从0开始
                CheckSum+=data
                Bytenum+=1
            else:
                if data == (CheckSum&0xff):  #假如校验位正确
                    a = get_acc(ACCData)
                CheckSum=0                  #各数据归零,进行新的循环判断
                Bytenum=0
                FrameState=0
        elif FrameState==2: # gyro
            
            if Bytenum<10:
                GYROData[Bytenum-2]=data
                CheckSum+=data
                Bytenum+=1
            else:
                if data == (CheckSum&0xff):
                    w = get_gyro(GYROData)
                CheckSum=0
                Bytenum=0
                FrameState=0
        elif FrameState==3: # angle
            
            if Bytenum<10:
                AngleData[Bytenum-2]=data
                CheckSum+=data
                Bytenum+=1
            else:
                if data == (CheckSum&0xff):
                    Angle = get_angle(AngleData)
                    d = a+w+Angle
                    print("a(g):%10.3f %10.3f %10.3f w(deg/s):%10.3f %10.3f %10.3f Angle(deg):%10.3f %10.3f %10.3f"%d)
                CheckSum=0
                Bytenum=0
                FrameState=0
 
 
def get_acc(datahex):  
    axl = datahex[0]                                        
    axh = datahex[1]
    ayl = datahex[2]                                        
    ayh = datahex[3]
    azl = datahex[4]                                        
    azh = datahex[5]
    
    k_acc = 16.0
 
    acc_x = (axh << 8 | axl) / 32768.0 * k_acc
    acc_y = (ayh << 8 | ayl) / 32768.0 * k_acc
    acc_z = (azh << 8 | azl) / 32768.0 * k_acc
    if acc_x >= k_acc:
        acc_x -= 2 * k_acc
    if acc_y >= k_acc:
        acc_y -= 2 * k_acc
    if acc_z >= k_acc:
        acc_z-= 2 * k_acc
    
    return acc_x,acc_y,acc_z
 
def get_gyro(datahex):                                      
    wxl = datahex[0]                                        
    wxh = datahex[1]
    wyl = datahex[2]                                        
    wyh = datahex[3]
    wzl = datahex[4]                                        
    wzh = datahex[5]
    k_gyro = 2000.0
 
    gyro_x = (wxh << 8 | wxl) / 32768.0 * k_gyro
    gyro_y = (wyh << 8 | wyl) / 32768.0 * k_gyro
    gyro_z = (wzh << 8 | wzl) / 32768.0 * k_gyro
    if gyro_x >= k_gyro:
        gyro_x -= 2 * k_gyro
    if gyro_y >= k_gyro:
        gyro_y -= 2 * k_gyro
    if gyro_z >=k_gyro:
        gyro_z-= 2 * k_gyro
    return gyro_x,gyro_y,gyro_z
 
 
def get_angle(datahex):                                 
    rxl = datahex[0]                                        
    rxh = datahex[1]
    ryl = datahex[2]                                        
    ryh = datahex[3]
    rzl = datahex[4]                                        
    rzh = datahex[5]
    k_angle = 180.0
 
    angle_x = (rxh << 8 | rxl) / 32768.0 * k_angle
    angle_y = (ryh << 8 | ryl) / 32768.0 * k_angle
    angle_z = (rzh << 8 | rzl) / 32768.0 * k_angle
    if angle_x >= k_angle:
        angle_x -= 2 * k_angle
    if angle_y >= k_angle:
        angle_y -= 2 * k_angle
    if angle_z >=k_angle:
        angle_z-= 2 * k_angle
 
    return angle_x,angle_y,angle_z
 
 
if __name__=='__main__': 
    port = '/dev/ttyUSB0' # use '/dev/ttyAMA0' for USB or '/dev/ttyAMA0' for GPIO
    baud = 9600 # baudrate
    ser = serial.Serial(port, baud, timeout=0.5)  # ser = serial.Serial('com7',115200, timeout=0.5) 
    if ser.is_open:
        print('The serial port was opened successfully!')
        while True:
            datahex = ser.read(33) # How many bytes are read from the port
            DueData(datahex)
    else:
        print('Failed to open the serial!')

http://www.kler.cn/news/354552.html

相关文章:

  • JNI是什么
  • vue综合指南(六)
  • 自动化工具:Ansible
  • 基于腾讯云的AI视频课程制作工具
  • 如何在Python中编写自定义上下文管理器?
  • 【AIGC】让AI像人一样思考和使用工具,reAct机制详解
  • 基于Springboot+Vue的农业收成管理系统(含源码数据库)
  • SpringBoot驱动的高校学科竞赛平台开发指南
  • HarmonyOS NEXT开发 ArkTS自定义组件
  • OPENSSL-2023/10/31学习记录(单向散列函数)
  • 【网络安全】-web安全-基础知识梳理
  • Junit单元测试时提示:Method should have no parameters
  • qiankun 应用之间数据传递
  • linux 开发机与测试机建立 ssh 隧道
  • Vue3的Composition组合式API(computed计算属性、watch监视属性、watchEffect函数)
  • TDengine 3.3.3.0 发布:新增 MySQL 函数与 MongoDB 数据源支持
  • 鸿蒙网络编程系列7-TLS安全数据传输单向认证示例
  • c# FrozenDictionary
  • 基于php的网上购物商场的设计
  • Java第二阶段---09类和对象---第一节 类和对象