回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页
best-icon

基于二哈识图2制作的智能关怀设备:留守灵眸 中等

头像 怀若谷 2025.11.25 23 0

注:本文档中的图片大部分为自行拍摄和绘制,部分来源于DFRobot网站,部分由豆包AI生成;如有雷同或侵权,请及时联系删除。

1.识别模式

本作品使用了二哈识图2中的表情识别模块,模型为自带。在表情识别功能下,HUSKYLENS 2能识别7种特定的表情:愤怒(ID为1)、厌恶(ID为2)、恐惧(ID为3)、开心(ID为4)、中性(ID为5)、悲伤(ID为6)和惊讶(ID为7)。

二哈2.jpg

2.创作背景

留守儿童,长期与父母分离,一般跟随祖辈生活。而这些孩子往往不太愿意跟祖辈进行深入交流,他们的很多需求会被忽视,时间一长,易引发心理问题。如何让家人或远在外地的父母能及时关注孩子的实时情绪,做出适时有效的关怀,是一个亟待解决的难题。使用二哈识图2的表情识别模式,可以捕捉孩子们的情绪变化,加上物联网技术,让这个问题迎刃而解。

留守儿童.png

3.系统设计与工作原理

3.1功能介绍

它是一个多功能智能实体,以桌面笔筒的形式呈现,可以显示日期时间信息,可以显示天气及气温信息,可以接收并显示外地父母发来的信息,它会识别小主人的表情并亮起相应颜色的灯光,让家人知道他的心情,还可以将情绪状态发送到外地父母手上的设备上。

在外地的父母可以使用各种智能终端与之进行交互,比如电脑、手机等,本案例中制作了一个电子相册进行演示。该电子相册能播放孩子的照片,能显示老家的天气及气温信息,能显示接收到的孩子的情绪信息,还能选择并发送简单的文字信息给孩子。

图片1.png

3.2 系统构成

孩子端设备由行空板K10、二哈识图2和RGB灯带组成,家长端使用了一块行空板K10,两端设备均通过Wi-Fi接入互联网,使用EasyIOT物联网平台进行交互。

系统构成.jpg

3.3 工作流程图

孩子端流程图.jpg

智能笔筒(孩子端)工作流程图

家长端流程图.jpg

电子相册(家长端)工作流程图

4.器材清单

4.1硬件

IMG_0666.JPG

材料清单

注:上述连接线和数据线,在购买相关产品时可能会有赠送。

 

 

4.2 软件

编程软件:Mind+ V1.8.1RC3.0

建模软件:LaserMaker2.0.16

 

5.制作过程

步骤1 硬件搭建

孩子端:将二哈识图2AI视觉传感器连接到行空板K10的I2C接口、RGB灯带连接到P0接口。

家长端:无需外接传感器。

IMG_0671.JPG

步骤2 程序设计

本作品的程序使用Mind+ V.8.1RC3.0编写,设计思路参照工作流程图。程序如下所示。孩子端程序_副本.jpg

智能笔筒(孩子端)程序

家长端程序_副本.jpg

电子相册(家长端)程序

步骤3 结构设计与加工

本作品的结构与外型图纸使用LaserMaker2.0.16绘制,然后使用激光切割机进行加工,使用的板材为3MM椴木板。

笔筒截屏.png

智能笔筒图纸

电子相册图纸截图.png

电子相册图纸

IMG_0665.JPG

激光切割加工

步骤4 组装成型

1 .组装智能笔筒

(1)安装控制板

IMG_0676.JPG

(2)粘贴灯带

IMG_0680.JPG

(3)组装底面和侧面板件

IMG_0694.JPG

(4)安装二哈识图2

IMG_0682.JPG

(5)组装内盒

IMG_0692.JPG

(6)将内盒放入外盒

IMG_0695.JPG

(7)装上顶面板件

IMG_0697.JPG

(8)装上背面板件

IMG_0699.JPG

2.组装电子相册

(1)安装控制板

IMG_0712.JPG

(2)粘上中间层板件

IMG_0715.JPG

(3)粘上背面板件

IMG_0747.JPG

步骤5 调试完善

