一、教学活动背景
随着信息科技的迅速发展,学生接触并运用现代科技设备的机会越来越多。为了提高学生们的信息科技素养,培养他们的计算思维、数字化学习与创新能力,我们设计了一款基于DFROBOT生产的行空板K10的仓鼠活动监测器项目。该项目贴近学生的生活,有实用性、趣味性、科学性与实践性,更重要的昌结合了硬件制作与编程开发,让学生们深入理解信息科技的应用,还能激发他们的动手实践能力和创新意识。
通过制作一个基于行空板K10的“移动检测”功能,学生们将设计并实现一个能够监测仓鼠活动的智能设备。当仓鼠在夜间活动时,行空板K10会通过红外夜视功能摄像头拍摄仓鼠的照片并存储在TF卡中;同时,安装在跑轮外侧的红外避障器会记录下跑轮转动的圈数,并将其显示在K10的LCD显示屏上;当按下行空板K10上的按键A,可以查看设备抓拍到的仓鼠活动照片。
这个由行空板K10与多个外设组件构建一个智能监测器,实时记录仓鼠的活动数据、夜间拍摄、跑轮圈数显示和存储照片等,激发学生的兴趣与好奇心,帮助学生们掌握硬件设计与编程技能,还能培养他们的团队合作和解决问题的能力。
二、教学目标
知识目标:通过本项目,学生可以了解行空板K10、红外避障传感器、LCD显示屏、TF卡存储等硬件组件的基本原理和应用。
能力目标:学生通过实际操作,掌握硬件连接与mind+编程技巧,能够调试并运行完整的运动检测与监控系统。
素养目标:培养学生的信息意识、计算思维、数字化学习与创新能力、以及信息社会责任感。
三、器材与工具
行空板K10、OV2640夜视功能摄像头、850nm红外补光灯、红外避障传感器、64GB TF存储卡、仓鼠跑轮、激光切割的椴木板外壳、DC3.7V稳压模块、5.5-2.5DC电源插座、导线若干。
四、工作原理
1.跑轮检测模块(红外避障传感器)
仓鼠跑轮是乳白色的,在跑轮的外侧粘贴一条宽度不大于2CM的黑色电工胶带。用螺丝把红外避障传感器固定在仓鼠笼的外侧,正对着跑轮,距离跑轮1.5~2cm 之间。当仓鼠在跑轮上跑步时,红外传感器检测到跑轮转动,输出的电平信号发生变化。行空板K10上运行的程序利用中断功能来判断仓鼠是否在跑轮上活动,并实时更新跑轮转动圈数。
2.运动检测
运动检测是计算机视觉和人工智能领域中的一个重要功能,广泛应用于视频监控、智能家居、机器人、安防系统、交通监控等多个领域。它的核心目标是通过分析视频或图像中的像素变化,检测和识别物体的运动行为,并做出相应的响应或触发预定的操作。
行空板K10内置“移动检测”功能。当夜间仓鼠出来活动时,行空板K10内置“移动检测”监测到仓鼠移动,启动拍摄功能,拍下仓鼠活动的照片,存储在TF卡上。图像文件以bmp格式保存,文件名按顺序生成,避免文件覆盖。
3.夜间图像采集(OV2640夜视摄像头)
行空板K10上自带的摄像头没有夜视功能,由于仓鼠是夜行动物,白天几乎不出来活动。为了观察到仓鼠夜间的活动情况,要把原配的摄像头折下,换上有夜视功功能的OV2640夜视摄像头,同时加装850nm的红外发光二极管补光。
4.显示模块(LCD屏)
行空板K10集成了2.8寸彩色LCD屏,用于实时显示跑轮转动圈数以及提供用户与设备交互的界面。当用户按下A按键时,LCD屏可以显示捕捉到的仓鼠活动照片。
(抓白到夜间活动的仓鼠)
5.微信小程序查看仓鼠活动量
该仓鼠活动监测器能把仓鼠每小时在跑轮上奔跑的圈数通过网络传到手机微信小程序上,可用曲线表示出来。
DFROBOT有一个物联网平台:Easy IoT。网址是 https://iot.dfrobot.com.cn/,该平台可以对联网的传感器/执行器数据进行实时监控和反馈,统计和分析已经接收的数据,并向传感器/执行器发送数据,帮助实现控制效果。在mind+上调用该平台,以实现将仓鼠每小时在跑轮上奔跑的圈数通过网络上传到手机微信小程序,并在微信小程序上以曲线图展示其活动量。该平台的注册与使用方法,可参考https://mc.dfrobot.com.cn/thread-267958-1-1.html的教程。
Mind+上MQTT命令初始化参数“Iot_id、Iot_pwd、Topic_0要与easyIOT上提供的参数一致。
仓鼠活动监测器上电工作一段时间后,在easy Iot上能查看接收到的数据。手机微信小程序也能同时查看数据,并用曲线显示数据的变化情况。
6.电源管理模块(DC 3.7V稳压模块和电源插座)
行空板上预留了 3.0-4.2V直流电源供电接口。仓鼠活动监测器全天工作,需用外接直流电源提供能量。本机采用6V2A电源适配器,仓鼠活动监测器内安装一个DC 3.7V稳压模块,电源插座为5.5-2.5DC插座,可把外部6V电源接入。外部电源进入设备后分两路:一路电源接到850nm红外补光灯上,另一路电源通过降压模块降压到4V后为行空板k10与红外避障传感器供电。
五、系统工作流程
初始化:设备通电后,行空板k10开始初始化各个功能:接入wifi,与easyiot建立连接,LCD显示屏显示欢迎界面,摄像头进行初始化,准备进行图像捕捉。
运动检测:当仓鼠进入跑轮奔跑时,红外避障传感器检测到信号变化,行空板k10记录仓鼠在跑轮上的活动,增加转动圈数并实时显示在屏幕上。
图像采集:当k10检测到仓鼠移动时,摄像头拍摄仓鼠的活动图像,保存在bmp格式文件中.
照片查看:当用户按下A按键时,设备进入查看模式,显示存储在TF卡中的照片。用户可以通过按键查看不同时间拍摄的图像。
六、总结
仓鼠活动监测器集成了运动检测、图像采集、数据存储和显示功能,能够在夜间监测仓鼠的活动并进行图像抓拍,通过TF卡存储照片,展示仓鼠的行为模式。通过这个项目,学生不仅能够理解硬件与软件的结合,学会如何利用传感器和控制器设计并实现实际应用,还能通过调试、编程和硬件搭建的过程,提升解决问题的能力。
下面是代码截图
附件中有代码与激光切割的文件供下载。
附件
/*!
* MindPlus
* esp32s3bit
*
*/
#include <DFRobot_Iot.h>
#include "unihiker_k10.h"
#include "AIRecognition.h"
#include <MPython_NtpTime.h>
#include <DFRobot_edgeTrigging.h>
// 动态变量
String mind_s_name;
volatile float mind_n_pi, mind_n_Now_time, mind_n_id, mind_n_ShowOrNot, mind_n_Mydate,
mind_n_HOURS, mind_n_total, mind_n_count;
// 函数声明
void onButtonAPressed();
String numberRetain(float t, uint8_t n);
void onButtonAUnPressed();
void onButtonBPressed();
void edge_up_P0();
// 静态常量
const String topics[5] = {"6HuXCFHNg","","","",""};
// 创建对象
UNIHIKER_K10 k10;
AIRecognition ai;
uint8_t screen_dir=2;
DFRobot_Iot myIot;
MPython_NtpTime ntptime;
DFRobot_edgeTrigging edge;
// 主程序开始
void setup() {
k10.begin();
k10.buttonA->setPressedCallback(onButtonAPressed);
k10.initScreen(screen_dir);
ai.initAi();
k10.initBgCamerImage();
k10.setBgCamerImage(false);
k10.creatCanvas();
k10.initSDFile();
k10.buttonA->setUnPressedCallback(onButtonAUnPressed);
ai.switchAiMode(ai.NoMode);
k10.buttonB->setPressedCallback(onButtonBPressed);
edge.registerEvent(P0, EDGE_RISING, edge_up_P0);
myIot.wifiConnect("robot", "sshyxqyc");
while (!myIot.wifiStatus()) {}
k10.canvas->canvasText("wifi连接成功!", 1, 0x0000FF);
k10.canvas->updateCanvas();
ntptime.setNtpTime(ntptime.UTCEast8_t, "edu.ntp.org.cn");
myIot.init("iot.dfrobot.com.cn","rSzXjKNNg","9930146163501163","rSkXjFHHRz",topics,1883);
myIot.connect();
while (!myIot.connected()) {}
mind_n_Now_time = ntptime.localTime(ntptime.Minute);
k10.canvas->canvasText("微信小程序服务器连接成功!", 3, 0x0000FF);
k10.canvas->updateCanvas();
mind_n_id = 0;
mind_n_ShowOrNot = 0;
k10.setBgCamerImage(true);
ai.switchAiMode(ai.Move);
ai.setMotinoThreshold(100);
// 灯亮,白色 输出低
// 灯灭,黑色 输出高
pinMode(P0, INPUT);
k10.canvas->canvasText("一切准备就绪", 5, 0x0000FF);
k10.canvas->updateCanvas();
delay(2000);
k10.canvas->canvasClear();
}
void loop() {
if ((!(mind_n_Mydate==ntptime.localTime(ntptime.Date)))) {
mind_n_Mydate = ntptime.localTime(ntptime.Date);
mind_n_HOURS = 0;
mind_n_total = 0;
}
if (ai.isDetectContent(AIRecognition::Move)) {
mind_s_name = (String(numberRetain(mind_n_id,0)) + String(".bmp"));
k10.photoSaveToTFCard("S:/" + mind_s_name);
mind_n_pi = mind_n_id;
mind_n_id += 1;
delay(10000);
}
if ((!(ntptime.localTime(ntptime.Hour)==mind_n_Now_time))) {
mind_n_HOURS += 1;
myIot.publish(topic_0, mind_n_count);
mind_n_count = 0;
mind_n_Now_time = ntptime.localTime(ntptime.Hour);
}
k10.canvas->canvasText((String(numberRetain(mind_n_id,0)) + String("张照片,按A键查看")), 1, 0xFFFF00);
k10.canvas->canvasText((String((String(numberRetain(mind_n_HOURS,0)) + String("小时仓鼠跑"))) + String((String(numberRetain(mind_n_total,0)) + String("圈")))), 3, 0xFFFF00);
k10.canvas->updateCanvas();
delay(1000);
}
// 事件回调函数
void onButtonAPressed() {
ai.setMotinoThreshold(0);
k10.setBgCamerImage(false);
mind_s_name = (String(numberRetain(mind_n_pi,0)) + String(".bmp"));
k10.canvas->canvasDrawImage(0, 0, "S:/" + mind_s_name);
k10.canvas->canvasText(mind_s_name, 1, 0x0000FF);
k10.canvas->updateCanvas();
if ((mind_n_pi>0)) {
mind_n_pi -= 1;
}
}
void onButtonAUnPressed() {
k10.canvas->canvasClear();
ai.setMotinoThreshold(100);
k10.setBgCamerImage(true);
k10.canvas->updateCanvas();
}
void onButtonBPressed() {
k10.setBgCamerImage(true);
mind_s_name = (String(numberRetain(mind_n_id,0)) + String(".bmp"));
k10.photoSaveToTFCard("S:/" + mind_s_name);
k10.canvas->canvasText(mind_s_name, 1, 0x0000FF);
k10.canvas->updateCanvas();
mind_n_pi += 1;
}
void edge_up_P0() {
mind_n_count += 1;
mind_n_total += 1;
}
// Static functions
String numberRetain(float t, uint8_t n)
{
String str=t<0 ? "-" : ""; int8_t _n=n; t=abs(t);
for(; _n>=0; --_n){
uint32_t integer = floor(t);
float decimal = t - integer;
str += _n == n ? (String(integer) + (n ? "." : "")) : integer;
t = decimal*10;
}
return str;
}
wwwpz2025.01.09
内容全面,过程精彩,实用性强。