Placar de Truco com Arduino 1

Nesse post veremos como montar um Placar de Truco portátil com Arduino. Os materiais necessários para montagem desse projeto são de fácil acesso e a programação apresenta vários conceitos fundamentais para quem deseja se aprofundar no Arduino. O placar pode ser montado em uma protoboard ou você pode criar uma placa de circuito impresso compacta a partir do design fornecido.

Placar de truco com Arduino

Materiais Necessários

Para montagem desse projeto vamos precisar dos seguintes materiais:

Circuito Eletrônico

Circuito eletrônico do placar de truco

Para montagem do projeto você deve conectar:

  • Pino VCC do Display no 5V do Arduino
  • Pino GND do Display no GND do Arduino
  • Pino SDA do Display na porta A4 do Arduino
  • Pino SCL do Display na porta A5 do Arduino
  • Pino GND do Arduino em um dos terminais de cada um dos Push Buttons
  • Terminal remanescente de cada um dos Push Buttons em uma porta digital do Arduino
  • Pino VIN do Arduino no positivo da bateria de 9V
  • Pino GND do Arduino no negativo da bateria de 9V
Tabela de Conexões
Arduino Display Bateria Botão 1 Botão 2 Botão 3
5V VCC
GND GND Negativo Terminal 1 Terminal 1 Terminal 1
A4 SDA
A5 SCL
D7 Terminal 2
D5 Terminal 2
D3 Terminal 2
VIN Positivo

 

Código do Placar de Truco

Nesse projeto, precisaremos usar a biblioteca Adafruit SSD1306 para controlar o display OLED. Ela pode ser facilmente instalada pela gerenciador de bibliotecas da IDE do Arduino conforme a imagem abaixo.

Logo no início do código, temos as definições dos parâmetros relativos a montagem do projeto:

// Portas------------
#define Botao1      7
#define Botao2      5
#define BotaoTruco  3
// ------------------

// Delay--------------
#define atraso    2000
#define debounce   500
// -------------------

// Parâmetros do Display----
#define SCREEN_WIDTH     128
#define SCREEN_HEIGHT     32
#define OLED_RESET         4
#define OLED_ADDRESS    0x3C
// -------------------------

Em Portas, temos os pinos do Arduino onde estão conectados os Push Buttons, nesse caso usamos os pinos 3, 5 e 7 mas você pode utilizar qualquer um dos pinos digitais.

Em Delay, definimos o tempo de debounce em milissegundos que, por padrão, está definido como 500 (meio segundo). Caso enfrente problemas com registro duplicado ao apertar os botões, aumente gradualmente esse valor até que o problema seja sanado. Para maiores detalhes sobre o uso de Push Buttons com o Arduino acesse o post “Debounce, o que é e como resolver via software“.

Os Parâmetros do Display já estão configurados para um display OLED 128×32. Caso deseje utilizar um display de 128×64 faça as alterações necessárias de acordo com as especificações do fabricante.

void setup()
{
  // Define o padrão das portas onde os botões estão conectados como HIGH
  pinMode( Botao1, INPUT_PULLUP);       
  pinMode( Botao2, INPUT_PULLUP);
  pinMode( BotaoTruco, INPUT_PULLUP);

  // Configura o Display OLED
  OLED.begin( SSD1306_SWITCHCAPVCC, OLED_ADDRESS);
  OLED.setTextColor( WHITE);
  OLED.clearDisplay();

  tela_inicial();       //Exibe tela inicial
}​​

No início da função setup, definimos as portas do Arduino onde os botões estão conectados como entrada mantida em estado alto por padrão. Para entender melhor o uso de entradas pull-up no Arduino confira o nosso post “Entendendo o pull-up e pull-down no Arduino“. Logo em seguida inicializamos o display OLED e chamamos a função tela_inicial, que exibe uma animação de boas-vindas com o nome do projeto.

void loop()
{
  // Jogo Normal
  if( pontos[0] < 11 && pontos[1] < 11)
    rodadas();

  // Equipe 1 Venceu
  if( pontos[0] >= 12)
    vencedor( 1);

  // Equipe 2 Venceu
  if( pontos[1] >= 12)
    vencedor( 2);

  // Equipe 1 com 11 pontos
  if( pontos[0] == 11 && pontos[1] < 11)
    mao_de_onze( 1);

  // Equipe 2 com 11 pontos
  if( pontos[1] == 11 && pontos[0] < 11)
    mao_de_onze( 2);

  // Ambas as equipes com 11 pontos
  if( pontos[1] == 11 && pontos[0] == 11)
    ambas_com_onze();
}