通电测试各项功能是否能正常实现。对程序和外型进行修改迭代,不断完善作品。IMG_0742.JPG

6.作品展示

6.1 成品图

IMG_0732.JPG

6.2 多角度图

IMG_0749.JPGIMG_0750.JPGIMG_0752.JPGIMG_0753.JPG

IMG_0720.JPG
IMG_0745.JPG
IMG_0747.JPG
IMG_0755.JPG

6.3 演示视频

7.总结与反思

该作品充分利用了二哈识图2和行空板K10的优点,聚焦留守儿童的关怀问题,各个功能模块也很实用。

最初想做一个情绪小夜灯,让家人通过小夜灯灯光颜色了解孩子的心情状况。经思考,这样的主题比较普通,功能也很单一,没有充分利用到行空板K10的特长。所以,逐步加入了其他功能,像模拟时钟,就是我之前做行空板K10新品评测时做的一个小项目。后来又想在主题上进行升华,想到了可以面向留守儿童,再加入物联网技术与在外地的家长进行互动。

作为一个智能笔筒,还有很多功能可以融合进去,比如写字姿态识别、久坐提醒等,相当于增加了预防近视主题,这还需要待二哈识图2进一步迭代,使用其多算法模式实现。

当然,该作品的存在形式不局限于笔筒,它还可以做成其它形态,布置在家里的各个能较方便捕捉到孩子面部表情的地方。如果不考虑成本的话,可以同时使用多个识别设备。它的终极形态,是与家里现有的监控摄像头、智能电视摄像头等结合起来。

代码
/*!
 * MindPlus
 * esp32s3bit
 *
 */
#include <DFRobot_Iot.h>
#include "unihiker_k10.h"
#include <MPython_NtpTime.h>
#include <mPython_Weather.h>
#include <DFRobot_NeoPixel.h>
#include "DFRobot_HuskylensV2.h"

// 动态变量
String         mind_s_LaiZiJiaChangDeXinXi;
volatile float mind_n_i, mind_n_a, mind_n_b, mind_n_j, mind_n_h, mind_n_m, mind_n_s;
// 函数声明
void DF_HuaBiaoPan();
void DF_HuaShiZhen();
void DF_HuaFenZhen();
void DF_HuaMiaoZhen();
void DF_ChuShiHuaSheBei();
void DF_PingMuXianShiXinXi();
void DF_QingXuShiBieJiChuLi();
void obloqMqttEventTfyp0g(String& message);
// 静态常量
const String topics[5] = {"eeDhHDmDg","yC-gWpiDR","I0i5PUiDg","",""};
const MsgHandleCb msgHandles[5] = {NULL,obloqMqttEventTfyp0g,NULL,NULL,NULL};
// 创建对象
UNIHIKER_K10     k10;
uint8_t          screen_dir=2;
AHT20            aht20;
DFRobot_Iot      myIot;
HuskylensV2      huskylens;
MPython_NtpTime  ntptime;
mPython_Weather  myWeather;
DFRobot_NeoPixel neoPixel_P0;


// 主程序开始
void setup() {
	k10.begin();
	myIot.setMqttCallback(msgHandles);
	k10.initScreen(screen_dir);
	k10.creatCanvas();
	Wire.begin();
  while (!huskylens.begin(Wire)) {
    delay(100);
  }
	DF_ChuShiHuaSheBei();
}
void loop() {
	DF_PingMuXianShiXinXi();
	DF_QingXuShiBieJiChuLi();
	myIot.publish(topic_2, aht20.getData(AHT20::eAHT20TempC));
	delay(1000);
}


