Voltar ao Catálogo
Matemática
Jogo da tabuada
Responda a perguntas matemáticas e veja os resultados em um display.
Código Fonte Arduino (.INO)
Código Arduino Jogo da Tabuada (.INO)
Código C++ principal para o Jogo da Tabuada em tela LCD/display.
/************************************************
* Projeto: Jogo da Tabuada *
* Desenvolvedor: Vanderlei Alves *
* Data: 04/02/2025 *
*************************************************/
//Mapeamento de hardware-------------------------
//Pinos do display LCD
#define RS 12
#define EN 11
#define D7 2
#define D6 3
#define D5 4
#define D4 5
//Pino de saída de toques sonoros
#define PTONE 10
//Pinos dos botões
#define UP 6
#define DN 7
#define NX 8
#define OK 9
//Pino de saída dos LEDs de aviso
#define LED 13
//Ponos dos LEDs de indicação de algarismo
#define P1 A0 //LED de posição do primeiro dígito
#define P2 A1 //LED de posição do segundo dígito
#define P3 A2 //LED de posição do terceiro dígito
#define P4 A3 //LED de posição do quarto dígito
//Inclusão da biblioteca do display LCD
#include<LiquidCrystal.h>
//Declaração de variáveis globais
int resultado,
dg = 0,
dg1 = 0,
dg2 = 0,
dg3 = 0,
dg4 = 0,
opc,
res,
x,
y,
z,
score = 0,
apagar = 0,
pts = 10,
nivel = 1,
rx = 9,
rz = 10,
oper = 2,
over = 0,
fr = 660,
t = 30;
//Variáveis de leitura dos botões
bool btUp = true,
btDn = true,
btNx = true,
btOk = true;
//------Caractere especial para LCD-----------
byte coin[8]={
0b00100,
0b01010,
0b10001,
0b10111,
0b11101,
0b10001,
0b01010,
0b00100
};
//Objeto do display LCD
LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
void setup()
{
lcd.clear(); //Elimina qualquer resíduo gráfico da tela
lcd.createChar(1, coin); //Criação do caractere especial
lcd.begin(16, 2); //Inicialização do display LCD 16 linhas e 2 colunas
//Pinos definidos como entradas digitais
pinMode(UP, INPUT);
pinMode(DN, INPUT);
pinMode(NX, INPUT);
pinMode(OK, INPUT);
//Pinos definidos como saídas digitais
pinMode(LED, OUTPUT);
pinMode(P1, OUTPUT);
pinMode(P2, OUTPUT);
pinMode(P3, OUTPUT);
pinMode(P4, OUTPUT);
//Inicialização do LED de aviso
digitalWrite(LED, LOW);
//Inicialização dos LEDs de posições dos dígitos
digitalWrite(P1, HIGH);
digitalWrite(P2, LOW);
digitalWrite(P3, LOW);
digitalWrite(P4, LOW);
randomSeed(analogRead(4)); //Ruído da porta analógica para gerar números aleatórios
}
void loop()
{
//Inicialização do jogo (Aparece apenas ao ligar ou reiniciar a placa)
lcd.setCursor(0,0); //Faz com que os caracteres comecem a serem apresentados na coluna 0 e linha 0
lcd.print("_=JOGO TABUADA=_"); //Escreve o nome do jogo no display
lcd.setCursor(0,1); //Faz com que os caracteres comecem a serem apresentados na coluna 0 e linha 1
lcd.print("Iniciando");
//Tempo ao iniciar com animação de pontinhos na tela
for(int i = 9; i < 14; i++)
{
digitalWrite(LED, LOW); //Acende led de stop informando para aguardar
lcd.setCursor(i,1);
lcd.print(".");
delay(500);
}
digitalWrite(LED, HIGH); //Acende led de start informando que o jogo pode ser iniciado
tone(PTONE, 870, 30); //Tom sonoro de 870Hz e 30 milisegundos de duração que sairá pelo pino 10
lcd.clear(); //Limpa as informções do display LCD
//Lógica e Design da tela LCD
while(score < pts && over < 5)
{
//Gerar números aleatórios
x = random(1, rx); //x pega um valor aleatório diferente de zero
z = random(0, rz); //z pegar qualquer valor aleatório
opc = random(1, oper); //Define a operação
//Dependendo da opção sorteada e armazenada na variável 'opc'
//teremos uma operação matemática para ser resolvida
switch(opc)
{
case 1:
y = x+z; //Operação de soma
break;
case 2:
y = x*z; //Operação de multiplicação
break;
}
//Design da tela do jogo
//Informações na primeira linha dp display LCD
lcd.setCursor(0, 0);
//Nível do jogo
lcd.print("N");
lcd.print(nivel);
//Erros cometidos
lcd.print(" E: ");
lcd.print(over);
//Pontuação conquistada
lcd.print(" S: ");
lcd.print(score);
//Máxima pontuação para mudar de nível
lcd.print("/");
lcd.print(pts);
//Gera um tom sonoro de 870Hz de frequência e com duração de 30 milisegundos
tone(PTONE, 870, 30);
//Informações na segunda linha do display LCD
lcd.setCursor(0, 1);
lcd.print("R: ");
lcd.print(x); //Primeiro valor da operação
//Dependendo da operação sorteada, o display apresentará o caractere adequado.
if(opc == 1) lcd.print("+");
else lcd.print("X");
lcd.print(z); //Segundo valor da operação
//Apresentação dos dígitos de tentativa de resposta
lcd.print("=");
lcd.setCursor(12, 1);
lcd.print(dg4);
lcd.setCursor(13, 1);
lcd.print(dg3);
lcd.setCursor(14, 1);
lcd.print(dg2);
lcd.setCursor(15, 1);
lcd.print(dg1);
//Laço de repetição aguardando resposta
while(res == 0)
{
//Leitura dos botões
btUp = digitalRead(UP);
btDn = digitalRead(DN);
btNx = digitalRead(NX);
btOk = digitalRead(OK);
delay(50); //Tempo como anti-bouncing
//Cada vez que o botão de próximo digito for pressionado, os botões btUp e
//btDn irão atuar sobre a unidade, dezena, centena ou milhar, dependendo do
//valor da variável 'dg'
if(!btNx)
{
dg++;
if(dg > 3) dg = 0;
//Acente o LED que indica qual dígito será alterado
switch (dg)
{
case 0:
//A unidade será alterada
digitalWrite(P1, HIGH);
digitalWrite(P2, LOW);
digitalWrite(P3, LOW);
digitalWrite(P4, LOW);
break;
case 1:
//A dezena será alterada
digitalWrite(P1, LOW);
digitalWrite(P2, HIGH);
digitalWrite(P3, LOW);
digitalWrite(P4, LOW);
break;
case 2:
//A centena será alterada
digitalWrite(P1, LOW);
digitalWrite(P2, LOW);
digitalWrite(P3, HIGH);
digitalWrite(P4, LOW);
break;
case 3:
//A milhar será alterada
digitalWrite(P1, LOW);
digitalWrite(P2, LOW);
digitalWrite(P3, LOW);
digitalWrite(P4, HIGH);
break;
}
//Anti-bouncing, evita efeito de trepidação do botão ao ser pressionado
while(!btNx) btNx = digitalRead(8);
}
//Alteração do valor de cada dígito
switch(dg)
{
case 0:
//Alteração da unidade
if(!btUp)
{
dg1++; //Incrementa o valor
if(dg1 > 9) dg1 = 0; //Se o valor for maior que 9, muda para zero
while(!btUp) btUp = digitalRead(6); //Anti-bouncing
}
else if(!btDn)
{
dg1--; //Decrementa o valor
if(dg1 < 0) dg1 = 9; //Se o valor for menor que zero, muda para 9
while(!btDn) btDn = digitalRead(7); //Anti-bouncing
}
break;
case 1:
//Alteração da dezena
if(!btUp)
{
dg2++;
if(dg2 > 9) dg2 = 0;
while(!btUp) btUp = digitalRead(6);
}
else if(!btDn)
{
dg2--;
if(dg2 < 0) dg2 = 9;
while(!btDn) btDn = digitalRead(7);
}
break;
case 2:
//Alteração da centena
if(!btUp)
{
dg3++;
if(dg3 > 9) dg3 = 0;
while(!btUp) btUp = digitalRead(6);
}
else if(!btDn)
{
dg3--;
if(dg3 < 0) dg3 = 9;
while(!btDn) btDn = digitalRead(7);
}
break;
case 3:
//Alteração da milhar
if(!btUp)
{
dg4++;
if(dg4 > 9) dg4 = 0;
while(!btUp) btUp = digitalRead(6);
}
else if(!btDn)
{
dg4--;
if(dg4 < 0) dg4 = 9;
while(!btDn) btDn = digitalRead(7);
}
break;
}
//Apresentação dos algarismos digitados como opção de resposta
lcd.setCursor(12, 1);
lcd.print(dg4);
lcd.setCursor(13, 1);
lcd.print(dg3);
lcd.setCursor(14, 1);
lcd.print(dg2);
lcd.setCursor(15, 1);
lcd.print(dg1);
if(!btOk)
{
//Juntando unidade, dezena, centena e milhar para a formação do
//valor de resposta
res = 1000*dg4 + 100*dg3 + 10*dg2 + dg1;
//Zera as variáveis de cada algarismo
dg1 = dg2 = dg3 = dg4 = 0;
while(!btOk) btOk = digitalRead(9);
lcd.clear();
}
}
//Quando a resposta é correta
if(res == y)
{
score++;
tone(PTONE, 560, 10);
tone(PTONE, 550, 8);
lcd.setCursor(0, 0);
lcd.print("PARABENS!!! ");
lcd.write((byte)1); //Desenha a moeda (caractere criado no setup())
lcd.setCursor(0, 1);
lcd.print("R: ");
lcd.print(y); //Mostra a resposta esperada
lcd.print(" Pts: ");
lcd.print(score); //Mostra a pontuação conquistada
delay(3000);
lcd.clear();
res = dg = 0; //Zera as variáveis
//Zera a posição dos dígitos para o algarismo da unidade
digitalWrite(P1, HIGH);
digitalWrite(P2, LOW);
digitalWrite(P3, LOW);
digitalWrite(P4, LOW);
}
else
{
//Quando a resposta está errada
tone(PTONE, 440, 100); //Tom de 440Hz por 100 milisegundos
over++; //Incrementa valor para Game Over
lcd.setCursor(0, 0);
lcd.print("Ops! errou");
lcd.setCursor(0, 1);
lcd.print("Resposta: ");
lcd.print(y); //Mostra qual seria a resposta correta
res = dg = 0;
digitalWrite(LED, LOW);
delay(3000);
digitalWrite(LED, HIGH);
lcd.clear();
//Zera a posição dos dígitos
digitalWrite(P1, HIGH);
digitalWrite(P2, LOW);
digitalWrite(P3, LOW);
digitalWrite(P4, LOW);
}
}
lcd.clear();
//Pontuação Máxima para mudar de nível
if(score == pts)
{
for(int i = 0; i < 4; i++)
{
tone(PTONE, 550, 8);
lcd.setCursor(0,0);
lcd.print("PARABENS! ");
lcd.write((byte)1);
lcd.write((byte)1);
lcd.write((byte)1);
lcd.setCursor(0,1);
lcd.print("_=VOCE PASSOU!=_");
lcd.blink();
//Comemoração. Alterna entre os LEDs vermelho e verde e
//Reproduz sons com frequência e tempos diferentes
digitalWrite(LED, LOW);
tone(PTONE, 560, 10);
delay(500);
digitalWrite(LED, HIGH);
tone(PTONE, 550, 8);
delay(500);
digitalWrite(LED, LOW);
tone(PTONE, 560, 20);
delay(500);
digitalWrite(LED, HIGH);
tone(PTONE, 550, 8);
delay(500);
score = 0;
over = 0;
}
lcd.noBlink();
pts += 10; //Eleva a meta de pontuação para mais 10 pontos
nivel++; //Muda de nível
rx += 5; //Aumenta os valores para cálculos x
rz += 10; //Aumenta os valores para cálculos y
oper++; //Aumenta a quantidade de operações
if(oper > 3) oper = 3;
lcd.clear();
}
//Game Over-------------------------------------
else if(over >= 5)
{
tone(PTONE, 330, 100);
lcd.setCursor(0, 0);
lcd.print("_>GAME OVER!!!<_");
lcd.setCursor(0, 1);
lcd.print("Pts: ");
lcd.print(score);
lcd.print(" N: ");
lcd.print(nivel);
//Reproduz um som de reprovação por 10 vezes
for(int i = 0; i < 10; i++)
{
tone(PTONE, 330, 100);
}
//Alterna entre os LEDs
digitalWrite(LED, HIGH);
delay(6000);
digitalWrite(LED, LOW);
//Reinicia as variáveis do jogo
pts = 10;
nivel = 1;
rx = 9;
rz = 10;
score = 0;
over = 0;
lcd.clear();
}
}
Materiais Didáticos & Documentos
Tutorial Didático - Jogo da Tabuada (PDF)
Tutorial Didático Guia passo a passo de montagem, circuito e roteiro pedagógico.Quer este projeto em sua escola?
A WETECH disponibiliza kits de hardware prontos, roteiros de aulas alinhados à BNCC e formação continuada de educadores.
Solicitar Orçamento Escolar