所有分类
主题 主题
平台 平台
我的工作台
userHead
注册时间 [[userInfo.create_time]]
创造力 [[userInfo.creativity]]
[[userInfo.remark]]
[[d.project_title]]
articleThumb
[[d.material_name]]
timelineThumb
进入工作台
折叠
所有分类 我的工作台
展开
#造作一夏#自动跟随风扇
汤果 汤果 2020-06-07 12:05:14
5
3
简单

【项目介绍】

夏天又到了,又到了日常汗流浃背的时候。每当夏天到来,给我续命的不是空调,而是电风扇!

projectImage

某次监考地理的时候,学生画了这张图。知识点结合到位,活学活用。而我在办公室的座位刚好就是空调斜对角,靠门的位置。窗户是防盗窗,锁死了,打不开。房间又太大了,空调吹不到,而且丝毫感受不到空调带来的凉意。于是夏日里,我就靠桌面上的 USB 风扇续命。

projectImage

然而有时候处理事情时会站起来或者换个位置,这时风扇需要手动去调整位置,不是很方便。为何不做一个自动跟随的风扇呢?我们的目标是,风扇跟着你走。你往哪儿,风扇就往哪儿吹!

【解决方案】

要做到自动跟踪,摄像头是少不了的。刚好我手上有个二哈识图(HuskyLens),可以进行人脸识别、物体追踪,我们可以利用它来记录人在摄像头中的相对位置,然后通过舵机调整风扇的角度。为了实现角度自由调整,我们还需要一个云台。因此主要器材就确定了。

材料清单 材料清单
1x
micro:bit 编程入门开发板
1x
micro:bit掌控I/O扩展板
1x
Gravity: 二哈识图(HuskyLens)AI 视觉传感器
1x
迷你2自由度云台(无舵机)
2x
DMS-MG90 金属9g舵机 (1.8Kg)
1x
Gravity: 130 直流电机风扇

【作品演示】

我们先来看看做好的样子吧!

projectImage

视频中我用的是“物体追踪”模式,实际上测试的时候用的是“人脸识别”模式,跟踪效果也很棒!

下面我们开始制作吧!

步骤1 步骤1
组装云台

这个迷你二自由度云台收到的时候是散件,需要自己组装。首先我们将一个舵机卡到底部固定座上。

projectImage

然后将另一边固定座盖上,接着用螺丝刀将两侧固定座固定在一起。

projectImage

找到舵机配件包中的舵盘。我们需要用到十字舵盘和条形单边舵盘。从下图可以看出,这两个舵盘全都太长了,需要进行修剪。

projectImage

温馨提示:舵盘修剪后不一定能放进对应的孔位,还要用锉刀打磨两侧或者修剪侧边。注意不要剪掉太多,否则稍后无法用螺丝固定。

修剪完成后从背面用最小号自攻螺丝将舵盘固定在底座和固定座上。

projectImage

取出另一个舵机,将其用螺丝固定在云台上方的固定座上。

projectImage

将云台的两个固定座组装在一起。

projectImage

最后将底部舵机对准底座上的十字舵盘插好就完成了云台的组装。

步骤2 步骤2
安装风扇

首先将风扇反过来,将二哈识图配件里的长支架固定在风扇的背面。

projectImage

将二哈识图通过短支架固定在风扇背面的支架上。然后就可以把风扇放到云台上了。

projectImage

看上去效果不错。然而转动云台上部分,发现只能往下转动,不能往上“抬头”!也就是说风扇只能垂直往前吹,或者低头吹地面。这可不是我想要的效果。那就再捣腾一下,看看有没有别的固定方法。

projectImage

最终找到了可以上下点头的固定方式。然而这个固定方式风扇根本没有牢牢固定在云台上。而且因为头重脚轻,直接会把云台搞翻了。

projectImage

那就把云台的底座用自攻螺丝固定在一个纸盒子上,这样就不会翻了。可还是没有解决固定风扇的问题。那就自己动手设计一个风扇支撑块吧。

步骤3 步骤3
制作风扇支撑块

通过观察可以知道,上述固定方式,云台底部悬空,风扇两侧都有空隙,因此根本固定不住。用尺子测量中间的间隙,绘制风扇支撑块的草图。

projectImage

尺寸确定后就可以用软件来建模了。打开 Fusion 360,绘制底面草图。

projectImage

为了防止中间开口太小导致风扇卡不进去,我将开口各往两侧缩进 0.1 mm。

projectImage

将底面整体往上提升 9.5 mm,完成模型的创建。

projectImage

将模型切片后用 3D 打印机打印出来。

projectImage

尺寸刚好可以塞进云台。

projectImage

试着将风扇塞到中间孔位中。刚好可以牢固固定住。

步骤4 步骤4
连接器材
projectImage

1.将二哈识图连接到扩展板的 IIC 接口。

2.将风扇连接到 P12 引脚。

3.将云台下方的舵机接到 P0 引脚,并关闭扩展板上的蜂鸣器开关。

4.将云台上方的舵机接到 P1 引脚。

步骤5 步骤5
编写代码

一、原理分析

二哈识图屏幕分辨率为 320*240,因此屏幕中心点坐标为(160,120)。我们可以获取屏幕中捕获对象方框的中心点坐标,将其与(160,120)进行比较。

projectImage

若 X 坐标<160,则水平舵机向左转;

若 X 坐标>160,则水平舵机向右转;