Na função loop, checamos constantemente a pontuação de cada equipe para saber o estado atual do jogo. De acordo com o momento em que o jogo se encontra, a função apropriada é chamada.

O código completo está disponível abaixo, assim como neste arquivo para download. Para saber como carregar o código no Arduino acesse o nosso post “Primeiros passos com Arduino“.

//Bibliotecas----------------
#include <Wire.h>
#include <Adafruit_SSD1306.h>
//---------------------------

//Portas-------------
#define Botao1      7
#define Botao2      5
#define BotaoTruco  3
//-------------------

//Delay---------------
#define atraso    2000
#define debounce   500
//--------------------

//Parâmetros do Display-----
#define SCREEN_WIDTH     128 
#define SCREEN_HEIGHT     32 
#define OLED_RESET         4 
#define OLED_ADDRESS    0x3C
//--------------------------

//Protótipos das Funções----------
void truco();
void placar();
void rodadas();
void nova_partida();
void tela_inicial();
int obter_resposta();
void ambas_com_onze();
void vencedor(int champ);
void mao_de_onze(int equipe_onze);
//--------------------------------

//Variáveis Globais--------------------
bool EstadoAtual_1 = HIGH;
bool EstadoAtual_3 = HIGH;
bool EstadoAtual_Truco = HIGH;
bool EstadoAnterior_1 = HIGH;
bool EstadoAnterior_2 = HIGH;
bool EstadoAnterior_Truco = HIGH;
unsigned short int resposta;
unsigned short int tentos = 0;
unsigned short int pontos[2] = { 0, 0};
//-------------------------------------

//Instancia o display OLED--------------------------------------------
Adafruit_SSD1306 OLED(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() 
{
  //Define o padrão das portas onde os botões estão conectados como HIGH
  pinMode(Botao1, INPUT_PULLUP);        
  pinMode(Botao2, INPUT_PULLUP);
  pinMode(BotaoTruco, INPUT_PULLUP);

  //Configura o Display OLED
  OLED.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS);
  OLED.setTextColor(WHITE);
  OLED.clearDisplay();
  
  tela_inicial();       //Exibe tela inicial
}

void loop() 
{
  //Jogo Normal
  if(pontos[0] < 11 && pontos[1] < 11)
    rodadas();

  //Equipe 1 Venceu
  if(pontos[0] >= 12)
    vencedor(1);

  //Equipe 2 Venceu
  if(pontos[1] >= 12)
    vencedor(2);
    
  //Equipe 1 com 11 pontos
  if(pontos[0] == 11 && pontos[1] < 11)
    mao_de_onze(1);

  //Equipe 2 com 11 pontos
  if(pontos[1] == 11 && pontos[0] < 11)
    mao_de_onze(2);

  //Ambas as equipes com 11 pontos
  if(pontos[1] == 11 && pontos[0] == 11)
    ambas_com_onze();
}

void placar()
{
  OLED.clearDisplay();                //Limpa a tela
  
  OLED.setTextSize(1);                //Define o tamanho da fonte
  
  OLED.setCursor(2,7);                //Posiciona o cursor
  OLED.print("Equipe 1-->     ");     //Define o texto a ser exibido
  OLED.setCursor(77,7);
  OLED.print(pontos[0]);
  
  OLED.setCursor(2, 16);
  OLED.print("Equipe 2-->     ");
  OLED.setCursor(77, 16);
  OLED.print(pontos[1]);

  OLED.display();                     //Mostra na tela o texto definido
}

int obter_resposta()        
{
  while(true)
  {
    //Lendo o estado dos pinos onde os botões estão conectados
    EstadoAtual_1 = digitalRead(Botao1);
    EstadoAtual_3 = digitalRead(Botao2);
    EstadoAtual_Truco = digitalRead(BotaoTruco);
    
    if(!EstadoAtual_1 && EstadoAnterior_1)        //O botão 1 está apertado
    {
      EstadoAnterior_1 = EstadoAtual_1;
      delay(debounce);                            //Evita que sejam registrados toques duplicados
      return 1;                                   //Função retorna o botão pressionado
      break;                                      //Sai do laço While
    }
    if(!EstadoAtual_3 && EstadoAnterior_2)        //O botão 2 está apertado
    {
      EstadoAnterior_2 = EstadoAtual_3;
      delay(debounce);
      return 2;                                       
      break;
    }
    if(!EstadoAtual_Truco && EstadoAnterior_Truco)    //O botão de truco está apertado
    {
      EstadoAnterior_Truco = EstadoAtual_Truco;
      delay(debounce);
      return 3;
      break;
    }
    
    EstadoAnterior_1 = EstadoAtual_1;
    EstadoAnterior_2 = EstadoAtual_3;
    EstadoAnterior_Truco = EstadoAtual_Truco;
  } 
}