// 自定义函数
void DF_HuaBiaoPan() {
	k10.canvas->canvasSetLineWidth(3);
	k10.canvas->canvasCircle(120, 190, 82, 0x0000FF, 0x00FFFF, true);
	mind_n_i = 0;
	for (int index = 0; index < 60; index++) {
		mind_n_a = (80 * (sin((float)(6 * mind_n_i) / 180 * PI)));
		mind_n_b = (80 * (cos((float)(6 * mind_n_i) / 180 * PI)));
		k10.canvas->canvasLine(120, 190, (120 + mind_n_a), (190 - mind_n_b), 0x0000FF);
		mind_n_i += 1;
	}
	k10.canvas->canvasCircle(120, 190, 76, 0x00FFFF, 0x00FFFF, true);
	mind_n_j = 0;
	for (int index = 0; index < 12; index++) {
		mind_n_a = (80 * (sin((float)(30 * mind_n_j) / 180 * PI)));
		mind_n_b = (80 * (cos((float)(30 * mind_n_j) / 180 * PI)));
		k10.canvas->canvasLine(120, 190, (120 + mind_n_a), (190 - mind_n_b), 0x0000FF);
		mind_n_j += 1;
	}
	k10.canvas->canvasCircle(120, 190, 72, 0x00FFFF, 0x00FFFF, true);
	k10.canvas->canvasCircle(120, 190, 4, 0x0000FF, 0x0000FF, true);
}
void DF_HuaShiZhen() {
	k10.canvas->canvasSetLineWidth(3);
	mind_n_a = (40 * (sin((float)((30 * mind_n_h) + (0.5 * mind_n_m)) / 180 * PI)));
	mind_n_b = (40 * (cos((float)((30 * mind_n_h) + (0.5 * mind_n_m)) / 180 * PI)));
	k10.canvas->canvasLine(120, 190, (120 + mind_n_a), (190 - mind_n_b), 0x000066);
}
void DF_HuaFenZhen() {
	k10.canvas->canvasSetLineWidth(2);
	mind_n_a = (60 * (sin((float)(6 * mind_n_m) / 180 * PI)));
	mind_n_b = (60 * (cos((float)(6 * mind_n_m) / 180 * PI)));
	k10.canvas->canvasLine(120, 190, (120 + mind_n_a), (190 - mind_n_b), 0xFF0000);
}
void DF_HuaMiaoZhen() {
	k10.canvas->canvasSetLineWidth(1);
	mind_n_a = (70 * (sin((float)(6 * mind_n_s) / 180 * PI)));
	mind_n_b = (70 * (cos((float)(6 * mind_n_s) / 180 * PI)));
	k10.canvas->canvasLine(120, 190, (120 + mind_n_a), (190 - mind_n_b), 0xFF9900);
}
void DF_ChuShiHuaSheBei() {
	huskylens.switchAlgorithm(ALGORITHM_EMOTION_RECOGNITION);
	myIot.wifiConnect("liu", "88888888");
	while (!myIot.wifiStatus()) {}
	ntptime.setNtpTime(ntptime.UTCEast8_t, "edu.ntp.org.cn");
	myWeather.init("server.mindplus.top", "31982666", "E6MtBcxQ");
	myIot.init("iot.dfrobot.com.cn","_TOKprSNR","8745261883497164","qhd2p9IHg",topics,1883);
	myIot.connect();
	while (!myIot.connected()) {}
	neoPixel_P0.begin(P0, 7);
	k10.canvas->canvasClear();
	k10.setScreenBackground(0x33FFFF);
	mind_s_LaiZiJiaChangDeXinXi = "每天进步一点点!";
}
void DF_PingMuXianShiXinXi() {
	k10.canvas->canvasText(ntptime.getDate(), 30, 10, 0x990000, k10.canvas->eCNAndENFont24, 50, true);
	k10.canvas->canvasText((String("星期") + String((ntptime.localTime(ntptime.Week) - 1))), 90, 40, 0x9999FF, k10.canvas->eCNAndENFont24, 50, true);
	k10.canvas->canvasText((String("天气:") + String((String(myWeather.getWeather("weather", "101240301")) + String((String(aht20.getData(AHT20::eAHT20TempC)) + String("℃")))))), 36, 70, 0xCC9933, k10.canvas->eCNAndENFont24, 15, true);
	mind_n_h = ntptime.localTime(ntptime.Hour);
	mind_n_m = ntptime.localTime(ntptime.Minute);
	mind_n_s = ntptime.localTime(ntptime.Second);
	DF_HuaBiaoPan();
	DF_HuaShiZhen();
	DF_HuaFenZhen();
	DF_HuaMiaoZhen();
	k10.canvas->canvasText(mind_s_LaiZiJiaChangDeXinXi, 30, 285, 0x000099, k10.canvas->eCNAndENFont16, 50, true);
	k10.canvas->updateCanvas();
}
void DF_QingXuShiBieJiChuLi() {
	huskylens.getResult(ALGORITHM_EMOTION_RECOGNITION);
	if (((RET_ITEM_NUM(huskylens.getCachedCenterResult(ALGORITHM_EMOTION_RECOGNITION), Result, ID))==1)) {
		neoPixel_P0.setRangeColor(0, 6, 0xFF0000);
		myIot.publish(topic_0, "1");
	}
	if (((RET_ITEM_NUM(huskylens.getCachedCenterResult(ALGORITHM_EMOTION_RECOGNITION), Result, ID))==2)) {
		neoPixel_P0.setRangeColor(0, 6, 0xFFCC33);
		myIot.publish(topic_0, "2");
	}
	if (((RET_ITEM_NUM(huskylens.getCachedCenterResult(ALGORITHM_EMOTION_RECOGNITION), Result, ID))==3)) {
		neoPixel_P0.setRangeColor(0, 6, 0xFFFF00);
		myIot.publish(topic_0, "3");
	}
	if (((RET_ITEM_NUM(huskylens.getCachedCenterResult(ALGORITHM_EMOTION_RECOGNITION), Result, ID))==4)) {
		neoPixel_P0.setRangeColor(0, 6, 0x3366FF);
		myIot.publish(topic_0, "4");
	}
	if (((RET_ITEM_NUM(huskylens.getCachedCenterResult(ALGORITHM_EMOTION_RECOGNITION), Result, ID))==5)) {
		neoPixel_P0.setRangeColor(0, 6, 0x00FF00);
		myIot.publish(topic_0, "5");
	}
	if (((RET_ITEM_NUM(huskylens.getCachedCenterResult(ALGORITHM_EMOTION_RECOGNITION), Result, ID))==6)) {
		neoPixel_P0.setRangeColor(0, 6, 0x3366FF);
		myIot.publish(topic_0, "6");
	}
	if (((RET_ITEM_NUM(huskylens.getCachedCenterResult(ALGORITHM_EMOTION_RECOGNITION), Result, ID))==7)) {
		neoPixel_P0.setRangeColor(0, 6, 0xCCFFFF);
		myIot.publish(topic_0, "7");
	}
}

