七校联赛题铅笔姿态及笔迹检测装置--mpu6050识别数字

前言

        前几天打完比赛,收获还是挺大的,数字识别部分基本上浪费了绝大部分时间。先将思路简单说明。

1、题目

2、思路

        针对笔迹检测,我们首先考虑的肯定是陀螺仪来测量加速度方向来判断书写的方向,从而得到书写的数字。

        我们的方案是不断记录四个方向的加速度最大值,如果有某个方向的最大值最先达到某个阈值,则判定在该方向上移动。

        但在实际测量的时候会遇到两个问题:

        ①:重力加速度的影响,因为陀螺仪本身会有z轴向下的重力加速度,在书写时难免会有倾斜,而且书写的时候加速度本身就很小,约0.2左右,就会导致重力加速度在x轴或y轴上的分量影响很大;

        ②:在书写的时候,由于惯性,会产生一个反方向的加速度,这个加速度也比较影响书写方向的判断;

        解决方案:

        针对问题①,解决方案也很明显,因为陀螺仪本身就可以检测自身角度,我们只需要根据角度计算出水平方向的分量再将它减掉就行(fAcc[0]表示x轴加速度,fAcc[1]表示y轴加速度)

fAcc[0]=fAcc[0]+sin(fAngle[1]*(M_PI/180));
fAcc[1]=fAcc[1]-sin(fAngle[0]*(M_PI/180));

        针对问题②,我们最终还是没解决,所以我们索性直接判断两个方向,即x轴和y轴。

        识别的思路是:如果笔是倾斜的,会进入一个循环开始不断读取mpu6050数据,如果识别到某个方向移动,则进入另一个循环,如果笔竖直,则退出此循环,并返回该方向。这便记作判断画了一笔,最后根据笔画方向排序判断数字。

void task_4(void)//功能4
{
	int i=0,direction_now=0;
	
	// 初始化数组
//    memset(shu, 0, sizeof(shu));
	
	while(1)
	{
		direction_now=get_direction();
		if(direction_now==1){
			shu[i++]='x';
			u3_printf("page4.t3.txt=\"X\"\xff\xff\xff");
			u3_printf("page4.n1.val=%d\xff\xff\xff",i);
		}else if(direction_now==2){
			shu[i++]='y';
			u3_printf("page4.t3.txt=\"Y\"\xff\xff\xff");
			u3_printf("page4.n1.val=%d\xff\xff\xff",i);
		}else{
			u3_printf("page4.t3.txt=\"error\"\xff\xff\xff");
			break;
		}
		u3_printf("page4.r0.val=0\xff\xff\xff");
		
		printf("第%d次书写成功,书写内容为%d\r\n,",i,direction_now);
	}
	show_num=number_ordinary();
	u3_printf("page4.n0.val=%d\xff\xff\xff",show_num);
	
}
//用来检测笔的移动方向
//返回0~2,表示2个方向
int get_direction(void)
{
	float accX;
    float accY;
    float maxAccX=0.0,minAccX=0.0;
	float maxAccY=0.0,minAccY=0.0;
	
	//进行清零
	count[0] = 0.0;
	count[1] = 0.0;

    printf("开始书写\r\n");
    printf("%f\r\n", rangle);
    
    while (rangle > 15 )
    {
        gryo_get(); // 获取传感器数据
        rangle = 39 - fAngle[0]; // 计算角度
		if(rangle>50){
			continue;
		}
        // 获取当前加速度值
        accX = fAcc[0];
        accY = fAcc[1];

        // 更新 x 轴的最大值和最小值
        if (accX > maxAccX) {
            maxAccX = accX;
        }
        if (accX < minAccX) {
            minAccX = accX;
        }

        // 更新 y 轴的最大值和最小值
        if (accY > maxAccY) {
            maxAccY = accY;
        }
        if (accY < minAccY) {
            minAccY = accY;
        }
		printf("maxAccX = %f mixAccX = %f  maxAccY = %f mixAccY = %f\r\n",maxAccX,minAccX,maxAccY,minAccY);
		if (max(maxAccX,minAccX) > max(maxAccY,minAccY) && max(maxAccX,minAccX) > 0.25) {
			while (rangle<70) {
				u3_printf("page4.r0.val=1\xff\xff\xff");
				u3_printf("page6.r0.val=1\xff\xff\xff");
				gryo_get(); // 获取传感器数据
				rangle = 39 - fAngle[0]; // 计算角度
			}
			return 2;
		} else if ( max(maxAccY,minAccY) > max(maxAccX,minAccX) && max(maxAccY,minAccY) > 0.25){
			while (rangle<70) {
				u3_printf("page4.r0.val=1\xff\xff\xff");
				u3_printf("page6.r0.val=1\xff\xff\xff");
				gryo_get(); // 获取传感器数据
				rangle = 39 - fAngle[0]; // 计算角度
			}
			return 1;
		}
		delay_ms(50);
	}
    return 0; // 未检测到显著的运动方向
}

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值