void rodadas()
{
  //Nenhuma equipe com 11 ou vencedora
  while(pontos[0] < 11 && pontos[1] < 11)
  {
    placar();                       //Exibe o placar atual
    resposta = obter_resposta();    //Espera o botão pressionado pelo usuário
    if(resposta == 3)
      truco();                      //A jogada está trucada
    else
      pontos[resposta-1] ++;        //Atualiza o placar 
  }
}

void truco()
{
  tentos += 3;

  //Exibe quanto vale a rodada
  OLED.clearDisplay();
  OLED.setTextSize(2);
 
  switch(tentos)
  {
    case 3:
    OLED.setCursor(3,8);
    OLED.print("  TRUCO!  ");
    break;

    case 6:
    OLED.setCursor(0,8);
    OLED.print("   SEIS!  ");
    break;

    case 9:
    OLED.setCursor(0,8);
    OLED.print("   NOVE!  ");
    break;

    case 12:
    OLED.setCursor(0,8);
    OLED.print("   DOZE!  ");
    break;
  }
  OLED.display();
  delay(1000);
  
  //Desconsidera o botão de truco sendo apertado depois de se pedir 12
  if(tentos > 12)
    tentos = 12;

  //Pergunta quem venceu a rodada trucada
  OLED.clearDisplay();
  OLED.setTextSize(1);
  OLED.setCursor(0,7);
  OLED.print("    Quem Venceu?    ");
  OLED.setCursor(0,16);
  OLED.print("  1)Eq. 1  2)Eq. 2  ");
  OLED.display();
  
  resposta = obter_resposta();
  
  if(resposta == 3)
    truco();    
  else
  {
    pontos[resposta-1] += tentos;
    placar();
    delay(atraso);
  }
  tentos = 0;
}

void mao_de_onze(int equipe_onze)
{
  int outra_equipe;
  if(equipe_onze == 1)
    outra_equipe = 2;
  else
    outra_equipe = 1;
    
  //Pergunta se a equipe com 11 deseja jogar a rodada 
  OLED.clearDisplay();
  OLED.setTextSize(1);
  OLED.setCursor(0,7);
  OLED.print("    Mao de Onze     ");
  OLED.setCursor(0,16);
  OLED.print(" 1)Aceita   2)Corre ");
  OLED.display();
  
  resposta = obter_resposta();
  
  //Rodada foi aceita
  if(resposta == 1)
  {  
    //Pergunta quem venceu a rodada
    OLED.clearDisplay();
    OLED.setTextSize(1);
    OLED.setCursor(0,7);
    OLED.print("    Quem Venceu?    ");
    OLED.setCursor(0,16);
    OLED.print("  1)Eq. 1  2)Eq. 2  ");
    OLED.display();
    
    resposta = obter_resposta();
    
    if(resposta == equipe_onze)
      pontos[equipe_onze-1] += 3;
 
    if(resposta == outra_equipe)
    {
      pontos[outra_equipe-1] += 3;
      placar();
      delay(atraso);
    }
  }

  //Rodada não foi aceita
  else if(resposta == 2)
  {
    pontos[outra_equipe-1]++;   //Equipe em desvantagem recebe um ponto
    placar();
    delay(atraso);
  }
  
}

void ambas_com_onze()
{
  //Pergunta qual equipe venceu a rodada final
  OLED.clearDisplay();
  OLED.setTextSize(1);
  OLED.setCursor(0,7);
  OLED.print("   Ambas com Onze   ");
  OLED.display();
  delay(atraso);
  
  OLED.clearDisplay();
  OLED.setTextSize(1);
  OLED.setCursor(0,7);
  OLED.print("    Quem Venceu?    ");
  OLED.setCursor(0,16);
  OLED.print("  1)Eq. 1  2)Eq. 2  ");
  OLED.display();

  resposta = obter_resposta();
  
  if(resposta == 1)
    pontos[0]++;

  if(resposta == 2)
    pontos[1]++;
}