// 事件回调函数
void obloqMqttEventTfyp0g(String& message) {
	mind_s_LaiZiJiaChangDeXinXi = message;
}
代码
/*!
 * MindPlus
 * esp32s3bit
 *
 */
#include <DFString.h>
#include <DFRobot_Iot.h>
#include "unihiker_k10.h"
#include <mPython_Weather.h>

// 动态变量
String         mind_s_LaoJiaQiWen, mind_s_HaiZiQingXu, mind_s_GeiHaiZiDeHua;
volatile float mind_n_BianHao;
// 函数声明
void obloqMqttEventT5e25h(String& message);
void obloqMqttEventTdiwbg(String& message);
void onButtonAPressed();
void onButtonBPressed();
// 静态常量
const String topics[5] = {"eeDhHDmDg","yC-gWpiDR","I0i5PUiDg","",""};
const MsgHandleCb msgHandles[5] = {obloqMqttEventT5e25h,NULL,obloqMqttEventTdiwbg,NULL,NULL};
// 创建对象
UNIHIKER_K10    k10;
DFRobot_Iot     myIot;
mPython_Weather myWeather;
uint8_t         screen_dir=3;


// 主程序开始
void setup() {
	k10.begin();
	myIot.setMqttCallback(msgHandles);
	k10.initScreen(screen_dir);
	k10.creatCanvas();
	k10.initSDFile();
	k10.buttonA->setPressedCallback(onButtonAPressed);
	k10.buttonB->setPressedCallback(onButtonBPressed);
	k10.rgb->write(-1, 0x0000FF);
	myIot.wifiConnect("liu", "88888888");
	while (!myIot.wifiStatus()) {}
	k10.rgb->write(-1, 0xCC0000);
	myWeather.init("server.mindplus.top", "31982666", "E6MtBcxQ");
	myIot.init("iot.dfrobot.com.cn","_TOKprSNR","41905917246231916","qhd2p9IHg",topics,1883);
	myIot.connect();
	while (!myIot.connected()) {}
	k10.rgb->write(-1, 0xFFFF00);
	k10.canvas->canvasClear();
	k10.rgb->write(-1, 0x000000);
	mind_n_BianHao = 0;
}
void loop() {
	k10.canvas->canvasDrawImage(0, 0, "S:/bj.png");
	k10.canvas->canvasText((String("老家天气:") + String((String(myWeather.getWeather("weather", "101240301")) + String((String((dfstring.substring(mind_s_LaoJiaQiWen,0,1,0,5))) + String("℃")))))), 10, 180, 0xFFFF00, k10.canvas->eCNAndENFont16, 50, false);
	k10.canvas->canvasText((String("孩子情绪:") + String(mind_s_HaiZiQingXu)), 10, 200, 0xFFFF00, k10.canvas->eCNAndENFont16, 50, false);
	k10.canvas->canvasText((String("写给孩子的话:") + String(mind_s_GeiHaiZiDeHua)), 10, 220, 0xFFFF00, k10.canvas->eCNAndENFont16, 50, false);
	k10.canvas->updateCanvas();
	delay(1000);
}


