首页 > 其他分享 >树莓派4B-用串口读取JY901S陀螺仪数据

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

时间:2024-07-09 16:30:15浏览次数:17  
标签:acc 树莓 angle gyro datahex Bytenum JY901S 串口 data

相关知识介绍

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

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!')

标签:acc,树莓,angle,gyro,datahex,Bytenum,JY901S,串口,data
From: https://www.cnblogs.com/kevenduan/p/18292231

相关文章

  • 串口通信&控制LED
    目录1.串口介绍2.硬件电路3.电平标准4.接口及引脚定义5.常见通信接口比较6.51单片机的UART7.串口参数及时序图8.串口模式图9.串口和中断系统10.串口相关寄存器11.串口向电脑发送数据12.电脑通过串口控制LED1.串口介绍串口是一种应用十分广泛的......
  • 树莓派4B-PCA9685驱动舵机
    前言不知道你们有没有遇到过这么一种情况,直接用树莓派的引脚输出PWM控制舵机,舵机是会出现抖动的。就算代码进行一定的时延迟优化还是会有影响的。现在我们可以使用PCA9685这个模块去驱动舵机。PCA9685是一种常用的PWM(脉冲宽度调制)驱动器芯片,通常用于控制舵机、电机和其他需要......
  • stm32串口接受定长和不定长数据的两种中断方式
    stm32串口有两种中断方式1.字节中断(定长数据接受)接收指定字节数的数据后产生中断:HAL_UART_Receive_IT(&huart3,rxBuffer,21);注意这里仍然是接受一个字节进入一次IRQ中断函数,这里指定的字节数指的是接受指定字节数量后进入一次回调函数,由于IRQ函数会关闭中断,如需重复接受定......
  • 通信方式中常用的串口,你真的了解么?
    串口介绍一、引言串行接口(SerialPort),简称串口,是计算机与外部设备或其他计算机之间进行数据交换的一种通信接口。与并行通信相比,串行通信通过一条或几条信号线按顺序传输数据,具有接口简单、传输距离长等优点。串口在计算机历史中占据了重要位置,即便在今天,许多工业控制系统、......
  • 串口电平多种,TLL、232、485、422到底应该如何选择?
    串口通信是电子设备之间进行数据交换的重要方式,其中常见的电平标准包括TTL电平、RS-232电平、RS-485电平和RS-422电平。本文将详细介绍这些电平的由来、原理、特点、优缺点、应用、实现方式及接线方式,帮助各位同学或工程师更好地理解这些通讯基础。TTL电平TTL(Transistor......
  • stm32串口 环形缓冲区 代码
    voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart){ //printf("ITIN\r\n");// printf("%d\r\n",HAL_GetTick()); //置零设定电流值PID时间if(huart->Instance==USART3){ //将数据放入缓冲区 circular_buffer.buffe......
  • 树莓派5 — 官方Raspberry Pi OS — OpenCV图像处理 — 1
    引言一名视觉入门选手,在校生大一,了解OpenCV的皮毛。撰写此文,一是为了分享内容,帮助后来人;二更是为了能吸引大佬能给我提出我在学习上的建议和问题。说明环境:树莓派5  官方操作系统RaspberryPiOS  OpenCV  Python语言  CSI500万摄像头内容:树莓派5安装OpenCV,调......
  • 树莓派学习笔记18:IIC驱动_PCA9685(16路舵机驱动模块)
    今日继续学习树莓派4B4G:(RaspberryPi,简称RPi或RasPi)本人所用树莓派4B装载的系统与版本如下: 版本可用命令(lsb_release-a)查询:​​ Python版本3.7.3:​​ IIC驱动_PCA9685(16路舵机驱动模块)文章提供测试代码讲解,整体代码贴出、测试效果图目录 开启树......
  • 树莓派与无人机通信有关操作
    草稿本我们执行的python脚本是在树莓派系统上,而SITL仿真环境是搭建在笔记本系统上的。第一步连接网络通过ssh链接到树莓派端[email protected]切换到对应文件夹cdtest编辑对应py文件(可选)sudovimexample2.py执行对应python程序//读取无人机的信息(可选)pytho......
  • stm32学习笔记---USART串口数据包(代码部分)串口收发HEX数据包/文本数据包
    目录第一个代码:串口收发HEX数据包Serial.cSerial.hMain.c第二个程序:串口收发文本数据包Serial.cSerial.hMain.c声明:本专栏是本人跟着B站江科大的视频的学习过程中记录下来的笔记,我之所以记录下来是为了方便自己日后复习。如果你也是跟着江科大的视频学习的,可以配套......