Arduino数学游戏制作指南

数学对于很多人来说可能像魔法一样神奇,但对另一些人来说却可能显得枯燥无味。因此,打算使用Arduino来改变一些人对数学的看法,通过制作一个小游戏来实现这一点。这个游戏将包含一系列从0到9的数字,所有数字都会显示在屏幕上。玩家需要快速地将这些数字相加。在数字显示后,玩家将使用按钮输入答案。有两个按钮,一个用于输入答案,另一个用于提交答案。当按下第一个按钮时,答案中的数字将增加1。玩家必须按下第一个按钮以得到正确的数字作为答案,并依次提交这些数字。如果答案正确/错误,绿色/红色LED灯将会亮起。数字的数量和每个数字显示的持续时间都可以在代码中调整。

例如:屏幕将显示一系列10个随机数字,每个数字显示1秒钟:5, 6, 1, 3, 7, 8, 9, 1, 2, 4。如果玩家按下46,绿色LED灯将会亮起。如果不是,红色LED灯将会亮起,因为本系列数字的正确答案是46(5 + 6 + 1 + 3 + 7 + 8 + 9 + 1 + 2 + 4 = 46)。玩家需要按下第一个按钮得到数字4,然后按下提交按钮,然后玩家需要按下那个按钮得到数字6,然后按下提交按钮。他就会赢。

材料清单

需要一些容易找到且便宜的组件,如下所示:

  • 1个ArduinoUno板
  • 2个LED灯(绿色和红色)
  • 2个按钮(一个用于按下答案,一个用于提交)
  • 1个7段显示器
  • 1K欧姆电阻
  • 导线
  • (如果想的话,可以使用10uF电容器来消抖按钮)

7段显示器

在开始之前,想让一些初学者对这种显示器有一个清晰的认识。7段显示器有两种类型,但它们并不是太不同。让看看下面的插图。首先,会发现它们彼此相似。事实上,它们各自有不同的使用方式。

7段显示器/LED有两种类型:

  • 公共阳极
  • 公共阴极

为了清楚起见,准备了一个简短的代码来测试显示器是公共阴极还是公共阳极。以下是测试代码的摘录。

#define sA 7 #define sB 6 #define sC 11 #define sD 12 #define sE 13 #define sF 8 #define sG 9 #define DP 10 int number = 0; void setup() { for(int i = 4; i <= 13; i++) { pinMode(i, OUTPUT); } Serial.begin(9600); } void loop() { number = (number + 1) % 10; displayNum(number); if(number % 2 == 0) { digitalWrite(DP, 1); } else { digitalWrite(DP, 0); } delay(1000); } void displayNum(int num) { clearAll(); switch(num) { case 0: digitalWrite(sA, 1); digitalWrite(sB, 1); digitalWrite(sC, 1); digitalWrite(sD, 1); digitalWrite(sE, 1); digitalWrite(sF, 1); break; case 1: digitalWrite(sB, 1); digitalWrite(sC, 1); break; // ... 更多的case } }

可以在这里下载完整的源代码。它显示从0到9的数字。显示器是公共阴极,所以如果这个代码不适用于显示器,请将代码中的LED打开行改为关闭,反之亦然。下面的图片是代码的电路图。

中断

在这个项目中,使用中断来处理两个按钮,以使程序更加整洁。中断是系统生成事件时自动调用的函数。这些事件由微控制器制造商使用硬件设置,并在软件中使用固定名称进行配置。由于中断是独立且在配置时自行生成的,主程序将更简单。中断的一个典型例子是millis()函数。这个函数随着程序的运行自动运行,并返回随时间递增的数字,尽管没有安装它。millis()函数的设置用于中断,并在Arduino程序代码中自动配置。

中断使程序更加整洁和快速。例如,当检查按钮是否被按下时,通常需要在loop()程序中使用digitalRead()函数来检查按钮状态。使用中断时,只需将按钮连接到支持中断的正确引脚,然后中断设置将在开关状态从LOW变为HIGH或反之亦定时生成。添加一个函数名来调用生成中断时。也就是说,中断程序中的变量将告诉按钮的状态。

中断引脚的数量取决于每个微控制器。ArduinoUno只有2个中断引脚,Mega 2560有6个中断引脚,Leonardo有5个中断引脚。在这里了解更多。

简单的电路图

完成这个简单的电路,开始编程。可能需要消抖按钮。

使用ArduinoIDE编程Arduino

不会再次提到显示功能,因为可以在上面的部分找到它。

找出中断引脚

当玩家按下按钮时,inputNum()和submit()函数将被调用。使用RISING,因为只在按下时调用这些函数一次。按下输入按钮时,将调用inputNum()函数,将变量增加1。将在下一个代码中解释提交答案时会发生什么。

void setup() { pinMode(INPUT_BUTTON, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(INPUT_BUTTON), inputNum, RISING); pinMode(SUBMIT_BUTTON, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(SUBMIT_BUTTON), submit, RISING); Serial.begin(9600); } //此函数在按下输入按钮时将当前数字增加1 void inputNum() { if(gameStatus == 2) { currentNum = (currentNum + 1) % 10; //确保数字在0到9的范围内 } } void submit() { if(gameStatus == 2) { String temp = String(currentNum); answer += temp; if(answer.length() - 1 == sResult.length()) { if(answer == sResult) { digitalWrite(GREEN_LED, 1); delay(1000); digitalWrite(GREEN_LED, 0); } else { digitalWrite(RED_LED, 1); delay(1000); digitalWrite(RED_LED, 0); } answer = ""; result = 0; gameStatus = 1; currentNum = 0; } } }

显示随机数字

可以很容易地通过两个变量quantity和delayTime来改变数字的数量和每个数字显示的时间。delayTime用作毫秒,1000毫秒=1秒。result变量用于累加所有随机数字,并用作关键答案。currentNum是包含玩家输入的数字的变量。如果按下输入按钮,currentNum变量将增加1。将整数转换为字符串以比较结果和玩家提交的答案。当答案的长度等于关键答案的长度时,它将检查玩家输入的所有数字是否与结果匹配。

int quantity = 10; int delayTime = 1000; int gameStatus = 1; //1:显示随机数字, //2:显示当前数字并等待提交 int result, currentNum = 0; String answer = "", sResult; void loop() { switch(gameStatus) { case 1: //显示随机数字 result = 0; for(int i = 1; i <= quantity; i++) { int a = random(0, 10); //a变量将是 //0到9之间的随机数字 displayNum(a); result += a; delay(delayTime); } finishDisplaying(); gameStatus = 2; sResult = String(result); break; case 2: //提交答案 displayNum(currentNum); delay(200); break; } }

可以在这里下载完整的源代码。将它们连接起来并上传以了解更多。

享受项目

将其上传到合适的板子上,看看它是如何工作的。按顺序按下数字。例如,答案如果是46。必须按下左边的按钮得到数字4,然后按下右边的按钮提交数字4,然后以相同的方式继续提交数字6。让看看下面的插图。它显示了如何按下以获得需要的数字。

消抖按钮

在测试期间,可能会发现它运行出乎意料。按下按钮一次,但数字增加了2或3而不是1。看起来按钮被按下了两次,但实际上只按了一次。在这种情况下,应该在这里了解更多关于消抖的信息。

有两种方法可以解决这个问题。可以通过添加几行代码或在电路中使用额外的电容器来消抖按钮。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485