若 Y 坐标<120,则垂直舵机向上转; 

若 X 坐标>120,则垂直舵机向下转。

另外,风扇当检测到画面中有人或者有识别对象时才打开,没有的时候关闭。这样做也算是节能减排了哈~

二、引入扩展

打开 Mind+,切换到上传模式。选择【主控板】分类下的【micro:bit】。

projectImage

在【传感器】分类下找到【HUSKYLENS AI 摄像头】,点击添加。

projectImage

将【执行器】下的【舵机模块】也添加到项目中。

projectImage

三、创建变量

选择【变量】分类,点击【新建数字类型变量】,新建两个变量,分别为“X角度”和“Y角度”。我们用这两个变量来记录水平方向舵机的角度和垂直方向舵机的角度。

projectImage

四、创建函数

点击【函数】分类,选择【自定义模块】,新建两个函数,分别为“X轴移动”和“Y轴移动”。我们用这两个函数来控制云台的移动。

projectImage

五、编写主函数

程序开始时我们先初始化二哈识图,切换到“人脸识别”模式,同时设置舵机的初始化角度。水平方向 90 度刚好在正中间,垂直方向 50 度是一个比较好的仰角。

projectImage

在循环中每次请求一次数据存入,如果方框在画面中就打开风扇,否则关闭风扇。打开风扇以后要判断目标对象的位置,并通过“X轴移动”和“Y轴移动”两个函数来使风扇朝着目标对象吹。

六、编写函数代码

依据原理分析中的方法,编写“X轴移动”和“Y轴移动”两个函数的程序。我们除了判断目标对象坐标外,还要加一个角度判断,防止舵机移动时角度超过了范围。

projectImage
projectImage

上述代码在测试的时候发现了一个问题。舵机一直在左右移动,好像一直在抖动。不是左移就是右移,即使你没有动。仔细观察代码发现,我们的代码就是这样子,只要偏离中心点就要调整舵机。而摄像头每次读取的坐标中心点都是有微小变化的。所以要消除这个抖动,就只能修改代码,不能将坐标一分为二,而是多划分几个区域。

projectImage

根据屏幕的尺寸,我们确定了中间有色区域为舵机不动区域。即:

若 X 坐标<140,则水平舵机向左转;

若 X 坐标>180,则水平舵机向右转。

修改代码如下:

projectImage

同理修改“Y轴移动”函数。

projectImage

现在就不会出现自己不动,风扇也在左右移动的情况了。

代码 代码
	                    					/*!
 * MindPlus
 * microbit
 *
 */
#include <DFRobot_Servo.h>
#include <DFRobot_HuskyLens.h>

// 动态变量
volatile float mind_n_XJiaoDu, mind_n_YJiaoDu;
// 函数声明
void DF_XZhouYiDong();
void DF_YZhouYiDong();
// 创建对象
DFRobot_HuskyLens huskylens;
Servo             servo_0;
Servo             servo_1;


// 主程序开始
void setup() {
	servo_0.attach(0);
	servo_1.attach(1);
	huskylens.beginI2CUntilSuccess();
	huskylens.writeAlgorithm(ALGORITHM_FACE_RECOGNITION);
	mind_n_XJiaoDu = 90;
	mind_n_YJiaoDu = 50;
	servo_0.angle(abs(mind_n_XJiaoDu));
	servo_1.angle(abs(mind_n_YJiaoDu));
}
void loop() {
	huskylens.request();
	if (huskylens.isAppearDirect(HUSKYLENSResultBlock)) {
		digitalWrite(12, HIGH);
		DF_XZhouYiDong();
		DF_YZhouYiDong();
	}
	else {
		digitalWrite(12, LOW);
	}
}


// 自定义函数
void DF_XZhouYiDong() {
	if (((huskylens.readBlockCenterParameterDirect().xCenter<140) && (mind_n_XJiaoDu<=170))) {
		mind_n_XJiaoDu += 2;
		servo_0.angle(abs(mind_n_XJiaoDu));
		delay(100);
	}
	if (((huskylens.readBlockCenterParameterDirect().xCenter>180) && (mind_n_XJiaoDu>=10))) {
		mind_n_XJiaoDu -= 2;
		servo_0.angle(abs(mind_n_XJiaoDu));
		delay(100);
	}
}
void DF_YZhouYiDong() {
	if (((huskylens.readBlockCenterParameterDirect().yCenter<100) && (mind_n_XJiaoDu<=10))) {
		mind_n_YJiaoDu -= 2;
		servo_1.angle(abs(mind_n_YJiaoDu));
		delay(100);
	}
	if (((huskylens.readBlockCenterParameterDirect().yCenter>140) && (mind_n_XJiaoDu>=70))) {
		mind_n_YJiaoDu += 2;
		servo_1.angle(abs(mind_n_YJiaoDu));
		delay(100);
	}
}
	                    				

【总结】

项目的思路比较简单,但是代码编写还是有一定的难度。关键在于舵机移动的方向与屏幕坐标的关系以及舵机的角度加减与左右、上下移动的关系。使用物体追踪和人脸识别都能够达到不错的追踪效果。不过跟踪的时候,舵机向上移动没有向下灵敏,代码或许有一定的改善空间。

Makelog作者原创文章,未经授权禁止转载。
5
3
评论
[[c.user_name]] [[c.create_time]]
[[c.parent_comment.count]]
[[c.comment_content]]