聚丰项目 > 基于AB32VG1的姿态检测

基于AB32VG1的姿态检测

本项目基于中科蓝汛AB32VG1开发板,制作了一个姿态检测系统。维特智能的高精度姿态传感器JY901S模块,该集成高精度的陀螺仪、加速度计、地磁场传感器,采用高性能的微处理器和先进的动力学解算与卡尔曼动态滤波算法,能够快速求解出模块当前的实时运动姿态。模块支持IIC和串口两种数字接口,本设计应用串口接口完成姿态传感器与开发板的通信。显示屏选择0.96寸IIC通信的OLED屏,对读取到的姿态角度进行显示。

ELECFANS_WYC ELECFANS_WYC

分享
0 喜欢这个项目
团队介绍

ELECFANS_WYC ELECFANS_WYC

团队成员

ELECFANS_WYC 电子爱好者

分享
项目简介
本项目基于中科蓝汛AB32VG1开发板,制作了一个姿态检测系统。维特智能的高精度姿态传感器JY901S模块,该集成高精度的陀螺仪、加速度计、地磁场传感器,采用高性能的微处理器和先进的动力学解算与卡尔曼动态滤波算法,能够快速求解出模块当前的实时运动姿态。模块支持IIC和串口两种数字接口,本设计应用串口接口完成姿态传感器与开发板的通信。显示屏选择0.96寸IIC通信的OLED屏,对读取到的姿态角度进行显示。
硬件说明

1、OLED:PE3--OLED_SCL、PE2--OLED_SDA、电源引脚;

image.png

2、JY901S(九轴姿态传感器)

    2.1 引脚说明:PA3--JY_TX、PA4--JY_RX、电源引脚。

image.png

image.png

        2.2、性能参数

            电压:3.3V~5V;电流:<25mA;

            测量维度:加速度-3维,角速度-3维,磁场-3维;

            量程:加速度:±2/4/8/16g,角速度:±250/500/1000/2000°/s,角度X、Z轴±180°,Y轴±90°。磁场:30Gauss;

            稳定性:加速度:0.01g,角速度0.05°/s。

            姿态测量稳定度:0.01°。


软件说明

软件框架:软件部分使用到了板卡的USART1和IIC两种通信,首先对两个模块初始化,然后开启按协议接收串口数据线程和OLED显示线程。流程图如下所示。

image.png

软件流程图

USART1配置:

image.png



协议说明:

角度输出 

0x550x53RollLRollHPitchLPitchHYawLYawHVLVHSUM
帧头功能data1Ldata1Hdata2Ldata2Hdata3Ldata3HVersionHVersionL校验和

计算方法:

俯仰角(y轴)Pitch=((PitchH<<8)|PitchL)/32768*180(°)

Version=(VH<<8)|VL

Sum=0x55+0x53+RollH+RollL+PitchH+PitchL+YawH+YawL+VH+VL


姿态传感器向上位机传输数据使用了基于串口的特定协议,一帧数据中包含帧头、功能字节、数据字节、版本信息和校验字节。因此编写串口读取程序时应按照如下逻辑:首先寻找帧头,然后匹配功能字节来判断此帧数据为什么内容,接着接收接下来的若干字节数据,最后根据校验字节校验数据是否接收正确。流程如下图所示:

image.png

串口读取协议流程图

串口1数据读取(含JY901S串口数据读取协议):

//串口1数据读取线程入口

static void serial_thread_entry(void *parameter)