void vencedor(int champ)
{
  //Exibe a equipe vencedora
  for(int i = 0; i < 4; i++)
  {
    OLED.clearDisplay();
    OLED.setTextSize(1);
    OLED.setCursor(0,7);
    OLED.print("    O Jogo Acabou!   ");
    OLED.setCursor(0,16);
    OLED.print("                     ");
    OLED.display();
    delay(atraso/2);
    OLED.setCursor(0,16);
    OLED.print("   Equipe   Venceu!  ");
    OLED.setCursor(60,16);
    OLED.print(champ);
    OLED.display();
    delay(atraso);
  }
  OLED.clearDisplay();
  while(true)
  {
    OLED.setCursor(0,7);
    OLED.println("        Italo        ");
    OLED.setCursor(0,15);
    OLED.println("        Coelho       ");
    OLED.display();
    delay(10000);
  }
}

void tela_inicial()     //Animação Incial
{
  OLED.setTextSize(1);
  OLED.setCursor(0,7);
  OLED.println("   Placar de Truco   ");
  OLED.setCursor(0,15);
  OLED.println("---------------------");
  OLED.display();
  delay(50);
  OLED.clearDisplay();
  OLED.setCursor(0,7);
  OLED.println("   Placar de Truco   ");
  OLED.setCursor(0,15);
  OLED.println(" ------------------- ");
  OLED.display();
  delay(50);
  OLED.clearDisplay();
  OLED.setCursor(0,7);
  OLED.println("   Placar de Truco   ");
  OLED.setCursor(0,15);
  OLED.println("  -----------------  ");
  OLED.display();
  delay(50);
  OLED.clearDisplay();
  OLED.setCursor(0,7);
  OLED.println("   Placar de Truco   ");
  OLED.setCursor(0,15);
  OLED.println("   ---------------   ");
  OLED.display();
  delay(50);
  OLED.clearDisplay();
  OLED.setCursor(0,7);
  OLED.println("   Placar de Truco   ");
  OLED.setCursor(0,15);
  OLED.println("    -------------    ");
  OLED.display();
  delay(50);
  OLED.clearDisplay();
  OLED.setCursor(0,7);
  OLED.println("   Placar de Truco   ");
  OLED.setCursor(0,15);
  OLED.println("    -------------    ");
  OLED.display();
  delay(50);
  OLED.clearDisplay();
  OLED.setCursor(0,7);
  OLED.println("   Placar de Truco   ");
  OLED.setCursor(0,15);
  OLED.println("      ---------      ");
  OLED.display();
  delay(50);
  OLED.clearDisplay();
  OLED.setCursor(0,7);
  OLED.println("   Placar de Truco   ");
  OLED.setCursor(0,15);
  OLED.println("      ---------      ");
  OLED.display();
  delay(50);
  OLED.clearDisplay();
  OLED.setCursor(0,7);
  OLED.println("   Placar de Truco   ");
  OLED.setCursor(0,15);
  OLED.println("        -----        ");
  OLED.display();
  delay(50);
  OLED.clearDisplay();
  OLED.setCursor(0,7);
  OLED.println("   Placar de Truco   ");
  OLED.setCursor(0,15);
  OLED.println("         ---         ");
  OLED.display();
  delay(50);
  OLED.clearDisplay();
  OLED.setCursor(0,15);
  OLED.println("          -          ");
  OLED.display();
  delay(50);
  OLED.clearDisplay();
  OLED.setCursor(0,7);
  OLED.println("   Placar de Truco   ");
  OLED.setCursor(0,15);
  OLED.println("                     ");
  OLED.display();
  delay(50);
  OLED.clearDisplay();
}

Placa de circuito impresso

Para confeccionar o Placar de Truco em forma de placa de circuito impresso, vamos utilizar como microcontrolador o Arduino Pro Mini de 5V e uma placa de Fenolite de 5 cm x 5 cm.

Para saber como fazer upload do código no Arduino Pro Mini você pode conferir o post “Programando um Arduino Pro Mini com Arduino Uno” ou “Programando o Arduino Pro Mini com Cabo Conversor USB TTL“.

Você pode fazer o download do design da PCB. Acesse o nosso post Confecção de PCB de formar caseira para instruções em como produzir a sua própria placa em casa.

Placar PCB do placar de truco com Arduino

Funcionamento do Placar de Truco com Arduino:

YouTube video

A interface do placar é composta por três botões que denominaremos, da esquerda para a direita, de botão Um, Dois e Três. Durante o jogo os botões Um e Dois adicionam um ponto a suas respectivas equipes enquanto o botão Três é usado para trucar e pedir seis, nove ou doze. Quando aparecem perguntas na tela, o botão Um corresponde à resposta afirmativa enquanto o botão Dois indica resposta negativa.

Gostou desse projeto? Não se esqueça de deixar um comentário nos contando o que achou.

Faça seu comentário

Acesse sua conta e participe

Um Comentário

  1. Boa TArde. Preciso de um código. Poderia me ajudar? Fazer negócio?