【比赛优秀作品】基础数学四则运算练习机
作品来源:第五届全国青少年人工智能创新挑战赛——开源硬件创意智造专项赛
参赛学生:
-
吕明阳 重庆市第八中学校
-
唐崧耀 重庆市第八中学校
原文链接:
https://contest.dfrobot.com.cn/tcwl2022/project/312682?p=dfrobot2022sh
步骤1 创作灵感
现如今市面上的玩具大多只注重于“玩”,而导致学龄儿童玩物丧志,学习成绩下滑的情况屡见不鲜。所以我们针对这个问题,对于智能玩具进行了一定的改进。
我们认为,玩具不仅要注重可玩性,更要关注其教育意义。这样不仅能让孩子们玩得开心,还能在玩的过程中收获知识,增长见识,提升自我。并且结合像我们自身有二娃的家庭的现实情况。针对孩子们喜欢玩什么,什么对于孩子们有教育性的意义,展开讨论。
在大量的取材研究后,我们发现,大多数孩子在小的时候对于计算方面表现出比较困难的状态。为了让孩子们从小就养成学数学,爱数学的习惯。最终我们决定制作一个能让孩子们在玩耍中学习基础数学的智能机器人。它能够自动的出算术题,以此来锻炼孩子们的计算能力,从而为孩子们的数学从小就打好坚实的基础。为推动全民爱数学,运用数学为国家贡献力量,提供教育保障。
步骤2 视频
https://www.bilibili.com/video/BV1Uj411m7JF/
步骤3 结构打印
1.主体盒
我们首先用3Done设计用于放置内置传感器的盒子,并用3D打印机打印出来。
2.电池固定架
因为在我们之前的实践操作中,由于我们没有把电池固定,导致机器人在使用的过程中,电池会晃来晃去,可能会把线给碰掉,并且造成一种不好的体验。我们用3Done设计了一种专门用于固定电池的架子,他可以用尼龙螺丝固定在我们的主体盒上,使用起来较为方便。比较好的解决了由于电池固定不当而造成的问题。
步骤4 机器搭建
1.主体盒安装。
我们用电钻在主体盒上钻好了孔,然后用尼龙螺丝和尼龙螺母,把我们的UNO控制板以及语音合成模块安装了上去。
2.IIC拓展版
因为在我们的机器上使用的IIC传感器比较多,但是UNO控制板上只有两个拓展口,所以说我们自己制作了一个用于拓展IIC接口的板子,以解决IIC拓展口不够用的情况。
3. OLED显示器,电源模块和NFC识别模块的安装
由于我们在设计主体盒的时候,就已经把显示器和NFC识别模块的位置给留了出来。我们便直接用尼龙螺丝和尼龙螺母固定了上去。
步骤5 程序编写
1.初始化部分
初始化每个传感器,设置端口,完成机器人的启动提示。
2.对于算数题目的获取
实现机器人自主出算术题目,并且实现随机。
3.读取NFC卡编号
把NFC卡的原始编号转换成1~13的编号。
4.OLED 屏幕及语音合成
实现四则运算的显示和语音提示。
5.判断卡片顺序
实现对于卡片放置顺序的判断。
6.判断计算结果
实现对于结果是否正确的判断。
步骤6 机器调试和程序构思过程
我们制作的机器人可以自动出1~9之间的加减乘除四则混合运算题目,然后,使用者可以根据我们准备的具有NFC识别功能且标有数字标号为1~9和加减乘除符号的卡片。按照数字、符号、数字的顺序,使你所构成的算式结果能够和机器人自动出的结果相等。如果结果正确,机器将会播放“恭喜你答对了”的语音提示,反之则会播放“错误的”语音提示。我们的机器人能够在加减乘除,1~9中随机选择,全方位提升儿童的计算能力。
在我们的制作之初,我们原本打算,采取机器出计算题,而使用者通过口答的方式来回答结果。但是我们经过实验发现,人工智能语音识别模块,很难将数字识别清楚。于是我们便打算不使用语音识别,而是采用更为可靠的NFC识别方式。而NFC识别需要NFC识别卡,而每一张卡的初始编号都不同。所以我们通过mind+自带的 NFC卡号识别功能,把每一张卡的编号都记录下来。这时候吕明阳同学便提议,既然我们已经采用NFC识别方式,可供支配的卡较多,不如把练习方式变为机器人出算式,而使用者通过数与数之间的运算,使结果等于机器人出的算式的结果(最终类似于一个等式的形式)。我们认为方案可行,于是把我们找出来的13张NFC识别卡,分别对应编号为1~13。而编号为1~9的NFC识别卡,就代表数字1~9。而编号为10~13的卡,则代表四则混合运算符号(加减乘除)。而随机的时候就只需要随机对应的编号即可。
其次,我们还考虑到为了避免使用者,把放卡顺序搞混(本应放数字卡而放成了符号卡)。我们在机器人的每一次运算后都对于编号进行了判断,如果放卡正常便会继续运行,但是如果放卡顺序错误的话,便会语音提示“读卡错误请重试”,以提醒你需要重新换卡。于是我们照此构想编了程序,但首次试验后我们发现,其他的都能按照我们的预想运行,但是如果机器人随机的是除法,并且计算出的结果是小数的话。出现这种情况,使用者便无法再进行下去。为解决此问题,我们对程序进行的优化,即在显示算数之前,机器人先自我判断一遍,如果出现了小数的情况,便再循环一次,直到满足要求。
代码
/*! * MindPlus
* uno
*
*/
#include <DFRobot_NFC0231.h>
#include <DFRobot_SSD1306_I2C.h>
#include <DFRobot_SpeechSynthesis_M.h>
// 动态变量
String mind_s_IDzifu, mind_s_timu, mind_s_daan;
volatile float mind_n_IDbianhao, mind_n_daan1, mind_n_daan2, mind_n_daan3, mind_n_daanx,
mind_n_timudaan, mind_n_timu1, mind_n_timu2, mind_n_timu3;
// 函数声明
void DF_HuoQuID();
void DF_HuoQuTiMu();
// 创建对象
DFRobot_PN532_IIC nfc;
DFRobot_SpeechSynthesis_I2C sstts;
DFRobot_SSD1306_I2C oled12864;
// 主程序开始
void setup() {
Serial.begin(9600);
dfrobotRandomSeed();
delay(1000);
sstts.begin(sstts.eV2);
sstts.setVolume(10);
sstts.setSpeed(5);
sstts.setSoundType(sstts.eMale1);
sstts.setTone(5);
sstts.speak("你好");
oled12864.begin(0x3c);
oled12864.setCursorLine(1);
oled12864.printLine("hello");
nfc.begin();
}
void loop() {
oled12864.fillScreen(0);
DF_HuoQuTiMu();
oled12864.setCursorLine(1);
oled12864.printLine(mind_s_timu);
mind_n_daan1 = 0;
mind_n_daan2 = 0;
mind_n_daan3 = 0;
mind_n_daanx = 0;
while (!(mind_n_daan1>0)) {
DF_HuoQuID();
mind_n_daan1 = mind_n_IDbianhao;
if ((mind_n_daan1>9)) {
sstts.speak("读卡错误请重试");
mind_n_daan1 = 0;
}
else {
sstts.speak((String(String((String(mind_n_daan1))).charAt(1-1))));
}
}
while (!(mind_n_daan2>0)) {
DF_HuoQuID();
mind_n_daan2 = mind_n_IDbianhao;
if ((10>mind_n_daan2)) {
sstts.speak("读卡错误请重试");
mind_n_daan2 = 0;
}
else {
if ((mind_n_daan2==10)) {
sstts.speak("加");
}
else if ((mind_n_daan2==11)) {
sstts.speak("减");
}
else if ((mind_n_daan2==12)) {
sstts.speak("乘");
}
else {
sstts.speak("除");
}
}
}
while (!(mind_n_daan3>0)) {
DF_HuoQuID();
mind_n_daan3 = mind_n_IDbianhao;
if ((mind_n_daan3>9)) {
sstts.speak("读卡错误请重试");
mind_n_daan3 = 0;
}
else {
sstts.speak((String(String((String(mind_n_daan3))).charAt(1-1))));
}
}
if ((mind_n_daan2==10)) {
mind_n_daanx = (mind_n_daan1 + mind_n_daan3);
}
else if ((mind_n_daan2==11)) {
mind_n_daanx = (mind_n_daan1 - mind_n_daan3);
}
else if ((mind_n_daan2==12)) {
mind_n_daanx = (mind_n_daan1 * mind_n_daan3);
}
else {
mind_n_daanx = (mind_n_daan1 / mind_n_daan3);
}
mind_s_daan = (String(String((String(mind_n_daan1))).charAt(1-1)));
if ((mind_n_daan2==10)) {
mind_s_daan = (String(mind_s_daan) + String("+"));
}
else if ((mind_n_daan2==11)) {
mind_s_daan = (String(mind_s_daan) + String("-"));
}
else if ((mind_n_daan2==12)) {
mind_s_daan = (String(mind_s_daan) + String("x"));
}
else {
mind_s_daan = (String(mind_s_daan) + String("/"));
}
mind_s_daan = (String(mind_s_daan) + String((String(String((String(mind_n_daan3))).charAt(1-1)))));
mind_s_daan = (String(mind_s_daan) + String("="));
mind_s_daan = (String(mind_s_daan) + String(mind_n_daanx));
mind_s_timu = (String(mind_s_timu) + String(mind_n_timudaan));
oled12864.fillScreen(0);
oled12864.setCursorLine(1);
oled12864.printLine(mind_s_timu);
oled12864.setCursorLine(2);
oled12864.printLine(mind_s_daan);
sstts.speak("等于");
sstts.speak((String(mind_n_daanx)));
if ((mind_n_daanx==mind_n_timudaan)) {
sstts.speak("恭喜你答对了,请继续下一题");
}
else {
sstts.speak("这一次打错了,再试一下吧");
}
}
// 自定义函数
void DF_HuoQuID() {
mind_n_IDbianhao = 0;
while (!(!(mind_n_IDbianhao==0))) {
if (nfc.scan()) {
mind_s_IDzifu = nfc.readUid();
Serial.println(mind_s_IDzifu);
if ((mind_s_IDzifu=="d324f11a")) {
mind_n_IDbianhao = 1;
}
else if ((mind_s_IDzifu=="23b89f1a")) {
mind_n_IDbianhao = 2;
}
else if ((mind_s_IDzifu=="c388ad1a")) {
mind_n_IDbianhao = 3;
}
else if ((mind_s_IDzifu=="ds8a1ca")) {
mind_n_IDbianhao = 4;
}
else if ((mind_s_IDzifu=="a357f23c")) {
mind_n_IDbianhao = 5;
}
else if ((mind_s_IDzifu=="8343f11a")) {
mind_n_IDbianhao = 6;
}
else if ((mind_s_IDzifu=="c87c368d")) {
mind_n_IDbianhao = 7;
}
else if ((mind_s_IDzifu=="e876c87a")) {
mind_n_IDbianhao = 8;
}
else if ((mind_s_IDzifu=="87e9676c")) {
mind_n_IDbianhao = 9;
}
else if ((mind_s_IDzifu=="1388ba1a")) {
mind_n_IDbianhao = 10;
}
else if ((mind_s_IDzifu=="434a7f96")) {
mind_n_IDbianhao = 11;
}
else if ((mind_s_IDzifu=="f1268b2a")) {
mind_n_IDbianhao = 12;
}
else if ((mind_s_IDzifu=="b3378c31")) {
mind_n_IDbianhao = (0 + 0);
}
else {
}
}
}
}
void DF_HuoQuTiMu() {
mind_n_IDbianhao = 0;
while (!(!(mind_n_IDbianhao==0))) {
mind_n_timu1 = (random(1, 9+1));
mind_n_timu2 = (random(0, 3+1));
mind_n_timu3 = (random(1, 9+1));
mind_s_timu = (String(String((String(mind_n_timu1))).charAt(1-1)));
if ((mind_n_timu2==0)) {
mind_s_timu = (String(mind_s_timu) + String("+"));
}
else if ((mind_n_timu2==1)) {
mind_s_timu = (String(mind_s_timu) + String("-"));
}
else if ((mind_n_timu2==2)) {
mind_s_timu = (String(mind_s_timu) + String("x"));
}
else {
mind_s_timu = (String(mind_s_timu) + String("/"));
}
mind_s_timu = (String(mind_s_timu) + String((String(String((String(mind_n_timu3))).charAt(1-1)))));
if ((mind_n_timu2==0)) {
mind_n_timudaan = (mind_n_timu1 + mind_n_timu3);
}
else if ((mind_n_timu2==1)) {
mind_n_timudaan = (mind_n_timu1 - mind_n_timu3);
}
else if ((mind_n_timu2==2)) {
mind_n_timudaan = (mind_n_timu1 * mind_n_timu3);
}
else {
mind_n_timudaan = (mind_n_timu1 / mind_n_timu3);
}
if ((mind_n_timudaan==(floor(mind_n_timudaan)))) {
mind_n_IDbianhao = 1;
mind_s_timu = (String(mind_s_timu) + String("="));
}
}
}
硬件清单
-
1x Arduino UNO 链接
-
1x Gravity: IO 传感器扩展板 V7.1 链接
-
1x Gravity:中英文语音合成模块V2.0 链接
-
1x Gravity: UART & I2C NFC近场通讯模块 链接
-
1x 0.96”128x64 IIC/SPI OLED单色显示屏 链接
往期推荐