3928浏览
查看: 3928|回复: 7

[项目] 妈妈再也不用担心我歪头了—斜视矫正器 基于Beetle、BNO055

[复制链接]



微信图片_20210315200153.jpg


#项目起源#
雷宇激光的陈典满老师是我的好朋友也是好大哥,他家的大公子上二年级,有一次聊天时说起大公子有点斜视,具体表现出来的现象就是看电视或者看黑板不由自主的转头斜着看,于是就与他一起合作共同为孩子制作了一个辅助矫正用眼姿势的眼镜,这一期旺仔爸爸就来介绍一下这个作品
先来欣赏一下演示视频
#方案介绍#
目前存在的问题:孩子在看电视或者看黑板的时候不由自主的把头转过去斜着看
想到的解决思路:当出现不由自主转头的动作时提醒孩子这个动作是不对的,及时纠正过来
问题的关键点:如何检测头部动作
设计方案:制作一个可以检测头部动作并具有遮挡视线功能的眼镜,当孩子正视前方时可以正常使用眼镜,当孩子头转向一侧时眼镜视线被遮挡,看不到前方
演示.gif


那么到底该如何检测头部动作呢,其实智能手机、平衡车或者无人机设备中会使用这样的传感器,一般称之为姿态传感器或者加速度传感器,比较常用的是MPU6050三轴加速度、三轴陀螺仪传感器,通常会再配合一个地磁传感器就可以精确计算姿态角,姿态角也就是由x、y、z 轴组成的立体空间中被测物体与水平面的倾角,即俯仰角 Pitch、翻滚角 Roll、偏航角 Yaw,本次作品我们只用到了翻滚角,这么多专业名词看不懂没关系,后面程序设计中我们再做详细介绍
下图为MPU6050模块和在立体空间中的状态图
微信图片_202103152001531.jpg


MPU6050模块基本上满足我们的需求,可以作为选择之一
除此之外,旺仔爸爸还找到一款自带地磁传感器的模块,是由DFRobot生产的BON055九轴加速度传感器,它的尺寸仅为5.2 x 3.8 x 1.1mm³,它相比较MPU6050模块来说有16位陀螺仪、14位加速度还有地磁传感器和一个自带算法处理的32位微控制器,通过混合传感器数据可以实现智能9轴绝对定向,它既可单独提供三类传感器(加速度/地磁/陀螺仪)的单一数据,亦可提供组合数据,例如欧拉向量绝对方位、四元素绝对方位、旋转矢量、线性加速度、重力、朝向等。通过内置MCU计算,省略了繁琐的算法处理,为智能手机、穿戴设备等产品提供更多方面的应用支持。
概括总结一下就是具有体积小、算法简单、功能强大的特点,综合比较本次作品我们采用BNO055作为头部动作检测的传感器
微信图片_202103152001532.jpg


想要更全面的了解BNO055传感器的伙伴可以参考下面的官方文档
另一个需要隆重介绍的是非常小巧的Beetle控制器,它的尺寸只有20mm X 22mm,它是采用ATmega32u4作为MCU的控制器,引脚功能和使用方法与Arduino leonardo系列的控制器基本相同,即插即用,特别方便,而且体积小这个特点对于本次作品来说太重要了
详细介绍文档可以点击下方链接了解
微信图片_202103152001533.jpg


全面了解了两个重要“角色”后,只需要再配合舵机就可以实现功能了,你一定特别期待眼镜是怎么制作的吧,下面我们马上开始
#设计制作#
#结构设计#
使用lasermaker计算机辅助设计软件设计图纸,材料选用2mm亚克力和3mm椴木板,采用护目镜作为眼镜的主体框架
装置分两部分组成,眼镜框架和视线遮挡部分,下面是设计图纸
微信图片_202103152001534.jpg


利用激光切割机加工后的结构如下图所示
微信图片_202103152001535.jpg


#硬件清单#
Beetle控制器*1
BNO055 9轴加速度传感器*1
9g舵机*1
500ma3.7V锂电池*1(602530分别表示长宽厚)
充放电模块*1
microusb母口*1
开关*1
护目眼镜*1
3mm椴木板
2mm亚克力板
金属小合页*1
五金件若干
微信图片_202103152001536.jpg



#电路设计#
本次我们要制作成一款可穿戴的眼镜,除了选用比较小巧的Beetle控制器和9轴加速度传感器之外,我们还需要电源管理模块和舵机,电路接下图如下
微信图片_202103152001537.jpg


