JY901陀螺仪数据的读取与简单数据处理


前言

JY901是维特公司出品的9轴陀螺仪,个人在使用上感觉是十分不错的,他们家的产品都可以使用串口或者IIC来进行数据读取。且内部自带滤波效果,不需要对其数据进行处理,就可以直接使用。
在这里插入图片描述
如果买了他们家产品,应该都有他们家的上位机,这里就不给出链接了,如果有需要私聊。

JY901简单介绍

JY901这款陀螺仪,每次发送出来的数据,可以在上位机中查看,且可以在上位机中选择需要发送出来的数据。
![在这里插入图片描述](https://img-blog.csdnimg.cn/5a8ee36e98f44538ac7d114b2d945228.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2x6enp6enpt,size_16,color_FFFFFF,t_70
我们分析原始数据或者看手册都可以知道,JY901每次发送出来的数据都是11位的,其中第一位位帧头,第二位为判断属于的类型。

一、上位机调试

我们在第一次使用时,记得将陀螺仪水平,然后点击加计校准,来校准陀螺仪。
在这里插入图片描述
我们在上位机中点击配置去修改一下陀螺仪的一些配置参数。
请添加图片描述
这里我将默认9600的波特率改为115200,将陀螺仪发送的内容改为只发送加速度,角速度,欧拉角。
其中加速度的类位为0x51,角速度为0x52,欧拉角为0x53

波特率看你通信需求,如果需要比较高速的情况,建议改为115200.
发送内容也是看需求勾选,然后到时候在代码那里做一点相应的修改即可。

二、Cubemax配置

我这里是直接使用了我之前配置用来和Openmv 通信的配置,详情请看下面这篇博客。
STM32 Cubemax(四) —— STM32利用DMA空闲中断与Openmv通信
配置是一模一样的!

三、代码

我们这里代码主要需要更改的就是接收的结构体,和处理函数。

包含官方JY901.h文件

#ifndef __JY901_H
#define __JY901_H

#define SAVE 			0x00
#define CALSW 		0x01
#define RSW 			0x02
#define RRATE			0x03
#define BAUD 			0x04
#define AXOFFSET	0x05
#define AYOFFSET	0x06
#define AZOFFSET	0x07
#define GXOFFSET	0x08
#define GYOFFSET	0x09
#define GZOFFSET	0x0a
#define HXOFFSET	0x0b
#define HYOFFSET	0x0c
#define HZOFFSET	0x0d
#define D0MODE		0x0e
#define D1MODE		0x0f
#define D2MODE		0x10
#define D3MODE		0x11
#define D0PWMH		0x12
#define D1PWMH		0x13
#define D2PWMH		0x14
#define D3PWMH		0x15
#define D0PWMT		0x16
#define D1PWMT		0x17
#define D2PWMT		0x18
#define D3PWMT		0x19
#define IICADDR		0x1a
#define LEDOFF 		0x1b
#define GPSBAUD		0x1c

#define YYMM				0x30
#define DDHH				0x31
#define MMSS				0x32
#define MS					0x33
#define AX					0x34
#define AY					0x35
#define AZ					0x36
#define GX					0x37
#define GY					0x38
#define GZ					0x39
#define HX					0x3a
#define HY					0x3b
#define HZ					0x3c			
#define Roll				0x3d
#define Pitch				0x3e
#define Yaw					0x3f
#define TEMP				0x40
#define D0Status		0x41
#define D1Status		0x42
#define D2Status		0x43
#define D3Status		0x44
#define PressureL		0x45
#define PressureH		0x46
#define HeightL			0x47
#define HeightH			0x48
#define LonL				0x49
#define LonH				0x4a
#define LatL				0x4b
#define LatH				0x4c
#define GPSHeight   0x4d
#define GPSYAW      0x4e
#define GPSVL				0x4f
#define GPSVH				0x50
#define q0          0x51
#define q1          0x52
#define q2          0x53
#define q3          0x54
      
#define DIO_MODE_AIN 0
#define DIO_MODE_DIN 1
#define DIO_MODE_DOH 2
#define DIO_MODE_DOL 3
#define DIO_MODE_DOPWM 4
#define DIO_MODE_GPS 5		

struct STime
{
	unsigned char ucYear;
	unsigned char ucMonth;
	unsigned char ucDay;
	unsigned char ucHour;
	unsigned char ucMinute;
	unsigned char ucSecond;
	unsigned short usMiliSecond;
};
struct SAcc
{
	short a[3];
	short T;
};
struct SGyro
{
	short w[3];
	short T;
};
struct SAngle
{
	short Angle[3];
	short T;
};
struct SMag
{
	short h[3];
	short T;
};

struct SDStatus
{
	short sDStatus[4];
};

struct SPress
{
	long lPressure;
	long lAltitude;
};

struct SLonLat
{
	long lLon;
	long lLat;
};

struct SGPSV
{
	short sGPSHeight;
	short sGPSYaw;
	long lGPSVelocity;
};
struct SQ
{ short q[4];
};
 
#endif

创建接收结构体和定义一些参数

#define RXBUFFER_LEN 33		//接收3类数据,一共33位

typedef struct
{
	float angle[3];
}Angle;

typedef struct
{
	float a[3];
}Acc;

typedef struct
{
	float w[3];
}SGyro;

typedef struct User_USART
{
		uint8_t Rx_flag;											
		uint8_t Rx_len;												
		uint8_t frame_head;					//帧头
		uint8_t RxBuffer[RXBUFFER_LEN];		//接收缓冲
		Angle angle;						//角度
		Acc acc;							//加速度
		SGyro w;							//角速度
}User_USART;

接收处理函数编写和结构体初始化函数

User_USART JY901_data;
struct SAcc 		stcAcc;
struct SGyro 		stcGyro;
struct SAngle 	stcAngle;

//接收结构体初始化
void User_USART_Init(User_USART *Data)
{
		for(uint16_t i=0; i < RXBUFFER_LEN; i++)	Data->RxBuffer[i] = 0;
		Data->frame_head = 0x55;
		Data->Rx_flag = 0;
		Data->Rx_len = 0;
}

void JY901_Process()
{
		if(JY901_data.Rx_len < RXBUFFER_LEN) return;   	//如果位数不对

		for(uint8_t i=0;i<4;i++)
		{
				if(JY901_data.RxBuffer[i*11]!= JY901_data.frame_head) return;	//如果帧头不对
				switch(JY901_data.RxBuffer[i*11+1])
				{
						case 0x51:	
							memcpy(&stcAcc,&JY901_data.RxBuffer[2 + i*11],8);
							for(uint8_t j = 0; j < 3; j++) JY901_data.acc.a[j] = (float)stcAcc.a[j]/32768*16;									//官方加速度解算
						break;
						case 0x52:	
							memcpy(&stcGyro,&JY901_data.RxBuffer[2 + i*11],8);
							for(uint8_t j = 0; j < 3; j++) JY901_data.w.w[j] = (float)stcGyro.w[j]/32768*2000;								//官方角速度解算
						break;
						case 0x53:	
							memcpy(&stcAngle,&JY901_data.RxBuffer[2 + i*11],8);
							for(uint8_t j = 0; j < 3; j++) JY901_data.angle.angle[j] = (float)stcAngle.Angle[j]/32768*180;		//官方角度解算
						break;
				}
				
		}

}

一些细节的修改

只需要把我那篇文章里的OpennMv_Data相关的内容都改成JY901_data和把处理函数OpenMvData_Process改成JY901_Process即可

实验结果

可以完美的读出角度,加速度,角加速度的值
请添加图片描述

总结

因为没有贴出比较详细的配置和代码,但大家只要看懂我那篇Openmv通信的代码配置后,根据其做一些代码修改和移植,是可以正常读出数据的。
完整工程代码下面自取:代码仓库

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