{

    uint8_t Res_U3;

    uint8_t Sum_U3=0,i_U3;

    while (1)

    {

        /* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */

        while (rt_device_read(serial, -1, &Res_U3, 1) != 1)

        {

            /* 阻塞等待接收信号量,等到信号量后再次读取数据 */

            rt_sem_take(&rx_sem, RT_WAITING_FOREVER);

        }

        /* 读取到的数据输出 */

        //rt_kprintf("%c",Res_U3);



        if((USART3_REC_STA&0x8000)==0)//接收未完成

        {

            if((USART3_REC_STA&0x00FF)>11)//数据长度出错

            {

                USART3_REC_STA=0;////接收错误,重新接收

                //rt_kprintf("->1\n");

            }

            else

            {

                if((USART3_REC_STA&0x4000)==0)//未接收到帧头

                {

                    if(Res_U3==0x55) //本字节为帧头

                    {

                        USART3_REC_STA |= 0x4000;

                        USART3_REC_BUF[USART3_REC_STA&0x00FF]=Res_U3;

                        USART3_REC_STA++;

                        //rt_kprintf("->2\n");

                    }

                    else {

                        //rt_kprintf("->3\n");

                    }

                }

                else//已接收到帧头

                {

                    if((USART3_REC_STA&0x2000)==0)//未接收到标识字节

                    {

                        if((Res_U3==0x53)||(0))//本字节为标识字节  (Res_U3==0x54)

                        {

                            USART3_REC_STA |= 0x2000;

                            USART3_REC_BUF[USART3_REC_STA&0x00FF]=Res_U3;

                            USART3_REC_STA++;

                            //rt_kprintf("->4\n");

                        }

                        else

                        {

                            USART3_REC_STA=0;//接收错误,重新接收

                            //rt_kprintf("->5  Res_U3=%X\n",Res_U3);

                        }

                    }

                    else//已接收到标识字节

                    {

                        if((USART3_REC_STA&0x00FF)<11)//

                        {

                            USART3_REC_BUF[USART3_REC_STA&0x00FF]=Res_U3;

                            USART3_REC_STA++;

                            //rt_kprintf("->6\n");

                            if((USART3_REC_STA&0x00FF)==11)

                            {

                                //求和

                                Sum_U3=0;//清零

                                for(i_U3=0;i_U3<10;i_U3++)

                                {

                                    Sum_U3=(uint8_t)(Sum_U3+USART3_REC_BUF[i_U3]);

                                }

                                //校验和

                                if(Sum_U3==USART3_REC_BUF[10])

                                {

                                    USART3_REC_STA |= 0x8000;//校验和成功,接收完成

                                    //rt_kprintf("rec success!\n");


                                }

                                else

                                {

                                    USART3_REC_STA=0;//校验和失败,重新接收

                                    //rt_kprintf("->7\n");

                                }

                            }

                        }

                        else {

                            //rt_kprintf("->8\n");

                        }

                    }

                }

            }


        }

    }

}



姿态传感器数据分析:

//数据分析函数

void Data_analysis(uint8_t fun_byte)

{

    uint8_t DataH,DataL;

    if((USART3_REC_STA&0x8000)==0) return;

    switch(fun_byte)

    {

    case 0x53:

    {

        Roll_X= ((short)((USART3_REC_BUF[3]<<8)|USART3_REC_BUF[2]))/32768.0*180;

        Pitch_Y=((short)((USART3_REC_BUF[5]<<8)|USART3_REC_BUF[4]))/32768.0*180;

        Yaw_Z=  ((short)((USART3_REC_BUF[7]<<8)|USART3_REC_BUF[6]))/32768.0*180;

    }break;

    default :USART3_REC_STA=0;break;

    }

}


IIC OLED配置:

image.png

image.png

image.png

OLED姿态数据显示:

static void thread_usart1_recsho(void *parameter)

{


    while(1)

    {

        if(USART3_REC_STA&0x8000)//接收完成

        {

            Data_analysis(USART3_REC_BUF[1]);

            sprintf((char*)print_str,"%3.1f",Roll_X);

            ssd1306_SetCursor(66,8);

            ssd1306_WriteString(print_str,Font_11x18,White);

            sprintf((char*)print_str,"%3.1f",Pitch_Y);

            ssd1306_SetCursor(66,8+18);

            ssd1306_WriteString(print_str,Font_11x18,White);

            sprintf((char*)print_str,"%3.1f",Yaw_Z);

            ssd1306_SetCursor(66,8+18+18);

            ssd1306_WriteString(print_str,Font_11x18,White);

            ssd1306_UpdateScreen();

            /*

            sprintf((char*)print_str,"Roll_X:%3.1f\n",Roll_X);

            rt_kprintf("%s",print_str);

            sprintf((char*)print_str,"Pitch_Y:%3.1f\n",Pitch_Y);

            rt_kprintf("%s",print_str);

            sprintf((char*)print_str,"Yaw_Z:%3.1f\n",Yaw_Z);

            rt_kprintf("%s",print_str);*/

            USART3_REC_STA=0;

        }

        rt_thread_mdelay(10);

    }

}




演示效果

效果演示:

代码见附件。

附件

(11.74 MB)下载

评论区(2 )
  • 幽幽鹿鸣: 代码缩水,没用

    回复

    • ELECFANS_WYC: 好的亲,我改改。

      回复