引脚定义
微信图片_202103152001538.jpg


#组装#
我们把本次装置分成视线遮挡结构和眼镜框架两部分,视线遮挡部分采用了重量较轻的椴木板材料,眼镜框架采用了比较结实易折弯的亚克力材料,控制器、传感器、执行器安装在眼镜框架结构中,电源部分安装在视线遮挡板中
视线遮挡板由四块椭圆形的椴木板、两个亚克力边框以及一个框架构成
下图为椭圆形的视线遮挡板
微信图片_202103152001539.jpg


框架与椭圆形的遮挡板安装在一起的正面图,中间预留的两个孔用来安装金属合页
微信图片_2021031520015310.jpg


从背面图中可以看出椭圆形的遮挡板和框架正好构成了一个可以放置电源模块的空间
微信图片_2021031520015311.jpg


接下来我们就可以将锂电池放入遮挡板中了
微信图片_2021031520015312.jpg


电池放置好后就可以在上面封装一层椭圆形的椴木板,电源线从预留孔中穿出
微信图片_2021031520015313.jpg


然后,将microusb母座安装在右侧
微信图片_2021031520015314.jpg


microusb的充电孔正好从亚克力边框的边缘漏出
微信图片_2021031520015315.jpg


将开关、microusb充电接口与充电模块焊接在一起
微信图片_2021031520015316.jpg


最后封上右侧的椭圆形椴木板,并将电池与充电电路穿出的电源线连接在一起,而上方剩下的灰、红两根电源线则是给控制器供电
微信图片_2021031520015317.jpg


接下来焊接主控和9轴加速度传感器,接线方式参照前面的电路图和引脚定义
微信图片_2021031520015318.jpg


焊接好后将控制器和传感器安装在眼镜框架的右侧
微信图片_2021031520015319.jpg


将9g舵机安装在眼镜框架的左侧(其实这里还可以使用重量更轻的舵机,这次先测试,后面再改进)
微信图片_2021031520015320.jpg


使用金属合页将眼镜框架与遮挡板连接
微信图片_2021031520015321.jpg


使用铁丝将舵机与遮挡板连接
微信图片_2021031520015322.jpg


遮挡板内部细节图
微信图片_2021031520015323.jpg


微信图片_2021031520015324.jpg


最终效果如下图
微信图片_2021031520015325.jpg


微信图片_2021031520015326.jpg


上电测试
微信图片_2021031520015327.jpg


称重,重量77g
微信图片_2021031520015328.jpg


测试后发现最先选用的110ma锂电池容量太小,续航时间不够,于是更换500ma锂电池,更换大容量的电池后体积也会相应增加,需要根据锂电池的体积修改结构
微信图片_2021031520015329.jpg


#编程实现#
开始程序设计之前,我们先理一下编程思路
本次装置的主要目的是检测小朋友用眼的姿势是否正确,如果出现斜视的情况,通过视线遮挡的方式提醒小朋友矫正动作
首先我们需要了解一下BNO055九轴加速度传感器是如何检测俯仰角 Pitch、翻滚角 Roll、偏航角 Yaw数据的
我们将传感器比较一架飞机,将它水平放置,假如飞机的机翼为y轴,那么机头和机尾自然就是x轴,原点为o,z轴垂直于x轴与y轴形成的平面xoy
微信图片_2021031520015330.jpg


其中俯仰角(pitch)为机头沿y轴上仰或下仰后,与xoy水平面所形成的夹角,向上为正,向下为负
俯仰角.gif


翻滚角(roll)为机身沿x轴左右翻滚后,与xoy平面所形成的夹角;翻滚角 Roll也是我们此次作品中唯一用到的数据,在组装阶段可以看出我们是将BNO055模块竖直放置在作品中使用的
横滚角.gif


偏航角(yaw)为机头沿z轴旋转后与xoz平面所形成的夹角;
偏航角.gif


当BNO055传感器模块的x,y,z完全与上述方向重合,则俯仰角 Pitch、翻滚角 Roll、偏航角 Yaw的值均为0度
接着我们下载一下官方示例程序,看一下BNO055九轴加速度传感器是不是与我们理解的一致
使用之前需要在官方提供的地址下载库文件
然后将下载好的库文件复制到arduino>>libraries文件夹中,如下图所示
微信图片_2021031520015331.jpg


