Arduino 的快速数学游戏
让我们用 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 并提交。他就赢了。
Material
我们需要一些容易找到且便宜的组件,例如:
- + 1 个 Arduino Uno 板
- + 2 个 LED(绿色和红色)
- + 2 个按钮(一个用于按数字,一个用于提交)
- + 1 个 7 段数码管
- + 1K 欧姆电阻
- + 连接线
- + (如果您愿意,可以使用 10uF 电容进行按钮去抖动)
7 段数码管
在开始之前,我想让一些初学者对这个显示屏有一个清晰的认识。7 段数码管有 2 种不同的类型,但它们差别不是很大。
让我们看看下面的插图。起初,您可能会觉得它们很相似。事实上,它们的使用方式不同。
7 段数码管/LED 有 2 种类型
+ 共阳极
我们都知道 LED 有 2 个极,阴极和阳极。在这个 7 段 LED 中,所有阳极都连接到正极 Vcc。要使 7 段 LED 中的 LED 点亮,您只需要将阴极连接到它的引脚。这样电路就闭合了,LED 就会点亮。例如,您想点亮 G 段,您应该将 Vcc 接到 5V 电源,将 G 引脚(在引脚图上)接到负极,并且不要忘记为 Vcc 引脚接一个电阻。
+ 共阴极
与前者相比,所有阴极都连接到负极 GND。如果您想点亮 7 段数码管中的所有 LED,您需要 8 个电阻,而对于共阳极类型,您只需要 1 个电阻。
为了更清楚,我准备了一个简短的代码来测试您的显示屏是共阴极还是共阳极。这是测试代码的一部分。
#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 2:
digitalWrite(sA, 1);
digitalWrite(sB, 1);
digitalWrite(sG, 1);
digitalWrite(sE, 1);
digitalWrite(sD, 1);
break;
您可以在此处下载完整的源代码。它显示从 0 到 9 的数字。我的显示屏是共阴极的,所以如果这段代码在您的显示屏上不起作用,请更改代码中点亮 LED 的行,使其反之亦然。下面的图片是代码的示意图。
中断
在这个项目中,我使用中断来处理两个按钮,以使程序更整洁。
中断是在系统生成事件时自动调用的函数。这些事件由微控制器制造商使用硬件设置,并在软件中通过固定名称进行配置。由于中断是独立的,并且在配置时是自生成的,因此主程序会更简单。中断的一个典型例子是 millis()
函数。这个函数随着程序的运行自动运行,并随着时间的推移返回一个递增的数字,尽管我们没有安装它。millis()
函数的设置用于中断,并且在 Arduino 程序代码中自动配置。
中断使程序更整洁、更快。例如,当检查按钮是否按下时,您通常需要在 loop()
程序中使用 digitalRead()
函数来检查按钮状态。使用中断,只需将按钮连接到支持中断的正确引脚,然后当开关状态从 LOW 变为 HIGH 或反之亦然时,就会生成中断设置。为生成中断时要调用的函数添加一个函数名。也就是说,中断程序中的变量将告诉我们按钮的状态。
中断引脚的数量取决于每个微控制器。对于 Arduino Uno,您只有 2 个中断引脚,Mega 2560 有 6 个中断引脚,Leonardo 有 5 个中断引脚。您可以在此处了解更多信息。
简单示意图
完成这个简单的电路,就可以开始对其进行编程了。您可能需要进行按钮去抖动。
使用 Arduino IDE 对 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);
}
//This function increase the current number by 1 when pressing input button
void inputNum()
{
if (gameStatus == 2)
{
currentNum = (currentNum + 1) % 10; //To make sure that the number
//is in the range from 0 to 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: show random numbers,
//2: show current number and wait for submit
int result, currentNum = 0;
String answer = "", sResult;
void loop() {
switch (gameStatus)
{
case 1: //Show random numbers
result = 0;
for (int i = 1; i <= quantity; i++)
{
int a = random(0, 10); // a variable will be
// a random number between 0 and 9
displayNum(a);
result += a;
delay(delayTime);
}
finishDisplaying();
gameStatus = 2;
sResult = String(result);
break;
case 2: //Submit the answer
displayNum(currentNum);
delay(200);
break;
}
}
您可以在此处下载完整的源代码。接线并上传以了解更多信息。
享受这个项目
将其上传到合适的板子上,看看它是如何工作的。
我们按顺序按下数字。例如,您的答案是 46。您必须按下左按钮得到数字 4,然后按下右按钮提交数字 4,然后以同样的方式提交数字 6。让我们看看下面的插图。它展示了如何按下以获得您需要的数字。
按钮去抖动
在测试过程中,您可能会发现它运行不正常。您按一次按钮,数字却增加了 2 或 3 而不是 1。看起来按钮被按了两次,但实际上您只按了一次。在这种情况下,您应该在此处了解更多关于按钮去抖动的信息。
有两种方法可以解决这个问题。您可以通过添加几行代码或在电路中使用附加电容来对按钮进行去抖动。
结论
感谢您的阅读。这是一个有趣的 Arduino 数学游戏。它可以帮助您提高加法技能。何不增加数字的数量并减少每个数字的显示时间以测试您的速度呢?您可以使用这个起点通过添加一些代码行来创建您自己的游戏。我认为和朋友一起玩这个游戏会更有趣、更激动人心。让我们一起来制作并玩这个游戏,享受乐趣。
历史
- 2018年8月6日:初版