// 事件回调函数
void obloqMqttEventT5e25h(String& message) {
	if ((message=="1")) {
		mind_s_HaiZiQingXu = "愤怒";
		k10.rgb->write(-1, 0xFF0000);
	}
	if ((message=="2")) {
		mind_s_HaiZiQingXu = "厌恶";
		k10.rgb->write(-1, 0xFF0000);
	}
	if ((message=="3")) {
		mind_s_HaiZiQingXu = "恐惧";
		k10.rgb->write(-1, 0xFFFF00);
	}
	if ((message=="4")) {
		mind_s_HaiZiQingXu = "开心";
		k10.rgb->write(-1, 0x0000FF);
	}
	if ((message=="5")) {
		mind_s_HaiZiQingXu = "中性";
		k10.rgb->write(-1, 0x00FF00);
	}
	if ((message=="6")) {
		mind_s_HaiZiQingXu = "悲伤";
		k10.rgb->write(-1, 0xFF0000);
	}
	if ((message=="7")) {
		mind_s_HaiZiQingXu = "惊讶";
		k10.rgb->write(-1, 0xFFFFCC);
	}
}
void obloqMqttEventTdiwbg(String& message) {
	mind_s_LaoJiaQiWen = message;
}
void onButtonAPressed() {
	mind_n_BianHao += 1;
	if ((mind_n_BianHao==8)) {
		mind_n_BianHao = 0;
	}
	if ((mind_n_BianHao==1)) {
		mind_s_GeiHaiZiDeHua = "每天进步一点点!";
	}
	if ((mind_n_BianHao==2)) {
		mind_s_GeiHaiZiDeHua = "今天降温,多穿点衣服!";
	}
	if ((mind_n_BianHao==3)) {
		mind_s_GeiHaiZiDeHua = "眼中有光,心中有爱";
	}
	if ((mind_n_BianHao==4)) {
		mind_s_GeiHaiZiDeHua = "有志者,事竟成";
	}
	if ((mind_n_BianHao==5)) {
		mind_s_GeiHaiZiDeHua = "失败乃成功之母!相信自己!";
	}
	if ((mind_n_BianHao==6)) {
		mind_s_GeiHaiZiDeHua = "失败乃成功之母!相信自己!";
	}
	if ((mind_n_BianHao==7)) {
		mind_s_GeiHaiZiDeHua = "海纳百川,有容乃大!";
	}
	if ((mind_n_BianHao==0)) {
		mind_s_GeiHaiZiDeHua = " ";
	}
}
void onButtonBPressed() {
	myIot.publish(topic_1, mind_s_GeiHaiZiDeHua);
}

评论

user-avatar