关于导入库的详细方法也可以参考下面链接
程序代码:
  1. #include "DFRobot_BNO055.h"
  2. #include "Wire.h"
  3. typedef DFRobot_BNO055_IIC    BNO;    // ******** use abbreviations instead of full names ********
  4. BNO   bno(&Wire, 0x28);    // input TwoWire interface and IIC address
  5. // show last sensor operate status
  6. void printLastOperateStatus(BNO::eStatus_t eStatus)
  7. {
  8.   switch(eStatus) {
  9.   case BNO::eStatusOK:    Serial.println("everything ok"); break;
  10.   case BNO::eStatusErr:   Serial.println("unknow error"); break;
  11.   case BNO::eStatusErrDeviceNotDetect:    Serial.println("device not detected"); break;
  12.   case BNO::eStatusErrDeviceReadyTimeOut: Serial.println("device ready time out"); break;
  13.   case BNO::eStatusErrDeviceStatus:       Serial.println("device internal status error"); break;
  14.   default: Serial.println("unknow status"); break;
  15.   }
  16. }
  17. void setup()
  18. {
  19.   Serial.begin(115200);
  20.   bno.reset();
  21.   while(bno.begin() != BNO::eStatusOK) {
  22.     Serial.println("bno begin faild");
  23.     printLastOperateStatus(bno.lastOperateStatus);
  24.     delay(2000);
  25.   }
  26.   Serial.println("bno begin success");
  27. }
  28. void loop()
  29. {
  30.   BNO::sEulAnalog_t   sEul;
  31.   sEul = bno.getEul();
  32.   Serial.print("pitch:");
  33.   Serial.print(sEul.pitch, 3);
  34.   Serial.print(" ");
  35.   Serial.print("roll:");
  36.   Serial.print(sEul.roll, 3);
  37.   Serial.print(" ");
  38.   Serial.print("yaw:");
  39.   Serial.print(sEul.head, 3);
  40.   Serial.println(" ");
  41.   delay(80);
  42. }
复制代码

接着下载程序,运行结果如下,这里使用了一款DFRobot为BNO055模块设计的可视化软件
SEN0253_Test.gif


通过前面的讲解和程序演示不仅理解了俯仰角 Pitch、翻滚角 Roll、偏航角 Yaw三大数据也意味着你对智能手机,平衡车,无人机中姿态检测的原理有了基本概念,那么我们离成功还差一步
最后一步我们需要将BNO055九轴加速度传感器与舵机配合实现视线遮挡的功能
这里我们需要做两个映射,小朋友正视前方时,BNO055传感器检测到的翻滚角Roll为360/0度,对应的舵机为0度也就是打开状态,而小朋友的头朝右或者朝左偏时,都会导致眼镜的遮挡板闭合,倾斜的角度越大闭合的角度越大,当超过极限时就会完全闭合,通过下图可以直观理解
微信图片_2021031520015332.jpg


微信图片_2021031520015333.jpg


舵机的角度和BNO055九轴加速度传感器配合的代码如下
  1. //val_roll翻滚角   val_servo舵机角度
  2. if(val_roll>=0&&val_roll<=20)  
  3. {
  4.     val_servo = map(val_roll, 20, 0, 0, 150);
  5. }
  6. else{
  7.       if(val_roll<=360&&val_roll>=340)  
  8.         {
  9.         val_servo = map(val_roll, 340, 360, 0, 150);
  10.       }
  11.       else{
  12.           val_servo=0;
  13.         }
  14.     }
  15. myservo.write(val_servo);
  16. delay(80);
复制代码

理解了关键的这一步后,我们来看完整的程序
  1. #include "DFRobot_BNO055.h"
  2. #include "Wire.h"
  3. #include <Servo.h>
  4. typedef DFRobot_BNO055_IIC    BNO;    // ******** use abbreviations instead of full names ********
  5. BNO   bno(&Wire, 0x28);    // input TwoWire interface and IIC address
  6. Servo myservo;
  7. //val_roll翻滚角   val_servo舵机角度
  8. int val_servo;  
  9. int val_roll;
  10. // show last sensor operate status
  11. void printLastOperateStatus(BNO::eStatus_t eStatus)
  12. {
  13.   switch(eStatus) {
  14.   case BNO::eStatusOK:    Serial.println("everything ok"); break;
  15.   case BNO::eStatusErr:   Serial.println("unknow error"); break;
  16.   case BNO::eStatusErrDeviceNotDetect:    Serial.println("device not detected"); break;
  17.   case BNO::eStatusErrDeviceReadyTimeOut: Serial.println("device ready time out"); break;
  18.   case BNO::eStatusErrDeviceStatus:       Serial.println("device internal status error"); break;
  19.   default: Serial.println("unknow status"); break;
  20.   }
  21. }
  22. void setup()
  23. {
  24.   Serial.begin(115200);
  25.   myservo.attach(9);
  26.   bno.reset();
  27.   while(bno.begin() != BNO::eStatusOK) {
  28.     Serial.println("bno begin faild");
  29.     printLastOperateStatus(bno.lastOperateStatus);
  30.     delay(2000);
  31.   }
  32.   Serial.println("bno begin success");
  33. }
  34. void loop()
  35. {
  36.   BNO::sEulAnalog_t   sEul;
  37.   sEul = bno.getEul();
  38.   Serial.print("pitch:");
  39.   Serial.print(sEul.pitch, 3);
  40.   Serial.print(" ");
  41.   Serial.print("roll:");
  42.   Serial.print(sEul.roll, 3);
  43.   Serial.print(" ");
  44.   Serial.print("yaw:");
  45.   Serial.print(sEul.head, 3);
  46.   Serial.println(" ");
  47.   val_roll = sEul.head;
  48.   if(val_roll>=0&&val_roll<=20)  
  49.   {
  50.   val_servo = map(val_roll, 20, 0, 0, 150);
  51.   }
  52.   else{
  53.       if(val_roll<=360&&val_roll>=340)  
  54.         {
  55.         val_servo = map(val_roll, 340, 360, 0, 150);
  56.       }
  57.       else{
  58.           val_servo=0;
  59.         }
  60.       }
  61.   myservo.write(val_servo);
  62.   delay(80);
  63. }
复制代码

#功能测试#
下面通过一个视频详细介绍斜视提醒器的功能
#总结#
“斜视提醒器”目前存在问题,如果需要转头斜着看的时候该如何优化程序,作品的体积和重量还有优化提升的空间
接下来改进的方向:优化集成电路,外观结构重新选材、重新设计,优化算法增加人性化的功能
微信图片_2021031520015334.jpg
问题总结到这,其实一个作品也反应出了产品设计迭代的过程,也是孩子学习stem多学科融合课程时需要锻炼的思维,不断的发现问题,解决问题,让产品更加的完美,也是知识不断汲取,进步增长的过程,这样的学习阶梯是容易被接收的,这个过程中就孕育了工匠精神
一个好的产品一定是怀揣着十年磨一剑的精神,不断的打磨而成,子曰:“无欲速,无见小利,欲速则不达”正是这个道理
每个人都是在不断修炼中自我成长的,让我们磨好豆腐给最亲的人
赞天地之化育,让工匠精神推动社会的车轮滚滚向前
造物让生活更美好,我们下期再见
更多有趣的项目,欢迎旺仔爸爸造物社公众号
qrcode_for_gh_e8377c4fa7d1_258.jpg



KIKI  管理员

发表于 2021-3-16 10:19:24

目不斜视吗 哈哈哈哈
回复

使用道具 举报

hnyzcj  版主

发表于 2021-3-17 06:36:06

KIKI 发表于 2021-3-16 10:19
目不斜视吗 哈哈哈哈

直视
回复

使用道具 举报

Wsheng  学徒

发表于 2021-3-31 09:58:22

好秀啊这个
回复

使用道具 举报

 中级技师

发表于 2021-4-1 21:03:14

很有创意,只是他不会斜视吗
回复

使用道具 举报

修远  见习技师 来自手机

发表于 2021-4-28 10:49:15

Mr Guo 发表于 2021-3-15 20:18
#项目起源#雷宇激光的陈典满老师是我的好朋友也是好大哥,他家的大公子上二年级,有一次聊天时说起大 ...

飞控也会用这个加速度传感器吗
回复

使用道具 举报

gyc13597926778  学徒

发表于 2021-5-28 22:34:12

好是好,都不会养成斜视的吗
回复

使用道具 举报

一只小学生  中级技师

发表于 2021-7-7 12:37:19

要看左右的东西可以加一个按键
按键一按就记录下当前的角度
然后用当前角度-记录的角度
这就可以再算出舵机的角度
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2021 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail